xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- InstructionSimplify.cpp - Fold instruction operands ----------------===//
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 routines for folding instructions into simpler forms
100b57cec5SDimitry Andric // that do not require creating new instructions.  This does constant folding
110b57cec5SDimitry Andric // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
120b57cec5SDimitry Andric // returning a constant ("and i32 %x, 0" -> "0") or an already existing value
130b57cec5SDimitry Andric // ("and i32 %x, %x" -> "%x").  All operands are assumed to have already been
140b57cec5SDimitry Andric // simplified: This is usually true and assuming it simplifies the logic (if
150b57cec5SDimitry Andric // they have not been simplified then results are correct but maybe suboptimal).
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
20fe6060f1SDimitry Andric 
21fe6060f1SDimitry Andric #include "llvm/ADT/STLExtras.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
230b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
250b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
260b57cec5SDimitry Andric #include "llvm/Analysis/CaptureTracking.h"
270b57cec5SDimitry Andric #include "llvm/Analysis/CmpInstAnalysis.h"
280b57cec5SDimitry Andric #include "llvm/Analysis/ConstantFolding.h"
2904eeddc0SDimitry Andric #include "llvm/Analysis/InstSimplifyFolder.h"
300b57cec5SDimitry Andric #include "llvm/Analysis/LoopAnalysisManager.h"
310b57cec5SDimitry Andric #include "llvm/Analysis/MemoryBuiltins.h"
32fe6060f1SDimitry Andric #include "llvm/Analysis/OverflowInstAnalysis.h"
330b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
340b57cec5SDimitry Andric #include "llvm/Analysis/VectorUtils.h"
350b57cec5SDimitry Andric #include "llvm/IR/ConstantRange.h"
360b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
370b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
380b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
390b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
400b57cec5SDimitry Andric #include "llvm/IR/Operator.h"
410b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h"
42*0fca6ea1SDimitry Andric #include "llvm/IR/Statepoint.h"
430b57cec5SDimitry Andric #include "llvm/Support/KnownBits.h"
440b57cec5SDimitry Andric #include <algorithm>
45bdd1243dSDimitry Andric #include <optional>
460b57cec5SDimitry Andric using namespace llvm;
470b57cec5SDimitry Andric using namespace llvm::PatternMatch;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric #define DEBUG_TYPE "instsimplify"
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric enum { RecursionLimit = 3 };
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric STATISTIC(NumExpand, "Number of expansions");
540b57cec5SDimitry Andric STATISTIC(NumReassoc, "Number of reassociations");
550b57cec5SDimitry Andric 
5681ad6265SDimitry Andric static Value *simplifyAndInst(Value *, Value *, const SimplifyQuery &,
5781ad6265SDimitry Andric                               unsigned);
580b57cec5SDimitry Andric static Value *simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned);
590b57cec5SDimitry Andric static Value *simplifyFPUnOp(unsigned, Value *, const FastMathFlags &,
600b57cec5SDimitry Andric                              const SimplifyQuery &, unsigned);
6181ad6265SDimitry Andric static Value *simplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &,
620b57cec5SDimitry Andric                             unsigned);
6381ad6265SDimitry Andric static Value *simplifyBinOp(unsigned, Value *, Value *, const FastMathFlags &,
640b57cec5SDimitry Andric                             const SimplifyQuery &, unsigned);
6581ad6265SDimitry Andric static Value *simplifyCmpInst(unsigned, Value *, Value *, const SimplifyQuery &,
660b57cec5SDimitry Andric                               unsigned);
6781ad6265SDimitry Andric static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
680b57cec5SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse);
6981ad6265SDimitry Andric static Value *simplifyOrInst(Value *, Value *, const SimplifyQuery &, unsigned);
7081ad6265SDimitry Andric static Value *simplifyXorInst(Value *, Value *, const SimplifyQuery &,
7181ad6265SDimitry Andric                               unsigned);
7281ad6265SDimitry Andric static Value *simplifyCastInst(unsigned, Value *, Type *, const SimplifyQuery &,
7381ad6265SDimitry Andric                                unsigned);
74*0fca6ea1SDimitry Andric static Value *simplifyGEPInst(Type *, Value *, ArrayRef<Value *>,
75*0fca6ea1SDimitry Andric                               GEPNoWrapFlags, const SimplifyQuery &, unsigned);
7681ad6265SDimitry Andric static Value *simplifySelectInst(Value *, Value *, Value *,
77fe6060f1SDimitry Andric                                  const SimplifyQuery &, unsigned);
7806c3fb27SDimitry Andric static Value *simplifyInstructionWithOperands(Instruction *I,
7906c3fb27SDimitry Andric                                               ArrayRef<Value *> NewOps,
8006c3fb27SDimitry Andric                                               const SimplifyQuery &SQ,
8106c3fb27SDimitry Andric                                               unsigned MaxRecurse);
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric static Value *foldSelectWithBinaryOp(Value *Cond, Value *TrueVal,
840b57cec5SDimitry Andric                                      Value *FalseVal) {
850b57cec5SDimitry Andric   BinaryOperator::BinaryOps BinOpCode;
860b57cec5SDimitry Andric   if (auto *BO = dyn_cast<BinaryOperator>(Cond))
870b57cec5SDimitry Andric     BinOpCode = BO->getOpcode();
880b57cec5SDimitry Andric   else
890b57cec5SDimitry Andric     return nullptr;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   CmpInst::Predicate ExpectedPred, Pred1, Pred2;
920b57cec5SDimitry Andric   if (BinOpCode == BinaryOperator::Or) {
930b57cec5SDimitry Andric     ExpectedPred = ICmpInst::ICMP_NE;
940b57cec5SDimitry Andric   } else if (BinOpCode == BinaryOperator::And) {
950b57cec5SDimitry Andric     ExpectedPred = ICmpInst::ICMP_EQ;
960b57cec5SDimitry Andric   } else
970b57cec5SDimitry Andric     return nullptr;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   // %A = icmp eq %TV, %FV
1000b57cec5SDimitry Andric   // %B = icmp eq %X, %Y (and one of these is a select operand)
1010b57cec5SDimitry Andric   // %C = and %A, %B
1020b57cec5SDimitry Andric   // %D = select %C, %TV, %FV
1030b57cec5SDimitry Andric   // -->
1040b57cec5SDimitry Andric   // %FV
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   // %A = icmp ne %TV, %FV
1070b57cec5SDimitry Andric   // %B = icmp ne %X, %Y (and one of these is a select operand)
1080b57cec5SDimitry Andric   // %C = or %A, %B
1090b57cec5SDimitry Andric   // %D = select %C, %TV, %FV
1100b57cec5SDimitry Andric   // -->
1110b57cec5SDimitry Andric   // %TV
1120b57cec5SDimitry Andric   Value *X, *Y;
1130b57cec5SDimitry Andric   if (!match(Cond, m_c_BinOp(m_c_ICmp(Pred1, m_Specific(TrueVal),
1140b57cec5SDimitry Andric                                       m_Specific(FalseVal)),
1150b57cec5SDimitry Andric                              m_ICmp(Pred2, m_Value(X), m_Value(Y)))) ||
1160b57cec5SDimitry Andric       Pred1 != Pred2 || Pred1 != ExpectedPred)
1170b57cec5SDimitry Andric     return nullptr;
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   if (X == TrueVal || X == FalseVal || Y == TrueVal || Y == FalseVal)
1200b57cec5SDimitry Andric     return BinOpCode == BinaryOperator::Or ? TrueVal : FalseVal;
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   return nullptr;
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric /// For a boolean type or a vector of boolean type, return false or a vector
1260b57cec5SDimitry Andric /// with every element false.
12781ad6265SDimitry Andric static Constant *getFalse(Type *Ty) { return ConstantInt::getFalse(Ty); }
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric /// For a boolean type or a vector of boolean type, return true or a vector
1300b57cec5SDimitry Andric /// with every element true.
13181ad6265SDimitry Andric static Constant *getTrue(Type *Ty) { return ConstantInt::getTrue(Ty); }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric /// isSameCompare - Is V equivalent to the comparison "LHS Pred RHS"?
1340b57cec5SDimitry Andric static bool isSameCompare(Value *V, CmpInst::Predicate Pred, Value *LHS,
1350b57cec5SDimitry Andric                           Value *RHS) {
1360b57cec5SDimitry Andric   CmpInst *Cmp = dyn_cast<CmpInst>(V);
1370b57cec5SDimitry Andric   if (!Cmp)
1380b57cec5SDimitry Andric     return false;
1390b57cec5SDimitry Andric   CmpInst::Predicate CPred = Cmp->getPredicate();
1400b57cec5SDimitry Andric   Value *CLHS = Cmp->getOperand(0), *CRHS = Cmp->getOperand(1);
1410b57cec5SDimitry Andric   if (CPred == Pred && CLHS == LHS && CRHS == RHS)
1420b57cec5SDimitry Andric     return true;
1430b57cec5SDimitry Andric   return CPred == CmpInst::getSwappedPredicate(Pred) && CLHS == RHS &&
1440b57cec5SDimitry Andric          CRHS == LHS;
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
147480093f4SDimitry Andric /// Simplify comparison with true or false branch of select:
148480093f4SDimitry Andric ///  %sel = select i1 %cond, i32 %tv, i32 %fv
149480093f4SDimitry Andric ///  %cmp = icmp sle i32 %sel, %rhs
150480093f4SDimitry Andric /// Compose new comparison by substituting %sel with either %tv or %fv
151480093f4SDimitry Andric /// and see if it simplifies.
152480093f4SDimitry Andric static Value *simplifyCmpSelCase(CmpInst::Predicate Pred, Value *LHS,
153480093f4SDimitry Andric                                  Value *RHS, Value *Cond,
154480093f4SDimitry Andric                                  const SimplifyQuery &Q, unsigned MaxRecurse,
155480093f4SDimitry Andric                                  Constant *TrueOrFalse) {
15681ad6265SDimitry Andric   Value *SimplifiedCmp = simplifyCmpInst(Pred, LHS, RHS, Q, MaxRecurse);
157480093f4SDimitry Andric   if (SimplifiedCmp == Cond) {
158480093f4SDimitry Andric     // %cmp simplified to the select condition (%cond).
159480093f4SDimitry Andric     return TrueOrFalse;
160480093f4SDimitry Andric   } else if (!SimplifiedCmp && isSameCompare(Cond, Pred, LHS, RHS)) {
161480093f4SDimitry Andric     // It didn't simplify. However, if composed comparison is equivalent
162480093f4SDimitry Andric     // to the select condition (%cond) then we can replace it.
163480093f4SDimitry Andric     return TrueOrFalse;
164480093f4SDimitry Andric   }
165480093f4SDimitry Andric   return SimplifiedCmp;
166480093f4SDimitry Andric }
167480093f4SDimitry Andric 
168480093f4SDimitry Andric /// Simplify comparison with true branch of select
169480093f4SDimitry Andric static Value *simplifyCmpSelTrueCase(CmpInst::Predicate Pred, Value *LHS,
170480093f4SDimitry Andric                                      Value *RHS, Value *Cond,
171480093f4SDimitry Andric                                      const SimplifyQuery &Q,
172480093f4SDimitry Andric                                      unsigned MaxRecurse) {
173480093f4SDimitry Andric   return simplifyCmpSelCase(Pred, LHS, RHS, Cond, Q, MaxRecurse,
174480093f4SDimitry Andric                             getTrue(Cond->getType()));
175480093f4SDimitry Andric }
176480093f4SDimitry Andric 
177480093f4SDimitry Andric /// Simplify comparison with false branch of select
178480093f4SDimitry Andric static Value *simplifyCmpSelFalseCase(CmpInst::Predicate Pred, Value *LHS,
179480093f4SDimitry Andric                                       Value *RHS, Value *Cond,
180480093f4SDimitry Andric                                       const SimplifyQuery &Q,
181480093f4SDimitry Andric                                       unsigned MaxRecurse) {
182480093f4SDimitry Andric   return simplifyCmpSelCase(Pred, LHS, RHS, Cond, Q, MaxRecurse,
183480093f4SDimitry Andric                             getFalse(Cond->getType()));
184480093f4SDimitry Andric }
185480093f4SDimitry Andric 
186480093f4SDimitry Andric /// We know comparison with both branches of select can be simplified, but they
187480093f4SDimitry Andric /// are not equal. This routine handles some logical simplifications.
188480093f4SDimitry Andric static Value *handleOtherCmpSelSimplifications(Value *TCmp, Value *FCmp,
189480093f4SDimitry Andric                                                Value *Cond,
190480093f4SDimitry Andric                                                const SimplifyQuery &Q,
191480093f4SDimitry Andric                                                unsigned MaxRecurse) {
192480093f4SDimitry Andric   // If the false value simplified to false, then the result of the compare
193480093f4SDimitry Andric   // is equal to "Cond && TCmp".  This also catches the case when the false
194480093f4SDimitry Andric   // value simplified to false and the true value to true, returning "Cond".
195fe6060f1SDimitry Andric   // Folding select to and/or isn't poison-safe in general; impliesPoison
196fe6060f1SDimitry Andric   // checks whether folding it does not convert a well-defined value into
197fe6060f1SDimitry Andric   // poison.
198fe6060f1SDimitry Andric   if (match(FCmp, m_Zero()) && impliesPoison(TCmp, Cond))
19981ad6265SDimitry Andric     if (Value *V = simplifyAndInst(Cond, TCmp, Q, MaxRecurse))
200480093f4SDimitry Andric       return V;
201480093f4SDimitry Andric   // If the true value simplified to true, then the result of the compare
202480093f4SDimitry Andric   // is equal to "Cond || FCmp".
203fe6060f1SDimitry Andric   if (match(TCmp, m_One()) && impliesPoison(FCmp, Cond))
20481ad6265SDimitry Andric     if (Value *V = simplifyOrInst(Cond, FCmp, Q, MaxRecurse))
205480093f4SDimitry Andric       return V;
206480093f4SDimitry Andric   // Finally, if the false value simplified to true and the true value to
207480093f4SDimitry Andric   // false, then the result of the compare is equal to "!Cond".
208480093f4SDimitry Andric   if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
20981ad6265SDimitry Andric     if (Value *V = simplifyXorInst(
210480093f4SDimitry Andric             Cond, Constant::getAllOnesValue(Cond->getType()), Q, MaxRecurse))
211480093f4SDimitry Andric       return V;
212480093f4SDimitry Andric   return nullptr;
213480093f4SDimitry Andric }
214480093f4SDimitry Andric 
2150b57cec5SDimitry Andric /// Does the given value dominate the specified phi node?
2160b57cec5SDimitry Andric static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
2170b57cec5SDimitry Andric   Instruction *I = dyn_cast<Instruction>(V);
2180b57cec5SDimitry Andric   if (!I)
2190b57cec5SDimitry Andric     // Arguments and constants dominate all instructions.
2200b57cec5SDimitry Andric     return true;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   // If we have a DominatorTree then do a precise test.
2230b57cec5SDimitry Andric   if (DT)
2240b57cec5SDimitry Andric     return DT->dominates(I, P);
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   // Otherwise, if the instruction is in the entry block and is not an invoke,
2270b57cec5SDimitry Andric   // then it obviously dominates all phi nodes.
228fe6060f1SDimitry Andric   if (I->getParent()->isEntryBlock() && !isa<InvokeInst>(I) &&
229fe6060f1SDimitry Andric       !isa<CallBrInst>(I))
2300b57cec5SDimitry Andric     return true;
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   return false;
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
235e8d8bef9SDimitry Andric /// Try to simplify a binary operator of form "V op OtherOp" where V is
236e8d8bef9SDimitry Andric /// "(B0 opex B1)" by distributing 'op' across 'opex' as
237e8d8bef9SDimitry Andric /// "(B0 op OtherOp) opex (B1 op OtherOp)".
238e8d8bef9SDimitry Andric static Value *expandBinOp(Instruction::BinaryOps Opcode, Value *V,
239e8d8bef9SDimitry Andric                           Value *OtherOp, Instruction::BinaryOps OpcodeToExpand,
2400b57cec5SDimitry Andric                           const SimplifyQuery &Q, unsigned MaxRecurse) {
241e8d8bef9SDimitry Andric   auto *B = dyn_cast<BinaryOperator>(V);
242e8d8bef9SDimitry Andric   if (!B || B->getOpcode() != OpcodeToExpand)
243e8d8bef9SDimitry Andric     return nullptr;
244e8d8bef9SDimitry Andric   Value *B0 = B->getOperand(0), *B1 = B->getOperand(1);
24581ad6265SDimitry Andric   Value *L =
24681ad6265SDimitry Andric       simplifyBinOp(Opcode, B0, OtherOp, Q.getWithoutUndef(), MaxRecurse);
247e8d8bef9SDimitry Andric   if (!L)
248e8d8bef9SDimitry Andric     return nullptr;
24981ad6265SDimitry Andric   Value *R =
25081ad6265SDimitry Andric       simplifyBinOp(Opcode, B1, OtherOp, Q.getWithoutUndef(), MaxRecurse);
251e8d8bef9SDimitry Andric   if (!R)
252e8d8bef9SDimitry Andric     return nullptr;
253e8d8bef9SDimitry Andric 
254e8d8bef9SDimitry Andric   // Does the expanded pair of binops simplify to the existing binop?
255e8d8bef9SDimitry Andric   if ((L == B0 && R == B1) ||
256e8d8bef9SDimitry Andric       (Instruction::isCommutative(OpcodeToExpand) && L == B1 && R == B0)) {
257e8d8bef9SDimitry Andric     ++NumExpand;
258e8d8bef9SDimitry Andric     return B;
259e8d8bef9SDimitry Andric   }
260e8d8bef9SDimitry Andric 
261e8d8bef9SDimitry Andric   // Otherwise, return "L op' R" if it simplifies.
26281ad6265SDimitry Andric   Value *S = simplifyBinOp(OpcodeToExpand, L, R, Q, MaxRecurse);
263e8d8bef9SDimitry Andric   if (!S)
264e8d8bef9SDimitry Andric     return nullptr;
265e8d8bef9SDimitry Andric 
266e8d8bef9SDimitry Andric   ++NumExpand;
267e8d8bef9SDimitry Andric   return S;
268e8d8bef9SDimitry Andric }
269e8d8bef9SDimitry Andric 
270e8d8bef9SDimitry Andric /// Try to simplify binops of form "A op (B op' C)" or the commuted variant by
271e8d8bef9SDimitry Andric /// distributing op over op'.
27281ad6265SDimitry Andric static Value *expandCommutativeBinOp(Instruction::BinaryOps Opcode, Value *L,
27381ad6265SDimitry Andric                                      Value *R,
274e8d8bef9SDimitry Andric                                      Instruction::BinaryOps OpcodeToExpand,
275e8d8bef9SDimitry Andric                                      const SimplifyQuery &Q,
276e8d8bef9SDimitry Andric                                      unsigned MaxRecurse) {
2770b57cec5SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
2780b57cec5SDimitry Andric   if (!MaxRecurse--)
2790b57cec5SDimitry Andric     return nullptr;
2800b57cec5SDimitry Andric 
281e8d8bef9SDimitry Andric   if (Value *V = expandBinOp(Opcode, L, R, OpcodeToExpand, Q, MaxRecurse))
2820b57cec5SDimitry Andric     return V;
283e8d8bef9SDimitry Andric   if (Value *V = expandBinOp(Opcode, R, L, OpcodeToExpand, Q, MaxRecurse))
2840b57cec5SDimitry Andric     return V;
2850b57cec5SDimitry Andric   return nullptr;
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric /// Generic simplifications for associative binary operations.
2890b57cec5SDimitry Andric /// Returns the simpler value, or null if none was found.
29081ad6265SDimitry Andric static Value *simplifyAssociativeBinOp(Instruction::BinaryOps Opcode,
2910b57cec5SDimitry Andric                                        Value *LHS, Value *RHS,
2920b57cec5SDimitry Andric                                        const SimplifyQuery &Q,
2930b57cec5SDimitry Andric                                        unsigned MaxRecurse) {
2940b57cec5SDimitry Andric   assert(Instruction::isAssociative(Opcode) && "Not an associative operation!");
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
2970b57cec5SDimitry Andric   if (!MaxRecurse--)
2980b57cec5SDimitry Andric     return nullptr;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   BinaryOperator *Op0 = dyn_cast<BinaryOperator>(LHS);
3010b57cec5SDimitry Andric   BinaryOperator *Op1 = dyn_cast<BinaryOperator>(RHS);
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   // Transform: "(A op B) op C" ==> "A op (B op C)" if it simplifies completely.
3040b57cec5SDimitry Andric   if (Op0 && Op0->getOpcode() == Opcode) {
3050b57cec5SDimitry Andric     Value *A = Op0->getOperand(0);
3060b57cec5SDimitry Andric     Value *B = Op0->getOperand(1);
3070b57cec5SDimitry Andric     Value *C = RHS;
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric     // Does "B op C" simplify?
31081ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Opcode, B, C, Q, MaxRecurse)) {
3110b57cec5SDimitry Andric       // It does!  Return "A op V" if it simplifies or is already available.
3120b57cec5SDimitry Andric       // If V equals B then "A op V" is just the LHS.
31381ad6265SDimitry Andric       if (V == B)
31481ad6265SDimitry Andric         return LHS;
3150b57cec5SDimitry Andric       // Otherwise return "A op V" if it simplifies.
31681ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Opcode, A, V, Q, MaxRecurse)) {
3170b57cec5SDimitry Andric         ++NumReassoc;
3180b57cec5SDimitry Andric         return W;
3190b57cec5SDimitry Andric       }
3200b57cec5SDimitry Andric     }
3210b57cec5SDimitry Andric   }
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   // Transform: "A op (B op C)" ==> "(A op B) op C" if it simplifies completely.
3240b57cec5SDimitry Andric   if (Op1 && Op1->getOpcode() == Opcode) {
3250b57cec5SDimitry Andric     Value *A = LHS;
3260b57cec5SDimitry Andric     Value *B = Op1->getOperand(0);
3270b57cec5SDimitry Andric     Value *C = Op1->getOperand(1);
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric     // Does "A op B" simplify?
33081ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Opcode, A, B, Q, MaxRecurse)) {
3310b57cec5SDimitry Andric       // It does!  Return "V op C" if it simplifies or is already available.
3320b57cec5SDimitry Andric       // If V equals B then "V op C" is just the RHS.
33381ad6265SDimitry Andric       if (V == B)
33481ad6265SDimitry Andric         return RHS;
3350b57cec5SDimitry Andric       // Otherwise return "V op C" if it simplifies.
33681ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Opcode, V, C, Q, MaxRecurse)) {
3370b57cec5SDimitry Andric         ++NumReassoc;
3380b57cec5SDimitry Andric         return W;
3390b57cec5SDimitry Andric       }
3400b57cec5SDimitry Andric     }
3410b57cec5SDimitry Andric   }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   // The remaining transforms require commutativity as well as associativity.
3440b57cec5SDimitry Andric   if (!Instruction::isCommutative(Opcode))
3450b57cec5SDimitry Andric     return nullptr;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   // Transform: "(A op B) op C" ==> "(C op A) op B" if it simplifies completely.
3480b57cec5SDimitry Andric   if (Op0 && Op0->getOpcode() == Opcode) {
3490b57cec5SDimitry Andric     Value *A = Op0->getOperand(0);
3500b57cec5SDimitry Andric     Value *B = Op0->getOperand(1);
3510b57cec5SDimitry Andric     Value *C = RHS;
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric     // Does "C op A" simplify?
35481ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Opcode, C, A, Q, MaxRecurse)) {
3550b57cec5SDimitry Andric       // It does!  Return "V op B" if it simplifies or is already available.
3560b57cec5SDimitry Andric       // If V equals A then "V op B" is just the LHS.
35781ad6265SDimitry Andric       if (V == A)
35881ad6265SDimitry Andric         return LHS;
3590b57cec5SDimitry Andric       // Otherwise return "V op B" if it simplifies.
36081ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Opcode, V, B, Q, MaxRecurse)) {
3610b57cec5SDimitry Andric         ++NumReassoc;
3620b57cec5SDimitry Andric         return W;
3630b57cec5SDimitry Andric       }
3640b57cec5SDimitry Andric     }
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   // Transform: "A op (B op C)" ==> "B op (C op A)" if it simplifies completely.
3680b57cec5SDimitry Andric   if (Op1 && Op1->getOpcode() == Opcode) {
3690b57cec5SDimitry Andric     Value *A = LHS;
3700b57cec5SDimitry Andric     Value *B = Op1->getOperand(0);
3710b57cec5SDimitry Andric     Value *C = Op1->getOperand(1);
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric     // Does "C op A" simplify?
37481ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Opcode, C, A, Q, MaxRecurse)) {
3750b57cec5SDimitry Andric       // It does!  Return "B op V" if it simplifies or is already available.
3760b57cec5SDimitry Andric       // If V equals C then "B op V" is just the RHS.
37781ad6265SDimitry Andric       if (V == C)
37881ad6265SDimitry Andric         return RHS;
3790b57cec5SDimitry Andric       // Otherwise return "B op V" if it simplifies.
38081ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Opcode, B, V, Q, MaxRecurse)) {
3810b57cec5SDimitry Andric         ++NumReassoc;
3820b57cec5SDimitry Andric         return W;
3830b57cec5SDimitry Andric       }
3840b57cec5SDimitry Andric     }
3850b57cec5SDimitry Andric   }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric   return nullptr;
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric /// In the case of a binary operation with a select instruction as an operand,
3910b57cec5SDimitry Andric /// try to simplify the binop by seeing whether evaluating it on both branches
3920b57cec5SDimitry Andric /// of the select results in the same value. Returns the common value if so,
3930b57cec5SDimitry Andric /// otherwise returns null.
39481ad6265SDimitry Andric static Value *threadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS,
3950b57cec5SDimitry Andric                                     Value *RHS, const SimplifyQuery &Q,
3960b57cec5SDimitry Andric                                     unsigned MaxRecurse) {
3970b57cec5SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
3980b57cec5SDimitry Andric   if (!MaxRecurse--)
3990b57cec5SDimitry Andric     return nullptr;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   SelectInst *SI;
4020b57cec5SDimitry Andric   if (isa<SelectInst>(LHS)) {
4030b57cec5SDimitry Andric     SI = cast<SelectInst>(LHS);
4040b57cec5SDimitry Andric   } else {
4050b57cec5SDimitry Andric     assert(isa<SelectInst>(RHS) && "No select instruction operand!");
4060b57cec5SDimitry Andric     SI = cast<SelectInst>(RHS);
4070b57cec5SDimitry Andric   }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   // Evaluate the BinOp on the true and false branches of the select.
4100b57cec5SDimitry Andric   Value *TV;
4110b57cec5SDimitry Andric   Value *FV;
4120b57cec5SDimitry Andric   if (SI == LHS) {
41381ad6265SDimitry Andric     TV = simplifyBinOp(Opcode, SI->getTrueValue(), RHS, Q, MaxRecurse);
41481ad6265SDimitry Andric     FV = simplifyBinOp(Opcode, SI->getFalseValue(), RHS, Q, MaxRecurse);
4150b57cec5SDimitry Andric   } else {
41681ad6265SDimitry Andric     TV = simplifyBinOp(Opcode, LHS, SI->getTrueValue(), Q, MaxRecurse);
41781ad6265SDimitry Andric     FV = simplifyBinOp(Opcode, LHS, SI->getFalseValue(), Q, MaxRecurse);
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   // If they simplified to the same value, then return the common value.
4210b57cec5SDimitry Andric   // If they both failed to simplify then return null.
4220b57cec5SDimitry Andric   if (TV == FV)
4230b57cec5SDimitry Andric     return TV;
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   // If one branch simplified to undef, return the other one.
426e8d8bef9SDimitry Andric   if (TV && Q.isUndefValue(TV))
4270b57cec5SDimitry Andric     return FV;
428e8d8bef9SDimitry Andric   if (FV && Q.isUndefValue(FV))
4290b57cec5SDimitry Andric     return TV;
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   // If applying the operation did not change the true and false select values,
4320b57cec5SDimitry Andric   // then the result of the binop is the select itself.
4330b57cec5SDimitry Andric   if (TV == SI->getTrueValue() && FV == SI->getFalseValue())
4340b57cec5SDimitry Andric     return SI;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   // If one branch simplified and the other did not, and the simplified
4370b57cec5SDimitry Andric   // value is equal to the unsimplified one, return the simplified value.
4380b57cec5SDimitry Andric   // For example, select (cond, X, X & Z) & Z -> X & Z.
4390b57cec5SDimitry Andric   if ((FV && !TV) || (TV && !FV)) {
4400b57cec5SDimitry Andric     // Check that the simplified value has the form "X op Y" where "op" is the
4410b57cec5SDimitry Andric     // same as the original operation.
4420b57cec5SDimitry Andric     Instruction *Simplified = dyn_cast<Instruction>(FV ? FV : TV);
443dfa39133SDimitry Andric     if (Simplified && Simplified->getOpcode() == unsigned(Opcode) &&
444dfa39133SDimitry Andric         !Simplified->hasPoisonGeneratingFlags()) {
4450b57cec5SDimitry Andric       // The value that didn't simplify is "UnsimplifiedLHS op UnsimplifiedRHS".
4460b57cec5SDimitry Andric       // We already know that "op" is the same as for the simplified value.  See
4470b57cec5SDimitry Andric       // if the operands match too.  If so, return the simplified value.
4480b57cec5SDimitry Andric       Value *UnsimplifiedBranch = FV ? SI->getTrueValue() : SI->getFalseValue();
4490b57cec5SDimitry Andric       Value *UnsimplifiedLHS = SI == LHS ? UnsimplifiedBranch : LHS;
4500b57cec5SDimitry Andric       Value *UnsimplifiedRHS = SI == LHS ? RHS : UnsimplifiedBranch;
4510b57cec5SDimitry Andric       if (Simplified->getOperand(0) == UnsimplifiedLHS &&
4520b57cec5SDimitry Andric           Simplified->getOperand(1) == UnsimplifiedRHS)
4530b57cec5SDimitry Andric         return Simplified;
4540b57cec5SDimitry Andric       if (Simplified->isCommutative() &&
4550b57cec5SDimitry Andric           Simplified->getOperand(1) == UnsimplifiedLHS &&
4560b57cec5SDimitry Andric           Simplified->getOperand(0) == UnsimplifiedRHS)
4570b57cec5SDimitry Andric         return Simplified;
4580b57cec5SDimitry Andric     }
4590b57cec5SDimitry Andric   }
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric   return nullptr;
4620b57cec5SDimitry Andric }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric /// In the case of a comparison with a select instruction, try to simplify the
4650b57cec5SDimitry Andric /// comparison by seeing whether both branches of the select result in the same
4660b57cec5SDimitry Andric /// value. Returns the common value if so, otherwise returns null.
467480093f4SDimitry Andric /// For example, if we have:
468480093f4SDimitry Andric ///  %tmp = select i1 %cmp, i32 1, i32 2
469480093f4SDimitry Andric ///  %cmp1 = icmp sle i32 %tmp, 3
470480093f4SDimitry Andric /// We can simplify %cmp1 to true, because both branches of select are
471480093f4SDimitry Andric /// less than 3. We compose new comparison by substituting %tmp with both
472480093f4SDimitry Andric /// branches of select and see if it can be simplified.
47381ad6265SDimitry Andric static Value *threadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
4740b57cec5SDimitry Andric                                   Value *RHS, const SimplifyQuery &Q,
4750b57cec5SDimitry Andric                                   unsigned MaxRecurse) {
4760b57cec5SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
4770b57cec5SDimitry Andric   if (!MaxRecurse--)
4780b57cec5SDimitry Andric     return nullptr;
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // Make sure the select is on the LHS.
4810b57cec5SDimitry Andric   if (!isa<SelectInst>(LHS)) {
4820b57cec5SDimitry Andric     std::swap(LHS, RHS);
4830b57cec5SDimitry Andric     Pred = CmpInst::getSwappedPredicate(Pred);
4840b57cec5SDimitry Andric   }
4850b57cec5SDimitry Andric   assert(isa<SelectInst>(LHS) && "Not comparing with a select instruction!");
4860b57cec5SDimitry Andric   SelectInst *SI = cast<SelectInst>(LHS);
4870b57cec5SDimitry Andric   Value *Cond = SI->getCondition();
4880b57cec5SDimitry Andric   Value *TV = SI->getTrueValue();
4890b57cec5SDimitry Andric   Value *FV = SI->getFalseValue();
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   // Now that we have "cmp select(Cond, TV, FV), RHS", analyse it.
4920b57cec5SDimitry Andric   // Does "cmp TV, RHS" simplify?
493480093f4SDimitry Andric   Value *TCmp = simplifyCmpSelTrueCase(Pred, TV, RHS, Cond, Q, MaxRecurse);
494480093f4SDimitry Andric   if (!TCmp)
4950b57cec5SDimitry Andric     return nullptr;
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   // Does "cmp FV, RHS" simplify?
498480093f4SDimitry Andric   Value *FCmp = simplifyCmpSelFalseCase(Pred, FV, RHS, Cond, Q, MaxRecurse);
499480093f4SDimitry Andric   if (!FCmp)
5000b57cec5SDimitry Andric     return nullptr;
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   // If both sides simplified to the same value, then use it as the result of
5030b57cec5SDimitry Andric   // the original comparison.
5040b57cec5SDimitry Andric   if (TCmp == FCmp)
5050b57cec5SDimitry Andric     return TCmp;
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric   // The remaining cases only make sense if the select condition has the same
5080b57cec5SDimitry Andric   // type as the result of the comparison, so bail out if this is not so.
509480093f4SDimitry Andric   if (Cond->getType()->isVectorTy() == RHS->getType()->isVectorTy())
510480093f4SDimitry Andric     return handleOtherCmpSelSimplifications(TCmp, FCmp, Cond, Q, MaxRecurse);
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric   return nullptr;
5130b57cec5SDimitry Andric }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric /// In the case of a binary operation with an operand that is a PHI instruction,
5160b57cec5SDimitry Andric /// try to simplify the binop by seeing whether evaluating it on the incoming
5170b57cec5SDimitry Andric /// phi values yields the same result for every value. If so returns the common
5180b57cec5SDimitry Andric /// value, otherwise returns null.
51981ad6265SDimitry Andric static Value *threadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS,
5200b57cec5SDimitry Andric                                  Value *RHS, const SimplifyQuery &Q,
5210b57cec5SDimitry Andric                                  unsigned MaxRecurse) {
5220b57cec5SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
5230b57cec5SDimitry Andric   if (!MaxRecurse--)
5240b57cec5SDimitry Andric     return nullptr;
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric   PHINode *PI;
5270b57cec5SDimitry Andric   if (isa<PHINode>(LHS)) {
5280b57cec5SDimitry Andric     PI = cast<PHINode>(LHS);
5290b57cec5SDimitry Andric     // Bail out if RHS and the phi may be mutually interdependent due to a loop.
5300b57cec5SDimitry Andric     if (!valueDominatesPHI(RHS, PI, Q.DT))
5310b57cec5SDimitry Andric       return nullptr;
5320b57cec5SDimitry Andric   } else {
5330b57cec5SDimitry Andric     assert(isa<PHINode>(RHS) && "No PHI instruction operand!");
5340b57cec5SDimitry Andric     PI = cast<PHINode>(RHS);
5350b57cec5SDimitry Andric     // Bail out if LHS and the phi may be mutually interdependent due to a loop.
5360b57cec5SDimitry Andric     if (!valueDominatesPHI(LHS, PI, Q.DT))
5370b57cec5SDimitry Andric       return nullptr;
5380b57cec5SDimitry Andric   }
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   // Evaluate the BinOp on the incoming phi values.
5410b57cec5SDimitry Andric   Value *CommonValue = nullptr;
54206c3fb27SDimitry Andric   for (Use &Incoming : PI->incoming_values()) {
5430b57cec5SDimitry Andric     // If the incoming value is the phi node itself, it can safely be skipped.
54481ad6265SDimitry Andric     if (Incoming == PI)
54581ad6265SDimitry Andric       continue;
54606c3fb27SDimitry Andric     Instruction *InTI = PI->getIncomingBlock(Incoming)->getTerminator();
54706c3fb27SDimitry Andric     Value *V = PI == LHS
54806c3fb27SDimitry Andric                    ? simplifyBinOp(Opcode, Incoming, RHS,
54906c3fb27SDimitry Andric                                    Q.getWithInstruction(InTI), MaxRecurse)
55006c3fb27SDimitry Andric                    : simplifyBinOp(Opcode, LHS, Incoming,
55106c3fb27SDimitry Andric                                    Q.getWithInstruction(InTI), MaxRecurse);
5520b57cec5SDimitry Andric     // If the operation failed to simplify, or simplified to a different value
5530b57cec5SDimitry Andric     // to previously, then give up.
5540b57cec5SDimitry Andric     if (!V || (CommonValue && V != CommonValue))
5550b57cec5SDimitry Andric       return nullptr;
5560b57cec5SDimitry Andric     CommonValue = V;
5570b57cec5SDimitry Andric   }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   return CommonValue;
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric /// In the case of a comparison with a PHI instruction, try to simplify the
5630b57cec5SDimitry Andric /// comparison by seeing whether comparing with all of the incoming phi values
5640b57cec5SDimitry Andric /// yields the same result every time. If so returns the common result,
5650b57cec5SDimitry Andric /// otherwise returns null.
56681ad6265SDimitry Andric static Value *threadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
5670b57cec5SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
5680b57cec5SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
5690b57cec5SDimitry Andric   if (!MaxRecurse--)
5700b57cec5SDimitry Andric     return nullptr;
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   // Make sure the phi is on the LHS.
5730b57cec5SDimitry Andric   if (!isa<PHINode>(LHS)) {
5740b57cec5SDimitry Andric     std::swap(LHS, RHS);
5750b57cec5SDimitry Andric     Pred = CmpInst::getSwappedPredicate(Pred);
5760b57cec5SDimitry Andric   }
5770b57cec5SDimitry Andric   assert(isa<PHINode>(LHS) && "Not comparing with a phi instruction!");
5780b57cec5SDimitry Andric   PHINode *PI = cast<PHINode>(LHS);
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   // Bail out if RHS and the phi may be mutually interdependent due to a loop.
5810b57cec5SDimitry Andric   if (!valueDominatesPHI(RHS, PI, Q.DT))
5820b57cec5SDimitry Andric     return nullptr;
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   // Evaluate the BinOp on the incoming phi values.
5850b57cec5SDimitry Andric   Value *CommonValue = nullptr;
586480093f4SDimitry Andric   for (unsigned u = 0, e = PI->getNumIncomingValues(); u < e; ++u) {
587480093f4SDimitry Andric     Value *Incoming = PI->getIncomingValue(u);
588480093f4SDimitry Andric     Instruction *InTI = PI->getIncomingBlock(u)->getTerminator();
5890b57cec5SDimitry Andric     // If the incoming value is the phi node itself, it can safely be skipped.
59081ad6265SDimitry Andric     if (Incoming == PI)
59181ad6265SDimitry Andric       continue;
592480093f4SDimitry Andric     // Change the context instruction to the "edge" that flows into the phi.
593480093f4SDimitry Andric     // This is important because that is where incoming is actually "evaluated"
594480093f4SDimitry Andric     // even though it is used later somewhere else.
59581ad6265SDimitry Andric     Value *V = simplifyCmpInst(Pred, Incoming, RHS, Q.getWithInstruction(InTI),
596480093f4SDimitry Andric                                MaxRecurse);
5970b57cec5SDimitry Andric     // If the operation failed to simplify, or simplified to a different value
5980b57cec5SDimitry Andric     // to previously, then give up.
5990b57cec5SDimitry Andric     if (!V || (CommonValue && V != CommonValue))
6000b57cec5SDimitry Andric       return nullptr;
6010b57cec5SDimitry Andric     CommonValue = V;
6020b57cec5SDimitry Andric   }
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   return CommonValue;
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric static Constant *foldOrCommuteConstant(Instruction::BinaryOps Opcode,
6080b57cec5SDimitry Andric                                        Value *&Op0, Value *&Op1,
6090b57cec5SDimitry Andric                                        const SimplifyQuery &Q) {
6100b57cec5SDimitry Andric   if (auto *CLHS = dyn_cast<Constant>(Op0)) {
61181ad6265SDimitry Andric     if (auto *CRHS = dyn_cast<Constant>(Op1)) {
61281ad6265SDimitry Andric       switch (Opcode) {
61381ad6265SDimitry Andric       default:
61481ad6265SDimitry Andric         break;
61581ad6265SDimitry Andric       case Instruction::FAdd:
61681ad6265SDimitry Andric       case Instruction::FSub:
61781ad6265SDimitry Andric       case Instruction::FMul:
61881ad6265SDimitry Andric       case Instruction::FDiv:
61981ad6265SDimitry Andric       case Instruction::FRem:
62081ad6265SDimitry Andric         if (Q.CxtI != nullptr)
62181ad6265SDimitry Andric           return ConstantFoldFPInstOperands(Opcode, CLHS, CRHS, Q.DL, Q.CxtI);
62281ad6265SDimitry Andric       }
6230b57cec5SDimitry Andric       return ConstantFoldBinaryOpOperands(Opcode, CLHS, CRHS, Q.DL);
62481ad6265SDimitry Andric     }
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric     // Canonicalize the constant to the RHS if this is a commutative operation.
6270b57cec5SDimitry Andric     if (Instruction::isCommutative(Opcode))
6280b57cec5SDimitry Andric       std::swap(Op0, Op1);
6290b57cec5SDimitry Andric   }
6300b57cec5SDimitry Andric   return nullptr;
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric /// Given operands for an Add, see if we can fold the result.
6340b57cec5SDimitry Andric /// If not, this returns null.
63581ad6265SDimitry Andric static Value *simplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
6360b57cec5SDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse) {
6370b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Instruction::Add, Op0, Op1, Q))
6380b57cec5SDimitry Andric     return C;
6390b57cec5SDimitry Andric 
64004eeddc0SDimitry Andric   // X + poison -> poison
64104eeddc0SDimitry Andric   if (isa<PoisonValue>(Op1))
64204eeddc0SDimitry Andric     return Op1;
64304eeddc0SDimitry Andric 
6440b57cec5SDimitry Andric   // X + undef -> undef
645e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op1))
6460b57cec5SDimitry Andric     return Op1;
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   // X + 0 -> X
6490b57cec5SDimitry Andric   if (match(Op1, m_Zero()))
6500b57cec5SDimitry Andric     return Op0;
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   // If two operands are negative, return 0.
6530b57cec5SDimitry Andric   if (isKnownNegation(Op0, Op1))
6540b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   // X + (Y - X) -> Y
6570b57cec5SDimitry Andric   // (Y - X) + X -> Y
6580b57cec5SDimitry Andric   // Eg: X + -X -> 0
6590b57cec5SDimitry Andric   Value *Y = nullptr;
6600b57cec5SDimitry Andric   if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) ||
6610b57cec5SDimitry Andric       match(Op0, m_Sub(m_Value(Y), m_Specific(Op1))))
6620b57cec5SDimitry Andric     return Y;
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric   // X + ~X -> -1   since   ~X = -X-1
6650b57cec5SDimitry Andric   Type *Ty = Op0->getType();
66681ad6265SDimitry Andric   if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0))))
6670b57cec5SDimitry Andric     return Constant::getAllOnesValue(Ty);
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   // add nsw/nuw (xor Y, signmask), signmask --> Y
6700b57cec5SDimitry Andric   // The no-wrapping add guarantees that the top bit will be set by the add.
6710b57cec5SDimitry Andric   // Therefore, the xor must be clearing the already set sign bit of Y.
6720b57cec5SDimitry Andric   if ((IsNSW || IsNUW) && match(Op1, m_SignMask()) &&
6730b57cec5SDimitry Andric       match(Op0, m_Xor(m_Value(Y), m_SignMask())))
6740b57cec5SDimitry Andric     return Y;
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric   // add nuw %x, -1  ->  -1, because %x can only be 0.
6770b57cec5SDimitry Andric   if (IsNUW && match(Op1, m_AllOnes()))
6780b57cec5SDimitry Andric     return Op1; // Which is -1.
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   /// i1 add -> xor.
6810b57cec5SDimitry Andric   if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1))
68281ad6265SDimitry Andric     if (Value *V = simplifyXorInst(Op0, Op1, Q, MaxRecurse - 1))
6830b57cec5SDimitry Andric       return V;
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   // Try some generic simplifications for associative operations.
68681ad6265SDimitry Andric   if (Value *V =
68781ad6265SDimitry Andric           simplifyAssociativeBinOp(Instruction::Add, Op0, Op1, Q, MaxRecurse))
6880b57cec5SDimitry Andric     return V;
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric   // Threading Add over selects and phi nodes is pointless, so don't bother.
6910b57cec5SDimitry Andric   // Threading over the select in "A + select(cond, B, C)" means evaluating
6920b57cec5SDimitry Andric   // "A+B" and "A+C" and seeing if they are equal; but they are equal if and
6930b57cec5SDimitry Andric   // only if B and C are equal.  If B and C are equal then (since we assume
6940b57cec5SDimitry Andric   // that operands have already been simplified) "select(cond, B, C)" should
6950b57cec5SDimitry Andric   // have been simplified to the common value of B and C already.  Analysing
6960b57cec5SDimitry Andric   // "A+B" and "A+C" thus gains nothing, but costs compile time.  Similarly
6970b57cec5SDimitry Andric   // for threading over phi nodes.
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric   return nullptr;
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric 
70281ad6265SDimitry Andric Value *llvm::simplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
7030b57cec5SDimitry Andric                              const SimplifyQuery &Query) {
70481ad6265SDimitry Andric   return ::simplifyAddInst(Op0, Op1, IsNSW, IsNUW, Query, RecursionLimit);
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric /// Compute the base pointer and cumulative constant offsets for V.
7080b57cec5SDimitry Andric ///
7090b57cec5SDimitry Andric /// This strips all constant offsets off of V, leaving it the base pointer, and
71081ad6265SDimitry Andric /// accumulates the total constant offset applied in the returned constant.
71181ad6265SDimitry Andric /// It returns zero if there are no constant offsets applied.
7120b57cec5SDimitry Andric ///
71381ad6265SDimitry Andric /// This is very similar to stripAndAccumulateConstantOffsets(), except it
71481ad6265SDimitry Andric /// normalizes the offset bitwidth to the stripped pointer type, not the
71581ad6265SDimitry Andric /// original pointer type.
71681ad6265SDimitry Andric static APInt stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V,
7170b57cec5SDimitry Andric                                             bool AllowNonInbounds = false) {
7180b57cec5SDimitry Andric   assert(V->getType()->isPtrOrPtrVectorTy());
7190b57cec5SDimitry Andric 
720349cc55cSDimitry Andric   APInt Offset = APInt::getZero(DL.getIndexTypeSizeInBits(V->getType()));
7210b57cec5SDimitry Andric   V = V->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds);
7220b57cec5SDimitry Andric   // As that strip may trace through `addrspacecast`, need to sext or trunc
7230b57cec5SDimitry Andric   // the offset calculated.
72481ad6265SDimitry Andric   return Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(V->getType()));
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric /// Compute the constant difference between two pointer values.
7280b57cec5SDimitry Andric /// If the difference is not a constant, returns zero.
7290b57cec5SDimitry Andric static Constant *computePointerDifference(const DataLayout &DL, Value *LHS,
7300b57cec5SDimitry Andric                                           Value *RHS) {
73181ad6265SDimitry Andric   APInt LHSOffset = stripAndComputeConstantOffsets(DL, LHS);
73281ad6265SDimitry Andric   APInt RHSOffset = stripAndComputeConstantOffsets(DL, RHS);
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   // If LHS and RHS are not related via constant offsets to the same base
7350b57cec5SDimitry Andric   // value, there is nothing we can do here.
7360b57cec5SDimitry Andric   if (LHS != RHS)
7370b57cec5SDimitry Andric     return nullptr;
7380b57cec5SDimitry Andric 
7390b57cec5SDimitry Andric   // Otherwise, the difference of LHS - RHS can be computed as:
7400b57cec5SDimitry Andric   //    LHS - RHS
7410b57cec5SDimitry Andric   //  = (LHSOffset + Base) - (RHSOffset + Base)
7420b57cec5SDimitry Andric   //  = LHSOffset - RHSOffset
74381ad6265SDimitry Andric   Constant *Res = ConstantInt::get(LHS->getContext(), LHSOffset - RHSOffset);
74481ad6265SDimitry Andric   if (auto *VecTy = dyn_cast<VectorType>(LHS->getType()))
74581ad6265SDimitry Andric     Res = ConstantVector::getSplat(VecTy->getElementCount(), Res);
74681ad6265SDimitry Andric   return Res;
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
749bdd1243dSDimitry Andric /// Test if there is a dominating equivalence condition for the
750bdd1243dSDimitry Andric /// two operands. If there is, try to reduce the binary operation
751bdd1243dSDimitry Andric /// between the two operands.
752bdd1243dSDimitry Andric /// Example: Op0 - Op1 --> 0 when Op0 == Op1
753bdd1243dSDimitry Andric static Value *simplifyByDomEq(unsigned Opcode, Value *Op0, Value *Op1,
754bdd1243dSDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse) {
755bdd1243dSDimitry Andric   // Recursive run it can not get any benefit
756bdd1243dSDimitry Andric   if (MaxRecurse != RecursionLimit)
757bdd1243dSDimitry Andric     return nullptr;
758bdd1243dSDimitry Andric 
759bdd1243dSDimitry Andric   std::optional<bool> Imp =
760bdd1243dSDimitry Andric       isImpliedByDomCondition(CmpInst::ICMP_EQ, Op0, Op1, Q.CxtI, Q.DL);
761bdd1243dSDimitry Andric   if (Imp && *Imp) {
762bdd1243dSDimitry Andric     Type *Ty = Op0->getType();
763bdd1243dSDimitry Andric     switch (Opcode) {
764bdd1243dSDimitry Andric     case Instruction::Sub:
765bdd1243dSDimitry Andric     case Instruction::Xor:
766bdd1243dSDimitry Andric     case Instruction::URem:
767bdd1243dSDimitry Andric     case Instruction::SRem:
768bdd1243dSDimitry Andric       return Constant::getNullValue(Ty);
769bdd1243dSDimitry Andric 
770bdd1243dSDimitry Andric     case Instruction::SDiv:
771bdd1243dSDimitry Andric     case Instruction::UDiv:
772bdd1243dSDimitry Andric       return ConstantInt::get(Ty, 1);
773bdd1243dSDimitry Andric 
774bdd1243dSDimitry Andric     case Instruction::And:
775bdd1243dSDimitry Andric     case Instruction::Or:
776bdd1243dSDimitry Andric       // Could be either one - choose Op1 since that's more likely a constant.
777bdd1243dSDimitry Andric       return Op1;
778bdd1243dSDimitry Andric     default:
779bdd1243dSDimitry Andric       break;
780bdd1243dSDimitry Andric     }
781bdd1243dSDimitry Andric   }
782bdd1243dSDimitry Andric   return nullptr;
783bdd1243dSDimitry Andric }
784bdd1243dSDimitry Andric 
7850b57cec5SDimitry Andric /// Given operands for a Sub, see if we can fold the result.
7860b57cec5SDimitry Andric /// If not, this returns null.
787bdd1243dSDimitry Andric static Value *simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
7880b57cec5SDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse) {
7890b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Instruction::Sub, Op0, Op1, Q))
7900b57cec5SDimitry Andric     return C;
7910b57cec5SDimitry Andric 
792fe6060f1SDimitry Andric   // X - poison -> poison
793fe6060f1SDimitry Andric   // poison - X -> poison
794fe6060f1SDimitry Andric   if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
795fe6060f1SDimitry Andric     return PoisonValue::get(Op0->getType());
796fe6060f1SDimitry Andric 
7970b57cec5SDimitry Andric   // X - undef -> undef
7980b57cec5SDimitry Andric   // undef - X -> undef
799e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
8000b57cec5SDimitry Andric     return UndefValue::get(Op0->getType());
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric   // X - 0 -> X
8030b57cec5SDimitry Andric   if (match(Op1, m_Zero()))
8040b57cec5SDimitry Andric     return Op0;
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   // X - X -> 0
8070b57cec5SDimitry Andric   if (Op0 == Op1)
8080b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric   // Is this a negation?
8110b57cec5SDimitry Andric   if (match(Op0, m_Zero())) {
8120b57cec5SDimitry Andric     // 0 - X -> 0 if the sub is NUW.
813bdd1243dSDimitry Andric     if (IsNUW)
8140b57cec5SDimitry Andric       return Constant::getNullValue(Op0->getType());
8150b57cec5SDimitry Andric 
8165f757f3fSDimitry Andric     KnownBits Known = computeKnownBits(Op1, /* Depth */ 0, Q);
8170b57cec5SDimitry Andric     if (Known.Zero.isMaxSignedValue()) {
8180b57cec5SDimitry Andric       // Op1 is either 0 or the minimum signed value. If the sub is NSW, then
8190b57cec5SDimitry Andric       // Op1 must be 0 because negating the minimum signed value is undefined.
820bdd1243dSDimitry Andric       if (IsNSW)
8210b57cec5SDimitry Andric         return Constant::getNullValue(Op0->getType());
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric       // 0 - X -> X if X is 0 or the minimum signed value.
8240b57cec5SDimitry Andric       return Op1;
8250b57cec5SDimitry Andric     }
8260b57cec5SDimitry Andric   }
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric   // (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
8290b57cec5SDimitry Andric   // For example, (X + Y) - Y -> X; (Y + X) - Y -> X
8300b57cec5SDimitry Andric   Value *X = nullptr, *Y = nullptr, *Z = Op1;
8310b57cec5SDimitry Andric   if (MaxRecurse && match(Op0, m_Add(m_Value(X), m_Value(Y)))) { // (X + Y) - Z
8320b57cec5SDimitry Andric     // See if "V === Y - Z" simplifies.
83381ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Instruction::Sub, Y, Z, Q, MaxRecurse - 1))
8340b57cec5SDimitry Andric       // It does!  Now see if "X + V" simplifies.
83581ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Instruction::Add, X, V, Q, MaxRecurse - 1)) {
8360b57cec5SDimitry Andric         // It does, we successfully reassociated!
8370b57cec5SDimitry Andric         ++NumReassoc;
8380b57cec5SDimitry Andric         return W;
8390b57cec5SDimitry Andric       }
8400b57cec5SDimitry Andric     // See if "V === X - Z" simplifies.
84181ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Instruction::Sub, X, Z, Q, MaxRecurse - 1))
8420b57cec5SDimitry Andric       // It does!  Now see if "Y + V" simplifies.
84381ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Instruction::Add, Y, V, Q, MaxRecurse - 1)) {
8440b57cec5SDimitry Andric         // It does, we successfully reassociated!
8450b57cec5SDimitry Andric         ++NumReassoc;
8460b57cec5SDimitry Andric         return W;
8470b57cec5SDimitry Andric       }
8480b57cec5SDimitry Andric   }
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric   // X - (Y + Z) -> (X - Y) - Z or (X - Z) - Y if everything simplifies.
8510b57cec5SDimitry Andric   // For example, X - (X + 1) -> -1
8520b57cec5SDimitry Andric   X = Op0;
8530b57cec5SDimitry Andric   if (MaxRecurse && match(Op1, m_Add(m_Value(Y), m_Value(Z)))) { // X - (Y + Z)
8540b57cec5SDimitry Andric     // See if "V === X - Y" simplifies.
85581ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse - 1))
8560b57cec5SDimitry Andric       // It does!  Now see if "V - Z" simplifies.
85781ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Instruction::Sub, V, Z, Q, MaxRecurse - 1)) {
8580b57cec5SDimitry Andric         // It does, we successfully reassociated!
8590b57cec5SDimitry Andric         ++NumReassoc;
8600b57cec5SDimitry Andric         return W;
8610b57cec5SDimitry Andric       }
8620b57cec5SDimitry Andric     // See if "V === X - Z" simplifies.
86381ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Instruction::Sub, X, Z, Q, MaxRecurse - 1))
8640b57cec5SDimitry Andric       // It does!  Now see if "V - Y" simplifies.
86581ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Instruction::Sub, V, Y, Q, MaxRecurse - 1)) {
8660b57cec5SDimitry Andric         // It does, we successfully reassociated!
8670b57cec5SDimitry Andric         ++NumReassoc;
8680b57cec5SDimitry Andric         return W;
8690b57cec5SDimitry Andric       }
8700b57cec5SDimitry Andric   }
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric   // Z - (X - Y) -> (Z - X) + Y if everything simplifies.
8730b57cec5SDimitry Andric   // For example, X - (X - Y) -> Y.
8740b57cec5SDimitry Andric   Z = Op0;
8750b57cec5SDimitry Andric   if (MaxRecurse && match(Op1, m_Sub(m_Value(X), m_Value(Y)))) // Z - (X - Y)
8760b57cec5SDimitry Andric     // See if "V === Z - X" simplifies.
87781ad6265SDimitry Andric     if (Value *V = simplifyBinOp(Instruction::Sub, Z, X, Q, MaxRecurse - 1))
8780b57cec5SDimitry Andric       // It does!  Now see if "V + Y" simplifies.
87981ad6265SDimitry Andric       if (Value *W = simplifyBinOp(Instruction::Add, V, Y, Q, MaxRecurse - 1)) {
8800b57cec5SDimitry Andric         // It does, we successfully reassociated!
8810b57cec5SDimitry Andric         ++NumReassoc;
8820b57cec5SDimitry Andric         return W;
8830b57cec5SDimitry Andric       }
8840b57cec5SDimitry Andric 
8850b57cec5SDimitry Andric   // trunc(X) - trunc(Y) -> trunc(X - Y) if everything simplifies.
8860b57cec5SDimitry Andric   if (MaxRecurse && match(Op0, m_Trunc(m_Value(X))) &&
8870b57cec5SDimitry Andric       match(Op1, m_Trunc(m_Value(Y))))
8880b57cec5SDimitry Andric     if (X->getType() == Y->getType())
8890b57cec5SDimitry Andric       // See if "V === X - Y" simplifies.
89081ad6265SDimitry Andric       if (Value *V = simplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse - 1))
8910b57cec5SDimitry Andric         // It does!  Now see if "trunc V" simplifies.
89281ad6265SDimitry Andric         if (Value *W = simplifyCastInst(Instruction::Trunc, V, Op0->getType(),
8930b57cec5SDimitry Andric                                         Q, MaxRecurse - 1))
8940b57cec5SDimitry Andric           // It does, return the simplified "trunc V".
8950b57cec5SDimitry Andric           return W;
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric   // Variations on GEP(base, I, ...) - GEP(base, i, ...) -> GEP(null, I-i, ...).
89881ad6265SDimitry Andric   if (match(Op0, m_PtrToInt(m_Value(X))) && match(Op1, m_PtrToInt(m_Value(Y))))
8990b57cec5SDimitry Andric     if (Constant *Result = computePointerDifference(Q.DL, X, Y))
9005f757f3fSDimitry Andric       return ConstantFoldIntegerCast(Result, Op0->getType(), /*IsSigned*/ true,
9015f757f3fSDimitry Andric                                      Q.DL);
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric   // i1 sub -> xor.
9040b57cec5SDimitry Andric   if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1))
90581ad6265SDimitry Andric     if (Value *V = simplifyXorInst(Op0, Op1, Q, MaxRecurse - 1))
9060b57cec5SDimitry Andric       return V;
9070b57cec5SDimitry Andric 
9080b57cec5SDimitry Andric   // Threading Sub over selects and phi nodes is pointless, so don't bother.
9090b57cec5SDimitry Andric   // Threading over the select in "A - select(cond, B, C)" means evaluating
9100b57cec5SDimitry Andric   // "A-B" and "A-C" and seeing if they are equal; but they are equal if and
9110b57cec5SDimitry Andric   // only if B and C are equal.  If B and C are equal then (since we assume
9120b57cec5SDimitry Andric   // that operands have already been simplified) "select(cond, B, C)" should
9130b57cec5SDimitry Andric   // have been simplified to the common value of B and C already.  Analysing
9140b57cec5SDimitry Andric   // "A-B" and "A-C" thus gains nothing, but costs compile time.  Similarly
9150b57cec5SDimitry Andric   // for threading over phi nodes.
9160b57cec5SDimitry Andric 
917bdd1243dSDimitry Andric   if (Value *V = simplifyByDomEq(Instruction::Sub, Op0, Op1, Q, MaxRecurse))
918bdd1243dSDimitry Andric     return V;
919bdd1243dSDimitry Andric 
9200b57cec5SDimitry Andric   return nullptr;
9210b57cec5SDimitry Andric }
9220b57cec5SDimitry Andric 
923bdd1243dSDimitry Andric Value *llvm::simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
9240b57cec5SDimitry Andric                              const SimplifyQuery &Q) {
925bdd1243dSDimitry Andric   return ::simplifySubInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
9260b57cec5SDimitry Andric }
9270b57cec5SDimitry Andric 
9280b57cec5SDimitry Andric /// Given operands for a Mul, see if we can fold the result.
9290b57cec5SDimitry Andric /// If not, this returns null.
930bdd1243dSDimitry Andric static Value *simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
931bdd1243dSDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse) {
9320b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Instruction::Mul, Op0, Op1, Q))
9330b57cec5SDimitry Andric     return C;
9340b57cec5SDimitry Andric 
935fe6060f1SDimitry Andric   // X * poison -> poison
936fe6060f1SDimitry Andric   if (isa<PoisonValue>(Op1))
937fe6060f1SDimitry Andric     return Op1;
938fe6060f1SDimitry Andric 
9390b57cec5SDimitry Andric   // X * undef -> 0
9400b57cec5SDimitry Andric   // X * 0 -> 0
941e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op1) || match(Op1, m_Zero()))
9420b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric   // X * 1 -> X
9450b57cec5SDimitry Andric   if (match(Op1, m_One()))
9460b57cec5SDimitry Andric     return Op0;
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric   // (X / Y) * Y -> X if the division is exact.
9490b57cec5SDimitry Andric   Value *X = nullptr;
9500b57cec5SDimitry Andric   if (Q.IIQ.UseInstrInfo &&
9510b57cec5SDimitry Andric       (match(Op0,
9520b57cec5SDimitry Andric              m_Exact(m_IDiv(m_Value(X), m_Specific(Op1)))) ||     // (X / Y) * Y
9530b57cec5SDimitry Andric        match(Op1, m_Exact(m_IDiv(m_Value(X), m_Specific(Op0)))))) // Y * (X / Y)
9540b57cec5SDimitry Andric     return X;
9550b57cec5SDimitry Andric 
956bdd1243dSDimitry Andric    if (Op0->getType()->isIntOrIntVectorTy(1)) {
957bdd1243dSDimitry Andric     // mul i1 nsw is a special-case because -1 * -1 is poison (+1 is not
958bdd1243dSDimitry Andric     // representable). All other cases reduce to 0, so just return 0.
959bdd1243dSDimitry Andric     if (IsNSW)
960bdd1243dSDimitry Andric       return ConstantInt::getNullValue(Op0->getType());
961bdd1243dSDimitry Andric 
962bdd1243dSDimitry Andric     // Treat "mul i1" as "and i1".
963bdd1243dSDimitry Andric     if (MaxRecurse)
96481ad6265SDimitry Andric       if (Value *V = simplifyAndInst(Op0, Op1, Q, MaxRecurse - 1))
9650b57cec5SDimitry Andric         return V;
966bdd1243dSDimitry Andric   }
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   // Try some generic simplifications for associative operations.
96981ad6265SDimitry Andric   if (Value *V =
97081ad6265SDimitry Andric           simplifyAssociativeBinOp(Instruction::Mul, Op0, Op1, Q, MaxRecurse))
9710b57cec5SDimitry Andric     return V;
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   // Mul distributes over Add. Try some generic simplifications based on this.
974e8d8bef9SDimitry Andric   if (Value *V = expandCommutativeBinOp(Instruction::Mul, Op0, Op1,
975e8d8bef9SDimitry Andric                                         Instruction::Add, Q, MaxRecurse))
9760b57cec5SDimitry Andric     return V;
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   // If the operation is with the result of a select instruction, check whether
9790b57cec5SDimitry Andric   // operating on either branch of the select always yields the same value.
9800b57cec5SDimitry Andric   if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
98181ad6265SDimitry Andric     if (Value *V =
98281ad6265SDimitry Andric             threadBinOpOverSelect(Instruction::Mul, Op0, Op1, Q, MaxRecurse))
9830b57cec5SDimitry Andric       return V;
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   // If the operation is with the result of a phi instruction, check whether
9860b57cec5SDimitry Andric   // operating on all incoming values of the phi always yields the same value.
9870b57cec5SDimitry Andric   if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
98881ad6265SDimitry Andric     if (Value *V =
98981ad6265SDimitry Andric             threadBinOpOverPHI(Instruction::Mul, Op0, Op1, Q, MaxRecurse))
9900b57cec5SDimitry Andric       return V;
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric   return nullptr;
9930b57cec5SDimitry Andric }
9940b57cec5SDimitry Andric 
995bdd1243dSDimitry Andric Value *llvm::simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
996bdd1243dSDimitry Andric                              const SimplifyQuery &Q) {
997bdd1243dSDimitry Andric   return ::simplifyMulInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric 
100006c3fb27SDimitry Andric /// Given a predicate and two operands, return true if the comparison is true.
100106c3fb27SDimitry Andric /// This is a helper for div/rem simplification where we return some other value
100206c3fb27SDimitry Andric /// when we can prove a relationship between the operands.
100306c3fb27SDimitry Andric static bool isICmpTrue(ICmpInst::Predicate Pred, Value *LHS, Value *RHS,
100406c3fb27SDimitry Andric                        const SimplifyQuery &Q, unsigned MaxRecurse) {
100506c3fb27SDimitry Andric   Value *V = simplifyICmpInst(Pred, LHS, RHS, Q, MaxRecurse);
100606c3fb27SDimitry Andric   Constant *C = dyn_cast_or_null<Constant>(V);
100706c3fb27SDimitry Andric   return (C && C->isAllOnesValue());
100806c3fb27SDimitry Andric }
100906c3fb27SDimitry Andric 
101006c3fb27SDimitry Andric /// Return true if we can simplify X / Y to 0. Remainder can adapt that answer
101106c3fb27SDimitry Andric /// to simplify X % Y to X.
101206c3fb27SDimitry Andric static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q,
101306c3fb27SDimitry Andric                       unsigned MaxRecurse, bool IsSigned) {
101406c3fb27SDimitry Andric   // Recursion is always used, so bail out at once if we already hit the limit.
101506c3fb27SDimitry Andric   if (!MaxRecurse--)
101606c3fb27SDimitry Andric     return false;
101706c3fb27SDimitry Andric 
101806c3fb27SDimitry Andric   if (IsSigned) {
101906c3fb27SDimitry Andric     // (X srem Y) sdiv Y --> 0
102006c3fb27SDimitry Andric     if (match(X, m_SRem(m_Value(), m_Specific(Y))))
102106c3fb27SDimitry Andric       return true;
102206c3fb27SDimitry Andric 
102306c3fb27SDimitry Andric     // |X| / |Y| --> 0
102406c3fb27SDimitry Andric     //
102506c3fb27SDimitry Andric     // We require that 1 operand is a simple constant. That could be extended to
102606c3fb27SDimitry Andric     // 2 variables if we computed the sign bit for each.
102706c3fb27SDimitry Andric     //
102806c3fb27SDimitry Andric     // Make sure that a constant is not the minimum signed value because taking
102906c3fb27SDimitry Andric     // the abs() of that is undefined.
103006c3fb27SDimitry Andric     Type *Ty = X->getType();
103106c3fb27SDimitry Andric     const APInt *C;
103206c3fb27SDimitry Andric     if (match(X, m_APInt(C)) && !C->isMinSignedValue()) {
103306c3fb27SDimitry Andric       // Is the variable divisor magnitude always greater than the constant
103406c3fb27SDimitry Andric       // dividend magnitude?
103506c3fb27SDimitry Andric       // |Y| > |C| --> Y < -abs(C) or Y > abs(C)
103606c3fb27SDimitry Andric       Constant *PosDividendC = ConstantInt::get(Ty, C->abs());
103706c3fb27SDimitry Andric       Constant *NegDividendC = ConstantInt::get(Ty, -C->abs());
103806c3fb27SDimitry Andric       if (isICmpTrue(CmpInst::ICMP_SLT, Y, NegDividendC, Q, MaxRecurse) ||
103906c3fb27SDimitry Andric           isICmpTrue(CmpInst::ICMP_SGT, Y, PosDividendC, Q, MaxRecurse))
104006c3fb27SDimitry Andric         return true;
104106c3fb27SDimitry Andric     }
104206c3fb27SDimitry Andric     if (match(Y, m_APInt(C))) {
104306c3fb27SDimitry Andric       // Special-case: we can't take the abs() of a minimum signed value. If
104406c3fb27SDimitry Andric       // that's the divisor, then all we have to do is prove that the dividend
104506c3fb27SDimitry Andric       // is also not the minimum signed value.
104606c3fb27SDimitry Andric       if (C->isMinSignedValue())
104706c3fb27SDimitry Andric         return isICmpTrue(CmpInst::ICMP_NE, X, Y, Q, MaxRecurse);
104806c3fb27SDimitry Andric 
104906c3fb27SDimitry Andric       // Is the variable dividend magnitude always less than the constant
105006c3fb27SDimitry Andric       // divisor magnitude?
105106c3fb27SDimitry Andric       // |X| < |C| --> X > -abs(C) and X < abs(C)
105206c3fb27SDimitry Andric       Constant *PosDivisorC = ConstantInt::get(Ty, C->abs());
105306c3fb27SDimitry Andric       Constant *NegDivisorC = ConstantInt::get(Ty, -C->abs());
105406c3fb27SDimitry Andric       if (isICmpTrue(CmpInst::ICMP_SGT, X, NegDivisorC, Q, MaxRecurse) &&
105506c3fb27SDimitry Andric           isICmpTrue(CmpInst::ICMP_SLT, X, PosDivisorC, Q, MaxRecurse))
105606c3fb27SDimitry Andric         return true;
105706c3fb27SDimitry Andric     }
105806c3fb27SDimitry Andric     return false;
105906c3fb27SDimitry Andric   }
106006c3fb27SDimitry Andric 
106106c3fb27SDimitry Andric   // IsSigned == false.
106206c3fb27SDimitry Andric 
106306c3fb27SDimitry Andric   // Is the unsigned dividend known to be less than a constant divisor?
106406c3fb27SDimitry Andric   // TODO: Convert this (and above) to range analysis
106506c3fb27SDimitry Andric   //      ("computeConstantRangeIncludingKnownBits")?
106606c3fb27SDimitry Andric   const APInt *C;
106706c3fb27SDimitry Andric   if (match(Y, m_APInt(C)) &&
10685f757f3fSDimitry Andric       computeKnownBits(X, /* Depth */ 0, Q).getMaxValue().ult(*C))
106906c3fb27SDimitry Andric     return true;
107006c3fb27SDimitry Andric 
107106c3fb27SDimitry Andric   // Try again for any divisor:
107206c3fb27SDimitry Andric   // Is the dividend unsigned less than the divisor?
107306c3fb27SDimitry Andric   return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
107406c3fb27SDimitry Andric }
107506c3fb27SDimitry Andric 
10760b57cec5SDimitry Andric /// Check for common or similar folds of integer division or integer remainder.
10770b57cec5SDimitry Andric /// This applies to all 4 opcodes (sdiv/udiv/srem/urem).
1078fe6060f1SDimitry Andric static Value *simplifyDivRem(Instruction::BinaryOps Opcode, Value *Op0,
1079bdd1243dSDimitry Andric                              Value *Op1, const SimplifyQuery &Q,
1080bdd1243dSDimitry Andric                              unsigned MaxRecurse) {
1081fe6060f1SDimitry Andric   bool IsDiv = (Opcode == Instruction::SDiv || Opcode == Instruction::UDiv);
1082fe6060f1SDimitry Andric   bool IsSigned = (Opcode == Instruction::SDiv || Opcode == Instruction::SRem);
1083fe6060f1SDimitry Andric 
10840b57cec5SDimitry Andric   Type *Ty = Op0->getType();
10850b57cec5SDimitry Andric 
1086e8d8bef9SDimitry Andric   // X / undef -> poison
1087e8d8bef9SDimitry Andric   // X % undef -> poison
10881fd87a68SDimitry Andric   if (Q.isUndefValue(Op1) || isa<PoisonValue>(Op1))
1089e8d8bef9SDimitry Andric     return PoisonValue::get(Ty);
10900b57cec5SDimitry Andric 
1091e8d8bef9SDimitry Andric   // X / 0 -> poison
1092e8d8bef9SDimitry Andric   // X % 0 -> poison
10930b57cec5SDimitry Andric   // We don't need to preserve faults!
10940b57cec5SDimitry Andric   if (match(Op1, m_Zero()))
1095e8d8bef9SDimitry Andric     return PoisonValue::get(Ty);
10960b57cec5SDimitry Andric 
1097e8d8bef9SDimitry Andric   // If any element of a constant divisor fixed width vector is zero or undef
1098e8d8bef9SDimitry Andric   // the behavior is undefined and we can fold the whole op to poison.
10990b57cec5SDimitry Andric   auto *Op1C = dyn_cast<Constant>(Op1);
11005ffd83dbSDimitry Andric   auto *VTy = dyn_cast<FixedVectorType>(Ty);
11015ffd83dbSDimitry Andric   if (Op1C && VTy) {
11025ffd83dbSDimitry Andric     unsigned NumElts = VTy->getNumElements();
11030b57cec5SDimitry Andric     for (unsigned i = 0; i != NumElts; ++i) {
11040b57cec5SDimitry Andric       Constant *Elt = Op1C->getAggregateElement(i);
1105e8d8bef9SDimitry Andric       if (Elt && (Elt->isNullValue() || Q.isUndefValue(Elt)))
1106e8d8bef9SDimitry Andric         return PoisonValue::get(Ty);
11070b57cec5SDimitry Andric     }
11080b57cec5SDimitry Andric   }
11090b57cec5SDimitry Andric 
1110fe6060f1SDimitry Andric   // poison / X -> poison
1111fe6060f1SDimitry Andric   // poison % X -> poison
1112fe6060f1SDimitry Andric   if (isa<PoisonValue>(Op0))
1113fe6060f1SDimitry Andric     return Op0;
1114fe6060f1SDimitry Andric 
11150b57cec5SDimitry Andric   // undef / X -> 0
11160b57cec5SDimitry Andric   // undef % X -> 0
1117e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op0))
11180b57cec5SDimitry Andric     return Constant::getNullValue(Ty);
11190b57cec5SDimitry Andric 
11200b57cec5SDimitry Andric   // 0 / X -> 0
11210b57cec5SDimitry Andric   // 0 % X -> 0
11220b57cec5SDimitry Andric   if (match(Op0, m_Zero()))
11230b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
11240b57cec5SDimitry Andric 
11250b57cec5SDimitry Andric   // X / X -> 1
11260b57cec5SDimitry Andric   // X % X -> 0
11270b57cec5SDimitry Andric   if (Op0 == Op1)
11280b57cec5SDimitry Andric     return IsDiv ? ConstantInt::get(Ty, 1) : Constant::getNullValue(Ty);
11290b57cec5SDimitry Andric 
11305f757f3fSDimitry Andric   KnownBits Known = computeKnownBits(Op1, /* Depth */ 0, Q);
113106c3fb27SDimitry Andric   // X / 0 -> poison
113206c3fb27SDimitry Andric   // X % 0 -> poison
113306c3fb27SDimitry Andric   // If the divisor is known to be zero, just return poison. This can happen in
113406c3fb27SDimitry Andric   // some cases where its provable indirectly the denominator is zero but it's
113506c3fb27SDimitry Andric   // not trivially simplifiable (i.e known zero through a phi node).
113606c3fb27SDimitry Andric   if (Known.isZero())
113706c3fb27SDimitry Andric     return PoisonValue::get(Ty);
113806c3fb27SDimitry Andric 
11390b57cec5SDimitry Andric   // X / 1 -> X
11400b57cec5SDimitry Andric   // X % 1 -> 0
114106c3fb27SDimitry Andric   // If the divisor can only be zero or one, we can't have division-by-zero
114206c3fb27SDimitry Andric   // or remainder-by-zero, so assume the divisor is 1.
114306c3fb27SDimitry Andric   //   e.g. 1, zext (i8 X), sdiv X (Y and 1)
114406c3fb27SDimitry Andric   if (Known.countMinLeadingZeros() == Known.getBitWidth() - 1)
11450b57cec5SDimitry Andric     return IsDiv ? Op0 : Constant::getNullValue(Ty);
11460b57cec5SDimitry Andric 
1147fe6060f1SDimitry Andric   // If X * Y does not overflow, then:
1148fe6060f1SDimitry Andric   //   X * Y / Y -> X
1149fe6060f1SDimitry Andric   //   X * Y % Y -> 0
115006c3fb27SDimitry Andric   Value *X;
1151fe6060f1SDimitry Andric   if (match(Op0, m_c_Mul(m_Value(X), m_Specific(Op1)))) {
1152fe6060f1SDimitry Andric     auto *Mul = cast<OverflowingBinaryOperator>(Op0);
1153fe6060f1SDimitry Andric     // The multiplication can't overflow if it is defined not to, or if
1154fe6060f1SDimitry Andric     // X == A / Y for some A.
1155fe6060f1SDimitry Andric     if ((IsSigned && Q.IIQ.hasNoSignedWrap(Mul)) ||
1156fe6060f1SDimitry Andric         (!IsSigned && Q.IIQ.hasNoUnsignedWrap(Mul)) ||
1157fe6060f1SDimitry Andric         (IsSigned && match(X, m_SDiv(m_Value(), m_Specific(Op1)))) ||
1158fe6060f1SDimitry Andric         (!IsSigned && match(X, m_UDiv(m_Value(), m_Specific(Op1))))) {
1159fe6060f1SDimitry Andric       return IsDiv ? X : Constant::getNullValue(Op0->getType());
1160fe6060f1SDimitry Andric     }
1161fe6060f1SDimitry Andric   }
1162fe6060f1SDimitry Andric 
116306c3fb27SDimitry Andric   if (isDivZero(Op0, Op1, Q, MaxRecurse, IsSigned))
116406c3fb27SDimitry Andric     return IsDiv ? Constant::getNullValue(Op0->getType()) : Op0;
116506c3fb27SDimitry Andric 
1166bdd1243dSDimitry Andric   if (Value *V = simplifyByDomEq(Opcode, Op0, Op1, Q, MaxRecurse))
1167bdd1243dSDimitry Andric     return V;
1168bdd1243dSDimitry Andric 
116906c3fb27SDimitry Andric   // If the operation is with the result of a select instruction, check whether
117006c3fb27SDimitry Andric   // operating on either branch of the select always yields the same value.
117106c3fb27SDimitry Andric   if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
117206c3fb27SDimitry Andric     if (Value *V = threadBinOpOverSelect(Opcode, Op0, Op1, Q, MaxRecurse))
117306c3fb27SDimitry Andric       return V;
117406c3fb27SDimitry Andric 
117506c3fb27SDimitry Andric   // If the operation is with the result of a phi instruction, check whether
117606c3fb27SDimitry Andric   // operating on all incoming values of the phi always yields the same value.
117706c3fb27SDimitry Andric   if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
117806c3fb27SDimitry Andric     if (Value *V = threadBinOpOverPHI(Opcode, Op0, Op1, Q, MaxRecurse))
117906c3fb27SDimitry Andric       return V;
118006c3fb27SDimitry Andric 
11810b57cec5SDimitry Andric   return nullptr;
11820b57cec5SDimitry Andric }
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric /// These are simplifications common to SDiv and UDiv.
11850b57cec5SDimitry Andric static Value *simplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
1186bdd1243dSDimitry Andric                           bool IsExact, const SimplifyQuery &Q,
1187bdd1243dSDimitry Andric                           unsigned MaxRecurse) {
11880b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
11890b57cec5SDimitry Andric     return C;
11900b57cec5SDimitry Andric 
1191bdd1243dSDimitry Andric   if (Value *V = simplifyDivRem(Opcode, Op0, Op1, Q, MaxRecurse))
11920b57cec5SDimitry Andric     return V;
11930b57cec5SDimitry Andric 
1194bdd1243dSDimitry Andric   const APInt *DivC;
1195647cbc5dSDimitry Andric   if (IsExact && match(Op1, m_APInt(DivC))) {
1196647cbc5dSDimitry Andric     // If this is an exact divide by a constant, then the dividend (Op0) must
1197647cbc5dSDimitry Andric     // have at least as many trailing zeros as the divisor to divide evenly. If
1198647cbc5dSDimitry Andric     // it has less trailing zeros, then the result must be poison.
1199647cbc5dSDimitry Andric     if (DivC->countr_zero()) {
12005f757f3fSDimitry Andric       KnownBits KnownOp0 = computeKnownBits(Op0, /* Depth */ 0, Q);
120106c3fb27SDimitry Andric       if (KnownOp0.countMaxTrailingZeros() < DivC->countr_zero())
1202bdd1243dSDimitry Andric         return PoisonValue::get(Op0->getType());
1203bdd1243dSDimitry Andric     }
1204bdd1243dSDimitry Andric 
1205647cbc5dSDimitry Andric     // udiv exact (mul nsw X, C), C --> X
1206647cbc5dSDimitry Andric     // sdiv exact (mul nuw X, C), C --> X
1207647cbc5dSDimitry Andric     // where C is not a power of 2.
1208647cbc5dSDimitry Andric     Value *X;
1209647cbc5dSDimitry Andric     if (!DivC->isPowerOf2() &&
1210647cbc5dSDimitry Andric         (Opcode == Instruction::UDiv
1211647cbc5dSDimitry Andric              ? match(Op0, m_NSWMul(m_Value(X), m_Specific(Op1)))
1212647cbc5dSDimitry Andric              : match(Op0, m_NUWMul(m_Value(X), m_Specific(Op1)))))
1213647cbc5dSDimitry Andric       return X;
1214647cbc5dSDimitry Andric   }
1215647cbc5dSDimitry Andric 
12160b57cec5SDimitry Andric   return nullptr;
12170b57cec5SDimitry Andric }
12180b57cec5SDimitry Andric 
12190b57cec5SDimitry Andric /// These are simplifications common to SRem and URem.
12200b57cec5SDimitry Andric static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
12210b57cec5SDimitry Andric                           const SimplifyQuery &Q, unsigned MaxRecurse) {
12220b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
12230b57cec5SDimitry Andric     return C;
12240b57cec5SDimitry Andric 
1225bdd1243dSDimitry Andric   if (Value *V = simplifyDivRem(Opcode, Op0, Op1, Q, MaxRecurse))
12260b57cec5SDimitry Andric     return V;
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric   // (X << Y) % X -> 0
1229*0fca6ea1SDimitry Andric   if (Q.IIQ.UseInstrInfo) {
1230*0fca6ea1SDimitry Andric     if ((Opcode == Instruction::SRem &&
12310b57cec5SDimitry Andric          match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
12320b57cec5SDimitry Andric         (Opcode == Instruction::URem &&
1233*0fca6ea1SDimitry Andric          match(Op0, m_NUWShl(m_Specific(Op1), m_Value()))))
12340b57cec5SDimitry Andric       return Constant::getNullValue(Op0->getType());
12350b57cec5SDimitry Andric 
1236*0fca6ea1SDimitry Andric     const APInt *C0;
1237*0fca6ea1SDimitry Andric     if (match(Op1, m_APInt(C0))) {
1238*0fca6ea1SDimitry Andric       // (srem (mul nsw X, C1), C0) -> 0 if C1 s% C0 == 0
1239*0fca6ea1SDimitry Andric       // (urem (mul nuw X, C1), C0) -> 0 if C1 u% C0 == 0
1240*0fca6ea1SDimitry Andric       if (Opcode == Instruction::SRem
1241*0fca6ea1SDimitry Andric               ? match(Op0,
1242*0fca6ea1SDimitry Andric                       m_NSWMul(m_Value(), m_CheckedInt([C0](const APInt &C) {
1243*0fca6ea1SDimitry Andric                                  return C.srem(*C0).isZero();
1244*0fca6ea1SDimitry Andric                                })))
1245*0fca6ea1SDimitry Andric               : match(Op0,
1246*0fca6ea1SDimitry Andric                       m_NUWMul(m_Value(), m_CheckedInt([C0](const APInt &C) {
1247*0fca6ea1SDimitry Andric                                  return C.urem(*C0).isZero();
1248*0fca6ea1SDimitry Andric                                }))))
1249*0fca6ea1SDimitry Andric         return Constant::getNullValue(Op0->getType());
1250*0fca6ea1SDimitry Andric     }
1251*0fca6ea1SDimitry Andric   }
12520b57cec5SDimitry Andric   return nullptr;
12530b57cec5SDimitry Andric }
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric /// Given operands for an SDiv, see if we can fold the result.
12560b57cec5SDimitry Andric /// If not, this returns null.
1257bdd1243dSDimitry Andric static Value *simplifySDivInst(Value *Op0, Value *Op1, bool IsExact,
1258bdd1243dSDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
12590b57cec5SDimitry Andric   // If two operands are negated and no signed overflow, return -1.
12600b57cec5SDimitry Andric   if (isKnownNegation(Op0, Op1, /*NeedNSW=*/true))
12610b57cec5SDimitry Andric     return Constant::getAllOnesValue(Op0->getType());
12620b57cec5SDimitry Andric 
1263bdd1243dSDimitry Andric   return simplifyDiv(Instruction::SDiv, Op0, Op1, IsExact, Q, MaxRecurse);
12640b57cec5SDimitry Andric }
12650b57cec5SDimitry Andric 
1266bdd1243dSDimitry Andric Value *llvm::simplifySDivInst(Value *Op0, Value *Op1, bool IsExact,
1267bdd1243dSDimitry Andric                               const SimplifyQuery &Q) {
1268bdd1243dSDimitry Andric   return ::simplifySDivInst(Op0, Op1, IsExact, Q, RecursionLimit);
12690b57cec5SDimitry Andric }
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric /// Given operands for a UDiv, see if we can fold the result.
12720b57cec5SDimitry Andric /// If not, this returns null.
1273bdd1243dSDimitry Andric static Value *simplifyUDivInst(Value *Op0, Value *Op1, bool IsExact,
1274bdd1243dSDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
1275bdd1243dSDimitry Andric   return simplifyDiv(Instruction::UDiv, Op0, Op1, IsExact, Q, MaxRecurse);
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric 
1278bdd1243dSDimitry Andric Value *llvm::simplifyUDivInst(Value *Op0, Value *Op1, bool IsExact,
1279bdd1243dSDimitry Andric                               const SimplifyQuery &Q) {
1280bdd1243dSDimitry Andric   return ::simplifyUDivInst(Op0, Op1, IsExact, Q, RecursionLimit);
12810b57cec5SDimitry Andric }
12820b57cec5SDimitry Andric 
12830b57cec5SDimitry Andric /// Given operands for an SRem, see if we can fold the result.
12840b57cec5SDimitry Andric /// If not, this returns null.
128581ad6265SDimitry Andric static Value *simplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
12860b57cec5SDimitry Andric                                unsigned MaxRecurse) {
12870b57cec5SDimitry Andric   // If the divisor is 0, the result is undefined, so assume the divisor is -1.
12880b57cec5SDimitry Andric   // srem Op0, (sext i1 X) --> srem Op0, -1 --> 0
12890b57cec5SDimitry Andric   Value *X;
12900b57cec5SDimitry Andric   if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
12910b57cec5SDimitry Andric     return ConstantInt::getNullValue(Op0->getType());
12920b57cec5SDimitry Andric 
12930b57cec5SDimitry Andric   // If the two operands are negated, return 0.
12940b57cec5SDimitry Andric   if (isKnownNegation(Op0, Op1))
12950b57cec5SDimitry Andric     return ConstantInt::getNullValue(Op0->getType());
12960b57cec5SDimitry Andric 
12970b57cec5SDimitry Andric   return simplifyRem(Instruction::SRem, Op0, Op1, Q, MaxRecurse);
12980b57cec5SDimitry Andric }
12990b57cec5SDimitry Andric 
130081ad6265SDimitry Andric Value *llvm::simplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
130181ad6265SDimitry Andric   return ::simplifySRemInst(Op0, Op1, Q, RecursionLimit);
13020b57cec5SDimitry Andric }
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric /// Given operands for a URem, see if we can fold the result.
13050b57cec5SDimitry Andric /// If not, this returns null.
130681ad6265SDimitry Andric static Value *simplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
13070b57cec5SDimitry Andric                                unsigned MaxRecurse) {
13080b57cec5SDimitry Andric   return simplifyRem(Instruction::URem, Op0, Op1, Q, MaxRecurse);
13090b57cec5SDimitry Andric }
13100b57cec5SDimitry Andric 
131181ad6265SDimitry Andric Value *llvm::simplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
131281ad6265SDimitry Andric   return ::simplifyURemInst(Op0, Op1, Q, RecursionLimit);
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
1315e8d8bef9SDimitry Andric /// Returns true if a shift by \c Amount always yields poison.
1316e8d8bef9SDimitry Andric static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q) {
13170b57cec5SDimitry Andric   Constant *C = dyn_cast<Constant>(Amount);
13180b57cec5SDimitry Andric   if (!C)
13190b57cec5SDimitry Andric     return false;
13200b57cec5SDimitry Andric 
1321e8d8bef9SDimitry Andric   // X shift by undef -> poison because it may shift by the bitwidth.
1322e8d8bef9SDimitry Andric   if (Q.isUndefValue(C))
13230b57cec5SDimitry Andric     return true;
13240b57cec5SDimitry Andric 
1325bdd1243dSDimitry Andric   // Shifting by the bitwidth or more is poison. This covers scalars and
1326bdd1243dSDimitry Andric   // fixed/scalable vectors with splat constants.
1327bdd1243dSDimitry Andric   const APInt *AmountC;
1328bdd1243dSDimitry Andric   if (match(C, m_APInt(AmountC)) && AmountC->uge(AmountC->getBitWidth()))
13290b57cec5SDimitry Andric     return true;
13300b57cec5SDimitry Andric 
1331bdd1243dSDimitry Andric   // Try harder for fixed-length vectors:
1332bdd1243dSDimitry Andric   // If all lanes of a vector shift are poison, the whole shift is poison.
13330b57cec5SDimitry Andric   if (isa<ConstantVector>(C) || isa<ConstantDataVector>(C)) {
1334e8d8bef9SDimitry Andric     for (unsigned I = 0,
1335e8d8bef9SDimitry Andric                   E = cast<FixedVectorType>(C->getType())->getNumElements();
13365ffd83dbSDimitry Andric          I != E; ++I)
1337e8d8bef9SDimitry Andric       if (!isPoisonShift(C->getAggregateElement(I), Q))
13380b57cec5SDimitry Andric         return false;
13390b57cec5SDimitry Andric     return true;
13400b57cec5SDimitry Andric   }
13410b57cec5SDimitry Andric 
13420b57cec5SDimitry Andric   return false;
13430b57cec5SDimitry Andric }
13440b57cec5SDimitry Andric 
13450b57cec5SDimitry Andric /// Given operands for an Shl, LShr or AShr, see if we can fold the result.
13460b57cec5SDimitry Andric /// If not, this returns null.
134781ad6265SDimitry Andric static Value *simplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
1348fe6060f1SDimitry Andric                             Value *Op1, bool IsNSW, const SimplifyQuery &Q,
1349fe6060f1SDimitry Andric                             unsigned MaxRecurse) {
13500b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
13510b57cec5SDimitry Andric     return C;
13520b57cec5SDimitry Andric 
1353fe6060f1SDimitry Andric   // poison shift by X -> poison
1354fe6060f1SDimitry Andric   if (isa<PoisonValue>(Op0))
1355fe6060f1SDimitry Andric     return Op0;
1356fe6060f1SDimitry Andric 
13570b57cec5SDimitry Andric   // 0 shift by X -> 0
13580b57cec5SDimitry Andric   if (match(Op0, m_Zero()))
13590b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
13600b57cec5SDimitry Andric 
13610b57cec5SDimitry Andric   // X shift by 0 -> X
13620b57cec5SDimitry Andric   // Shift-by-sign-extended bool must be shift-by-0 because shift-by-all-ones
13630b57cec5SDimitry Andric   // would be poison.
13640b57cec5SDimitry Andric   Value *X;
13650b57cec5SDimitry Andric   if (match(Op1, m_Zero()) ||
13660b57cec5SDimitry Andric       (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)))
13670b57cec5SDimitry Andric     return Op0;
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric   // Fold undefined shifts.
1370e8d8bef9SDimitry Andric   if (isPoisonShift(Op1, Q))
1371e8d8bef9SDimitry Andric     return PoisonValue::get(Op0->getType());
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   // If the operation is with the result of a select instruction, check whether
13740b57cec5SDimitry Andric   // operating on either branch of the select always yields the same value.
13750b57cec5SDimitry Andric   if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
137681ad6265SDimitry Andric     if (Value *V = threadBinOpOverSelect(Opcode, Op0, Op1, Q, MaxRecurse))
13770b57cec5SDimitry Andric       return V;
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric   // If the operation is with the result of a phi instruction, check whether
13800b57cec5SDimitry Andric   // operating on all incoming values of the phi always yields the same value.
13810b57cec5SDimitry Andric   if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
138281ad6265SDimitry Andric     if (Value *V = threadBinOpOverPHI(Opcode, Op0, Op1, Q, MaxRecurse))
13830b57cec5SDimitry Andric       return V;
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric   // If any bits in the shift amount make that value greater than or equal to
13860b57cec5SDimitry Andric   // the number of bits in the type, the shift is undefined.
13875f757f3fSDimitry Andric   KnownBits KnownAmt = computeKnownBits(Op1, /* Depth */ 0, Q);
1388fe6060f1SDimitry Andric   if (KnownAmt.getMinValue().uge(KnownAmt.getBitWidth()))
1389e8d8bef9SDimitry Andric     return PoisonValue::get(Op0->getType());
13900b57cec5SDimitry Andric 
13910b57cec5SDimitry Andric   // If all valid bits in the shift amount are known zero, the first operand is
13920b57cec5SDimitry Andric   // unchanged.
1393fe6060f1SDimitry Andric   unsigned NumValidShiftBits = Log2_32_Ceil(KnownAmt.getBitWidth());
1394fe6060f1SDimitry Andric   if (KnownAmt.countMinTrailingZeros() >= NumValidShiftBits)
13950b57cec5SDimitry Andric     return Op0;
13960b57cec5SDimitry Andric 
1397fe6060f1SDimitry Andric   // Check for nsw shl leading to a poison value.
1398fe6060f1SDimitry Andric   if (IsNSW) {
1399fe6060f1SDimitry Andric     assert(Opcode == Instruction::Shl && "Expected shl for nsw instruction");
14005f757f3fSDimitry Andric     KnownBits KnownVal = computeKnownBits(Op0, /* Depth */ 0, Q);
1401fe6060f1SDimitry Andric     KnownBits KnownShl = KnownBits::shl(KnownVal, KnownAmt);
1402fe6060f1SDimitry Andric 
1403fe6060f1SDimitry Andric     if (KnownVal.Zero.isSignBitSet())
1404fe6060f1SDimitry Andric       KnownShl.Zero.setSignBit();
1405fe6060f1SDimitry Andric     if (KnownVal.One.isSignBitSet())
1406fe6060f1SDimitry Andric       KnownShl.One.setSignBit();
1407fe6060f1SDimitry Andric 
1408fe6060f1SDimitry Andric     if (KnownShl.hasConflict())
1409fe6060f1SDimitry Andric       return PoisonValue::get(Op0->getType());
1410fe6060f1SDimitry Andric   }
1411fe6060f1SDimitry Andric 
14120b57cec5SDimitry Andric   return nullptr;
14130b57cec5SDimitry Andric }
14140b57cec5SDimitry Andric 
141506c3fb27SDimitry Andric /// Given operands for an LShr or AShr, see if we can fold the result.  If not,
141606c3fb27SDimitry Andric /// this returns null.
141781ad6265SDimitry Andric static Value *simplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0,
1418bdd1243dSDimitry Andric                                  Value *Op1, bool IsExact,
141981ad6265SDimitry Andric                                  const SimplifyQuery &Q, unsigned MaxRecurse) {
1420fe6060f1SDimitry Andric   if (Value *V =
142181ad6265SDimitry Andric           simplifyShift(Opcode, Op0, Op1, /*IsNSW*/ false, Q, MaxRecurse))
14220b57cec5SDimitry Andric     return V;
14230b57cec5SDimitry Andric 
14240b57cec5SDimitry Andric   // X >> X -> 0
14250b57cec5SDimitry Andric   if (Op0 == Op1)
14260b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric   // undef >> X -> 0
14290b57cec5SDimitry Andric   // undef >> X -> undef (if it's exact)
1430e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op0))
1431bdd1243dSDimitry Andric     return IsExact ? Op0 : Constant::getNullValue(Op0->getType());
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric   // The low bit cannot be shifted out of an exact shift if it is set.
1434bdd1243dSDimitry Andric   // TODO: Generalize by counting trailing zeros (see fold for exact division).
1435bdd1243dSDimitry Andric   if (IsExact) {
14365f757f3fSDimitry Andric     KnownBits Op0Known = computeKnownBits(Op0, /* Depth */ 0, Q);
14370b57cec5SDimitry Andric     if (Op0Known.One[0])
14380b57cec5SDimitry Andric       return Op0;
14390b57cec5SDimitry Andric   }
14400b57cec5SDimitry Andric 
14410b57cec5SDimitry Andric   return nullptr;
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric /// Given operands for an Shl, see if we can fold the result.
14450b57cec5SDimitry Andric /// If not, this returns null.
1446bdd1243dSDimitry Andric static Value *simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
14470b57cec5SDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse) {
1448fe6060f1SDimitry Andric   if (Value *V =
1449bdd1243dSDimitry Andric           simplifyShift(Instruction::Shl, Op0, Op1, IsNSW, Q, MaxRecurse))
14500b57cec5SDimitry Andric     return V;
14510b57cec5SDimitry Andric 
145206c3fb27SDimitry Andric   Type *Ty = Op0->getType();
14530b57cec5SDimitry Andric   // undef << X -> 0
14540b57cec5SDimitry Andric   // undef << X -> undef if (if it's NSW/NUW)
1455e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op0))
145606c3fb27SDimitry Andric     return IsNSW || IsNUW ? Op0 : Constant::getNullValue(Ty);
14570b57cec5SDimitry Andric 
14580b57cec5SDimitry Andric   // (X >> A) << A -> X
14590b57cec5SDimitry Andric   Value *X;
14600b57cec5SDimitry Andric   if (Q.IIQ.UseInstrInfo &&
14610b57cec5SDimitry Andric       match(Op0, m_Exact(m_Shr(m_Value(X), m_Specific(Op1)))))
14620b57cec5SDimitry Andric     return X;
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric   // shl nuw i8 C, %x  ->  C  iff C has sign bit set.
1465bdd1243dSDimitry Andric   if (IsNUW && match(Op0, m_Negative()))
14660b57cec5SDimitry Andric     return Op0;
14670b57cec5SDimitry Andric   // NOTE: could use computeKnownBits() / LazyValueInfo,
14680b57cec5SDimitry Andric   // but the cost-benefit analysis suggests it isn't worth it.
14690b57cec5SDimitry Andric 
147006c3fb27SDimitry Andric   // "nuw" guarantees that only zeros are shifted out, and "nsw" guarantees
147106c3fb27SDimitry Andric   // that the sign-bit does not change, so the only input that does not
147206c3fb27SDimitry Andric   // produce poison is 0, and "0 << (bitwidth-1) --> 0".
147306c3fb27SDimitry Andric   if (IsNSW && IsNUW &&
147406c3fb27SDimitry Andric       match(Op1, m_SpecificInt(Ty->getScalarSizeInBits() - 1)))
147506c3fb27SDimitry Andric     return Constant::getNullValue(Ty);
147606c3fb27SDimitry Andric 
14770b57cec5SDimitry Andric   return nullptr;
14780b57cec5SDimitry Andric }
14790b57cec5SDimitry Andric 
1480bdd1243dSDimitry Andric Value *llvm::simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
14810b57cec5SDimitry Andric                              const SimplifyQuery &Q) {
1482bdd1243dSDimitry Andric   return ::simplifyShlInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric /// Given operands for an LShr, see if we can fold the result.
14860b57cec5SDimitry Andric /// If not, this returns null.
1487bdd1243dSDimitry Andric static Value *simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact,
14880b57cec5SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
1489bdd1243dSDimitry Andric   if (Value *V = simplifyRightShift(Instruction::LShr, Op0, Op1, IsExact, Q,
14900b57cec5SDimitry Andric                                     MaxRecurse))
14910b57cec5SDimitry Andric     return V;
14920b57cec5SDimitry Andric 
14930b57cec5SDimitry Andric   // (X << A) >> A -> X
14940b57cec5SDimitry Andric   Value *X;
14955f757f3fSDimitry Andric   if (Q.IIQ.UseInstrInfo && match(Op0, m_NUWShl(m_Value(X), m_Specific(Op1))))
14960b57cec5SDimitry Andric     return X;
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric   // ((X << A) | Y) >> A -> X  if effective width of Y is not larger than A.
14990b57cec5SDimitry Andric   // We can return X as we do in the above case since OR alters no bits in X.
15000b57cec5SDimitry Andric   // SimplifyDemandedBits in InstCombine can do more general optimization for
15010b57cec5SDimitry Andric   // bit manipulation. This pattern aims to provide opportunities for other
15020b57cec5SDimitry Andric   // optimizers by supporting a simple but common case in InstSimplify.
15030b57cec5SDimitry Andric   Value *Y;
15040b57cec5SDimitry Andric   const APInt *ShRAmt, *ShLAmt;
15055f757f3fSDimitry Andric   if (Q.IIQ.UseInstrInfo && match(Op1, m_APInt(ShRAmt)) &&
15060b57cec5SDimitry Andric       match(Op0, m_c_Or(m_NUWShl(m_Value(X), m_APInt(ShLAmt)), m_Value(Y))) &&
15070b57cec5SDimitry Andric       *ShRAmt == *ShLAmt) {
15085f757f3fSDimitry Andric     const KnownBits YKnown = computeKnownBits(Y, /* Depth */ 0, Q);
1509349cc55cSDimitry Andric     const unsigned EffWidthY = YKnown.countMaxActiveBits();
15100b57cec5SDimitry Andric     if (ShRAmt->uge(EffWidthY))
15110b57cec5SDimitry Andric       return X;
15120b57cec5SDimitry Andric   }
15130b57cec5SDimitry Andric 
15140b57cec5SDimitry Andric   return nullptr;
15150b57cec5SDimitry Andric }
15160b57cec5SDimitry Andric 
1517bdd1243dSDimitry Andric Value *llvm::simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact,
15180b57cec5SDimitry Andric                               const SimplifyQuery &Q) {
1519bdd1243dSDimitry Andric   return ::simplifyLShrInst(Op0, Op1, IsExact, Q, RecursionLimit);
15200b57cec5SDimitry Andric }
15210b57cec5SDimitry Andric 
15220b57cec5SDimitry Andric /// Given operands for an AShr, see if we can fold the result.
15230b57cec5SDimitry Andric /// If not, this returns null.
1524bdd1243dSDimitry Andric static Value *simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact,
15250b57cec5SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
1526bdd1243dSDimitry Andric   if (Value *V = simplifyRightShift(Instruction::AShr, Op0, Op1, IsExact, Q,
15270b57cec5SDimitry Andric                                     MaxRecurse))
15280b57cec5SDimitry Andric     return V;
15290b57cec5SDimitry Andric 
1530349cc55cSDimitry Andric   // -1 >>a X --> -1
1531349cc55cSDimitry Andric   // (-1 << X) a>> X --> -1
1532*0fca6ea1SDimitry Andric   // We could return the original -1 constant to preserve poison elements.
1533349cc55cSDimitry Andric   if (match(Op0, m_AllOnes()) ||
1534349cc55cSDimitry Andric       match(Op0, m_Shl(m_AllOnes(), m_Specific(Op1))))
15350b57cec5SDimitry Andric     return Constant::getAllOnesValue(Op0->getType());
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric   // (X << A) >> A -> X
15380b57cec5SDimitry Andric   Value *X;
15390b57cec5SDimitry Andric   if (Q.IIQ.UseInstrInfo && match(Op0, m_NSWShl(m_Value(X), m_Specific(Op1))))
15400b57cec5SDimitry Andric     return X;
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric   // Arithmetic shifting an all-sign-bit value is a no-op.
15430b57cec5SDimitry Andric   unsigned NumSignBits = ComputeNumSignBits(Op0, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
15440b57cec5SDimitry Andric   if (NumSignBits == Op0->getType()->getScalarSizeInBits())
15450b57cec5SDimitry Andric     return Op0;
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric   return nullptr;
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric 
1550bdd1243dSDimitry Andric Value *llvm::simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact,
15510b57cec5SDimitry Andric                               const SimplifyQuery &Q) {
1552bdd1243dSDimitry Andric   return ::simplifyAShrInst(Op0, Op1, IsExact, Q, RecursionLimit);
15530b57cec5SDimitry Andric }
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric /// Commuted variants are assumed to be handled by calling this function again
15560b57cec5SDimitry Andric /// with the parameters swapped.
15570b57cec5SDimitry Andric static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
15588bcb0991SDimitry Andric                                          ICmpInst *UnsignedICmp, bool IsAnd,
15598bcb0991SDimitry Andric                                          const SimplifyQuery &Q) {
15600b57cec5SDimitry Andric   Value *X, *Y;
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric   ICmpInst::Predicate EqPred;
15630b57cec5SDimitry Andric   if (!match(ZeroICmp, m_ICmp(EqPred, m_Value(Y), m_Zero())) ||
15640b57cec5SDimitry Andric       !ICmpInst::isEquality(EqPred))
15650b57cec5SDimitry Andric     return nullptr;
15660b57cec5SDimitry Andric 
15670b57cec5SDimitry Andric   ICmpInst::Predicate UnsignedPred;
15688bcb0991SDimitry Andric 
15698bcb0991SDimitry Andric   Value *A, *B;
15708bcb0991SDimitry Andric   // Y = (A - B);
15718bcb0991SDimitry Andric   if (match(Y, m_Sub(m_Value(A), m_Value(B)))) {
15728bcb0991SDimitry Andric     if (match(UnsignedICmp,
15738bcb0991SDimitry Andric               m_c_ICmp(UnsignedPred, m_Specific(A), m_Specific(B))) &&
15748bcb0991SDimitry Andric         ICmpInst::isUnsigned(UnsignedPred)) {
15758bcb0991SDimitry Andric       // A >=/<= B || (A - B) != 0  <-->  true
15768bcb0991SDimitry Andric       if ((UnsignedPred == ICmpInst::ICMP_UGE ||
15778bcb0991SDimitry Andric            UnsignedPred == ICmpInst::ICMP_ULE) &&
15788bcb0991SDimitry Andric           EqPred == ICmpInst::ICMP_NE && !IsAnd)
15798bcb0991SDimitry Andric         return ConstantInt::getTrue(UnsignedICmp->getType());
15808bcb0991SDimitry Andric       // A </> B && (A - B) == 0  <-->  false
15818bcb0991SDimitry Andric       if ((UnsignedPred == ICmpInst::ICMP_ULT ||
15828bcb0991SDimitry Andric            UnsignedPred == ICmpInst::ICMP_UGT) &&
15838bcb0991SDimitry Andric           EqPred == ICmpInst::ICMP_EQ && IsAnd)
15848bcb0991SDimitry Andric         return ConstantInt::getFalse(UnsignedICmp->getType());
15858bcb0991SDimitry Andric 
15868bcb0991SDimitry Andric       // A </> B && (A - B) != 0  <-->  A </> B
15878bcb0991SDimitry Andric       // A </> B || (A - B) != 0  <-->  (A - B) != 0
15888bcb0991SDimitry Andric       if (EqPred == ICmpInst::ICMP_NE && (UnsignedPred == ICmpInst::ICMP_ULT ||
15898bcb0991SDimitry Andric                                           UnsignedPred == ICmpInst::ICMP_UGT))
15908bcb0991SDimitry Andric         return IsAnd ? UnsignedICmp : ZeroICmp;
15918bcb0991SDimitry Andric 
15928bcb0991SDimitry Andric       // A <=/>= B && (A - B) == 0  <-->  (A - B) == 0
15938bcb0991SDimitry Andric       // A <=/>= B || (A - B) == 0  <-->  A <=/>= B
15948bcb0991SDimitry Andric       if (EqPred == ICmpInst::ICMP_EQ && (UnsignedPred == ICmpInst::ICMP_ULE ||
15958bcb0991SDimitry Andric                                           UnsignedPred == ICmpInst::ICMP_UGE))
15968bcb0991SDimitry Andric         return IsAnd ? ZeroICmp : UnsignedICmp;
15978bcb0991SDimitry Andric     }
15988bcb0991SDimitry Andric 
15998bcb0991SDimitry Andric     // Given  Y = (A - B)
16008bcb0991SDimitry Andric     //   Y >= A && Y != 0  --> Y >= A  iff B != 0
16018bcb0991SDimitry Andric     //   Y <  A || Y == 0  --> Y <  A  iff B != 0
16028bcb0991SDimitry Andric     if (match(UnsignedICmp,
16038bcb0991SDimitry Andric               m_c_ICmp(UnsignedPred, m_Specific(Y), m_Specific(A)))) {
16048bcb0991SDimitry Andric       if (UnsignedPred == ICmpInst::ICMP_UGE && IsAnd &&
1605*0fca6ea1SDimitry Andric           EqPred == ICmpInst::ICMP_NE && isKnownNonZero(B, Q))
16068bcb0991SDimitry Andric         return UnsignedICmp;
16078bcb0991SDimitry Andric       if (UnsignedPred == ICmpInst::ICMP_ULT && !IsAnd &&
1608*0fca6ea1SDimitry Andric           EqPred == ICmpInst::ICMP_EQ && isKnownNonZero(B, Q))
16098bcb0991SDimitry Andric         return UnsignedICmp;
16108bcb0991SDimitry Andric     }
16118bcb0991SDimitry Andric   }
16128bcb0991SDimitry Andric 
16130b57cec5SDimitry Andric   if (match(UnsignedICmp, m_ICmp(UnsignedPred, m_Value(X), m_Specific(Y))) &&
16140b57cec5SDimitry Andric       ICmpInst::isUnsigned(UnsignedPred))
16150b57cec5SDimitry Andric     ;
16160b57cec5SDimitry Andric   else if (match(UnsignedICmp,
16170b57cec5SDimitry Andric                  m_ICmp(UnsignedPred, m_Specific(Y), m_Value(X))) &&
16180b57cec5SDimitry Andric            ICmpInst::isUnsigned(UnsignedPred))
16190b57cec5SDimitry Andric     UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
16200b57cec5SDimitry Andric   else
16210b57cec5SDimitry Andric     return nullptr;
16220b57cec5SDimitry Andric 
16235ffd83dbSDimitry Andric   // X > Y && Y == 0  -->  Y == 0  iff X != 0
16245ffd83dbSDimitry Andric   // X > Y || Y == 0  -->  X > Y   iff X != 0
16255ffd83dbSDimitry Andric   if (UnsignedPred == ICmpInst::ICMP_UGT && EqPred == ICmpInst::ICMP_EQ &&
1626*0fca6ea1SDimitry Andric       isKnownNonZero(X, Q))
16275ffd83dbSDimitry Andric     return IsAnd ? ZeroICmp : UnsignedICmp;
16280b57cec5SDimitry Andric 
16298bcb0991SDimitry Andric   // X <= Y && Y != 0  -->  X <= Y  iff X != 0
16308bcb0991SDimitry Andric   // X <= Y || Y != 0  -->  Y != 0  iff X != 0
16318bcb0991SDimitry Andric   if (UnsignedPred == ICmpInst::ICMP_ULE && EqPred == ICmpInst::ICMP_NE &&
1632*0fca6ea1SDimitry Andric       isKnownNonZero(X, Q))
16338bcb0991SDimitry Andric     return IsAnd ? UnsignedICmp : ZeroICmp;
16348bcb0991SDimitry Andric 
16355ffd83dbSDimitry Andric   // The transforms below here are expected to be handled more generally with
16365ffd83dbSDimitry Andric   // simplifyAndOrOfICmpsWithLimitConst() or in InstCombine's
16375ffd83dbSDimitry Andric   // foldAndOrOfICmpsWithConstEq(). If we are looking to trim optimizer overlap,
16385ffd83dbSDimitry Andric   // these are candidates for removal.
16395ffd83dbSDimitry Andric 
16405ffd83dbSDimitry Andric   // X < Y && Y != 0  -->  X < Y
16415ffd83dbSDimitry Andric   // X < Y || Y != 0  -->  Y != 0
16425ffd83dbSDimitry Andric   if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_NE)
16435ffd83dbSDimitry Andric     return IsAnd ? UnsignedICmp : ZeroICmp;
16445ffd83dbSDimitry Andric 
16458bcb0991SDimitry Andric   // X >= Y && Y == 0  -->  Y == 0
16460b57cec5SDimitry Andric   // X >= Y || Y == 0  -->  X >= Y
16478bcb0991SDimitry Andric   if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_EQ)
16488bcb0991SDimitry Andric     return IsAnd ? ZeroICmp : UnsignedICmp;
16498bcb0991SDimitry Andric 
16500b57cec5SDimitry Andric   // X < Y && Y == 0  -->  false
16510b57cec5SDimitry Andric   if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_EQ &&
16520b57cec5SDimitry Andric       IsAnd)
16530b57cec5SDimitry Andric     return getFalse(UnsignedICmp->getType());
16540b57cec5SDimitry Andric 
16558bcb0991SDimitry Andric   // X >= Y || Y != 0  -->  true
16568bcb0991SDimitry Andric   if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_NE &&
16578bcb0991SDimitry Andric       !IsAnd)
16588bcb0991SDimitry Andric     return getTrue(UnsignedICmp->getType());
16598bcb0991SDimitry Andric 
16600b57cec5SDimitry Andric   return nullptr;
16610b57cec5SDimitry Andric }
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric /// Test if a pair of compares with a shared operand and 2 constants has an
16640b57cec5SDimitry Andric /// empty set intersection, full set union, or if one compare is a superset of
16650b57cec5SDimitry Andric /// the other.
16660b57cec5SDimitry Andric static Value *simplifyAndOrOfICmpsWithConstants(ICmpInst *Cmp0, ICmpInst *Cmp1,
16670b57cec5SDimitry Andric                                                 bool IsAnd) {
16680b57cec5SDimitry Andric   // Look for this pattern: {and/or} (icmp X, C0), (icmp X, C1)).
16690b57cec5SDimitry Andric   if (Cmp0->getOperand(0) != Cmp1->getOperand(0))
16700b57cec5SDimitry Andric     return nullptr;
16710b57cec5SDimitry Andric 
16720b57cec5SDimitry Andric   const APInt *C0, *C1;
16730b57cec5SDimitry Andric   if (!match(Cmp0->getOperand(1), m_APInt(C0)) ||
16740b57cec5SDimitry Andric       !match(Cmp1->getOperand(1), m_APInt(C1)))
16750b57cec5SDimitry Andric     return nullptr;
16760b57cec5SDimitry Andric 
16770b57cec5SDimitry Andric   auto Range0 = ConstantRange::makeExactICmpRegion(Cmp0->getPredicate(), *C0);
16780b57cec5SDimitry Andric   auto Range1 = ConstantRange::makeExactICmpRegion(Cmp1->getPredicate(), *C1);
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric   // For and-of-compares, check if the intersection is empty:
16810b57cec5SDimitry Andric   // (icmp X, C0) && (icmp X, C1) --> empty set --> false
16820b57cec5SDimitry Andric   if (IsAnd && Range0.intersectWith(Range1).isEmptySet())
16830b57cec5SDimitry Andric     return getFalse(Cmp0->getType());
16840b57cec5SDimitry Andric 
16850b57cec5SDimitry Andric   // For or-of-compares, check if the union is full:
16860b57cec5SDimitry Andric   // (icmp X, C0) || (icmp X, C1) --> full set --> true
16870b57cec5SDimitry Andric   if (!IsAnd && Range0.unionWith(Range1).isFullSet())
16880b57cec5SDimitry Andric     return getTrue(Cmp0->getType());
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric   // Is one range a superset of the other?
16910b57cec5SDimitry Andric   // If this is and-of-compares, take the smaller set:
16920b57cec5SDimitry Andric   // (icmp sgt X, 4) && (icmp sgt X, 42) --> icmp sgt X, 42
16930b57cec5SDimitry Andric   // If this is or-of-compares, take the larger set:
16940b57cec5SDimitry Andric   // (icmp sgt X, 4) || (icmp sgt X, 42) --> icmp sgt X, 4
16950b57cec5SDimitry Andric   if (Range0.contains(Range1))
16960b57cec5SDimitry Andric     return IsAnd ? Cmp1 : Cmp0;
16970b57cec5SDimitry Andric   if (Range1.contains(Range0))
16980b57cec5SDimitry Andric     return IsAnd ? Cmp0 : Cmp1;
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric   return nullptr;
17010b57cec5SDimitry Andric }
17020b57cec5SDimitry Andric 
17030b57cec5SDimitry Andric static Value *simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1,
17040b57cec5SDimitry Andric                                         const InstrInfoQuery &IIQ) {
17050b57cec5SDimitry Andric   // (icmp (add V, C0), C1) & (icmp V, C0)
17060b57cec5SDimitry Andric   ICmpInst::Predicate Pred0, Pred1;
17070b57cec5SDimitry Andric   const APInt *C0, *C1;
17080b57cec5SDimitry Andric   Value *V;
17090b57cec5SDimitry Andric   if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_APInt(C0)), m_APInt(C1))))
17100b57cec5SDimitry Andric     return nullptr;
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric   if (!match(Op1, m_ICmp(Pred1, m_Specific(V), m_Value())))
17130b57cec5SDimitry Andric     return nullptr;
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric   auto *AddInst = cast<OverflowingBinaryOperator>(Op0->getOperand(0));
17160b57cec5SDimitry Andric   if (AddInst->getOperand(1) != Op1->getOperand(1))
17170b57cec5SDimitry Andric     return nullptr;
17180b57cec5SDimitry Andric 
17190b57cec5SDimitry Andric   Type *ITy = Op0->getType();
1720bdd1243dSDimitry Andric   bool IsNSW = IIQ.hasNoSignedWrap(AddInst);
1721bdd1243dSDimitry Andric   bool IsNUW = IIQ.hasNoUnsignedWrap(AddInst);
17220b57cec5SDimitry Andric 
17230b57cec5SDimitry Andric   const APInt Delta = *C1 - *C0;
17240b57cec5SDimitry Andric   if (C0->isStrictlyPositive()) {
17250b57cec5SDimitry Andric     if (Delta == 2) {
17260b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_SGT)
17270b57cec5SDimitry Andric         return getFalse(ITy);
1728bdd1243dSDimitry Andric       if (Pred0 == ICmpInst::ICMP_SLT && Pred1 == ICmpInst::ICMP_SGT && IsNSW)
17290b57cec5SDimitry Andric         return getFalse(ITy);
17300b57cec5SDimitry Andric     }
17310b57cec5SDimitry Andric     if (Delta == 1) {
17320b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_SGT)
17330b57cec5SDimitry Andric         return getFalse(ITy);
1734bdd1243dSDimitry Andric       if (Pred0 == ICmpInst::ICMP_SLE && Pred1 == ICmpInst::ICMP_SGT && IsNSW)
17350b57cec5SDimitry Andric         return getFalse(ITy);
17360b57cec5SDimitry Andric     }
17370b57cec5SDimitry Andric   }
1738bdd1243dSDimitry Andric   if (C0->getBoolValue() && IsNUW) {
17390b57cec5SDimitry Andric     if (Delta == 2)
17400b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_UGT)
17410b57cec5SDimitry Andric         return getFalse(ITy);
17420b57cec5SDimitry Andric     if (Delta == 1)
17430b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_UGT)
17440b57cec5SDimitry Andric         return getFalse(ITy);
17450b57cec5SDimitry Andric   }
17460b57cec5SDimitry Andric 
17470b57cec5SDimitry Andric   return nullptr;
17480b57cec5SDimitry Andric }
17490b57cec5SDimitry Andric 
175081ad6265SDimitry Andric /// Try to simplify and/or of icmp with ctpop intrinsic.
175181ad6265SDimitry Andric static Value *simplifyAndOrOfICmpsWithCtpop(ICmpInst *Cmp0, ICmpInst *Cmp1,
175281ad6265SDimitry Andric                                             bool IsAnd) {
175381ad6265SDimitry Andric   ICmpInst::Predicate Pred0, Pred1;
175481ad6265SDimitry Andric   Value *X;
175581ad6265SDimitry Andric   const APInt *C;
175681ad6265SDimitry Andric   if (!match(Cmp0, m_ICmp(Pred0, m_Intrinsic<Intrinsic::ctpop>(m_Value(X)),
175781ad6265SDimitry Andric                           m_APInt(C))) ||
175881ad6265SDimitry Andric       !match(Cmp1, m_ICmp(Pred1, m_Specific(X), m_ZeroInt())) || C->isZero())
175981ad6265SDimitry Andric     return nullptr;
176081ad6265SDimitry Andric 
176181ad6265SDimitry Andric   // (ctpop(X) == C) || (X != 0) --> X != 0 where C > 0
176281ad6265SDimitry Andric   if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_NE)
176381ad6265SDimitry Andric     return Cmp1;
176481ad6265SDimitry Andric   // (ctpop(X) != C) && (X == 0) --> X == 0 where C > 0
176581ad6265SDimitry Andric   if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_EQ)
176681ad6265SDimitry Andric     return Cmp1;
176781ad6265SDimitry Andric 
176881ad6265SDimitry Andric   return nullptr;
176981ad6265SDimitry Andric }
177081ad6265SDimitry Andric 
17710b57cec5SDimitry Andric static Value *simplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1,
17728bcb0991SDimitry Andric                                  const SimplifyQuery &Q) {
17738bcb0991SDimitry Andric   if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/true, Q))
17740b57cec5SDimitry Andric     return X;
17758bcb0991SDimitry Andric   if (Value *X = simplifyUnsignedRangeCheck(Op1, Op0, /*IsAnd=*/true, Q))
17760b57cec5SDimitry Andric     return X;
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric   if (Value *X = simplifyAndOrOfICmpsWithConstants(Op0, Op1, true))
17790b57cec5SDimitry Andric     return X;
17800b57cec5SDimitry Andric 
178181ad6265SDimitry Andric   if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op0, Op1, true))
178281ad6265SDimitry Andric     return X;
178381ad6265SDimitry Andric   if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op1, Op0, true))
178481ad6265SDimitry Andric     return X;
178581ad6265SDimitry Andric 
17868bcb0991SDimitry Andric   if (Value *X = simplifyAndOfICmpsWithAdd(Op0, Op1, Q.IIQ))
17870b57cec5SDimitry Andric     return X;
17888bcb0991SDimitry Andric   if (Value *X = simplifyAndOfICmpsWithAdd(Op1, Op0, Q.IIQ))
17890b57cec5SDimitry Andric     return X;
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric   return nullptr;
17920b57cec5SDimitry Andric }
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric static Value *simplifyOrOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1,
17950b57cec5SDimitry Andric                                        const InstrInfoQuery &IIQ) {
17960b57cec5SDimitry Andric   // (icmp (add V, C0), C1) | (icmp V, C0)
17970b57cec5SDimitry Andric   ICmpInst::Predicate Pred0, Pred1;
17980b57cec5SDimitry Andric   const APInt *C0, *C1;
17990b57cec5SDimitry Andric   Value *V;
18000b57cec5SDimitry Andric   if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_APInt(C0)), m_APInt(C1))))
18010b57cec5SDimitry Andric     return nullptr;
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric   if (!match(Op1, m_ICmp(Pred1, m_Specific(V), m_Value())))
18040b57cec5SDimitry Andric     return nullptr;
18050b57cec5SDimitry Andric 
18060b57cec5SDimitry Andric   auto *AddInst = cast<BinaryOperator>(Op0->getOperand(0));
18070b57cec5SDimitry Andric   if (AddInst->getOperand(1) != Op1->getOperand(1))
18080b57cec5SDimitry Andric     return nullptr;
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric   Type *ITy = Op0->getType();
1811bdd1243dSDimitry Andric   bool IsNSW = IIQ.hasNoSignedWrap(AddInst);
1812bdd1243dSDimitry Andric   bool IsNUW = IIQ.hasNoUnsignedWrap(AddInst);
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric   const APInt Delta = *C1 - *C0;
18150b57cec5SDimitry Andric   if (C0->isStrictlyPositive()) {
18160b57cec5SDimitry Andric     if (Delta == 2) {
18170b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_SLE)
18180b57cec5SDimitry Andric         return getTrue(ITy);
1819bdd1243dSDimitry Andric       if (Pred0 == ICmpInst::ICMP_SGE && Pred1 == ICmpInst::ICMP_SLE && IsNSW)
18200b57cec5SDimitry Andric         return getTrue(ITy);
18210b57cec5SDimitry Andric     }
18220b57cec5SDimitry Andric     if (Delta == 1) {
18230b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_SLE)
18240b57cec5SDimitry Andric         return getTrue(ITy);
1825bdd1243dSDimitry Andric       if (Pred0 == ICmpInst::ICMP_SGT && Pred1 == ICmpInst::ICMP_SLE && IsNSW)
18260b57cec5SDimitry Andric         return getTrue(ITy);
18270b57cec5SDimitry Andric     }
18280b57cec5SDimitry Andric   }
1829bdd1243dSDimitry Andric   if (C0->getBoolValue() && IsNUW) {
18300b57cec5SDimitry Andric     if (Delta == 2)
18310b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_ULE)
18320b57cec5SDimitry Andric         return getTrue(ITy);
18330b57cec5SDimitry Andric     if (Delta == 1)
18340b57cec5SDimitry Andric       if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_ULE)
18350b57cec5SDimitry Andric         return getTrue(ITy);
18360b57cec5SDimitry Andric   }
18370b57cec5SDimitry Andric 
18380b57cec5SDimitry Andric   return nullptr;
18390b57cec5SDimitry Andric }
18400b57cec5SDimitry Andric 
18410b57cec5SDimitry Andric static Value *simplifyOrOfICmps(ICmpInst *Op0, ICmpInst *Op1,
18428bcb0991SDimitry Andric                                 const SimplifyQuery &Q) {
18438bcb0991SDimitry Andric   if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/false, Q))
18440b57cec5SDimitry Andric     return X;
18458bcb0991SDimitry Andric   if (Value *X = simplifyUnsignedRangeCheck(Op1, Op0, /*IsAnd=*/false, Q))
18460b57cec5SDimitry Andric     return X;
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric   if (Value *X = simplifyAndOrOfICmpsWithConstants(Op0, Op1, false))
18490b57cec5SDimitry Andric     return X;
18500b57cec5SDimitry Andric 
185181ad6265SDimitry Andric   if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op0, Op1, false))
185281ad6265SDimitry Andric     return X;
185381ad6265SDimitry Andric   if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op1, Op0, false))
185481ad6265SDimitry Andric     return X;
185581ad6265SDimitry Andric 
18568bcb0991SDimitry Andric   if (Value *X = simplifyOrOfICmpsWithAdd(Op0, Op1, Q.IIQ))
18570b57cec5SDimitry Andric     return X;
18588bcb0991SDimitry Andric   if (Value *X = simplifyOrOfICmpsWithAdd(Op1, Op0, Q.IIQ))
18590b57cec5SDimitry Andric     return X;
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric   return nullptr;
18620b57cec5SDimitry Andric }
18630b57cec5SDimitry Andric 
186406c3fb27SDimitry Andric static Value *simplifyAndOrOfFCmps(const SimplifyQuery &Q, FCmpInst *LHS,
186581ad6265SDimitry Andric                                    FCmpInst *RHS, bool IsAnd) {
18660b57cec5SDimitry Andric   Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
18670b57cec5SDimitry Andric   Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
18680b57cec5SDimitry Andric   if (LHS0->getType() != RHS0->getType())
18690b57cec5SDimitry Andric     return nullptr;
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric   FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
1872*0fca6ea1SDimitry Andric   if ((PredL == FCmpInst::FCMP_ORD || PredL == FCmpInst::FCMP_UNO) &&
1873*0fca6ea1SDimitry Andric       ((FCmpInst::isOrdered(PredR) && IsAnd) ||
1874*0fca6ea1SDimitry Andric        (FCmpInst::isUnordered(PredR) && !IsAnd))) {
1875*0fca6ea1SDimitry Andric     // (fcmp ord X, 0) & (fcmp o** X, Y) --> fcmp o** X, Y
1876*0fca6ea1SDimitry Andric     // (fcmp uno X, 0) & (fcmp o** X, Y) --> false
1877*0fca6ea1SDimitry Andric     // (fcmp uno X, 0) | (fcmp u** X, Y) --> fcmp u** X, Y
1878*0fca6ea1SDimitry Andric     // (fcmp ord X, 0) | (fcmp u** X, Y) --> true
1879*0fca6ea1SDimitry Andric     if ((LHS0 == RHS0 || LHS0 == RHS1) && match(LHS1, m_PosZeroFP()))
1880*0fca6ea1SDimitry Andric       return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
1881*0fca6ea1SDimitry Andric                  ? static_cast<Value *>(RHS)
1882*0fca6ea1SDimitry Andric                  : ConstantInt::getBool(LHS->getType(), !IsAnd);
1883*0fca6ea1SDimitry Andric   }
18840b57cec5SDimitry Andric 
1885*0fca6ea1SDimitry Andric   if ((PredR == FCmpInst::FCMP_ORD || PredR == FCmpInst::FCMP_UNO) &&
1886*0fca6ea1SDimitry Andric       ((FCmpInst::isOrdered(PredL) && IsAnd) ||
1887*0fca6ea1SDimitry Andric        (FCmpInst::isUnordered(PredL) && !IsAnd))) {
1888*0fca6ea1SDimitry Andric     // (fcmp o** X, Y) & (fcmp ord X, 0) --> fcmp o** X, Y
1889*0fca6ea1SDimitry Andric     // (fcmp o** X, Y) & (fcmp uno X, 0) --> false
1890*0fca6ea1SDimitry Andric     // (fcmp u** X, Y) | (fcmp uno X, 0) --> fcmp u** X, Y
1891*0fca6ea1SDimitry Andric     // (fcmp u** X, Y) | (fcmp ord X, 0) --> true
1892*0fca6ea1SDimitry Andric     if ((RHS0 == LHS0 || RHS0 == LHS1) && match(RHS1, m_PosZeroFP()))
1893*0fca6ea1SDimitry Andric       return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
1894*0fca6ea1SDimitry Andric                  ? static_cast<Value *>(LHS)
1895*0fca6ea1SDimitry Andric                  : ConstantInt::getBool(LHS->getType(), !IsAnd);
18960b57cec5SDimitry Andric   }
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric   return nullptr;
18990b57cec5SDimitry Andric }
19000b57cec5SDimitry Andric 
190181ad6265SDimitry Andric static Value *simplifyAndOrOfCmps(const SimplifyQuery &Q, Value *Op0,
190281ad6265SDimitry Andric                                   Value *Op1, bool IsAnd) {
19030b57cec5SDimitry Andric   // Look through casts of the 'and' operands to find compares.
19040b57cec5SDimitry Andric   auto *Cast0 = dyn_cast<CastInst>(Op0);
19050b57cec5SDimitry Andric   auto *Cast1 = dyn_cast<CastInst>(Op1);
19060b57cec5SDimitry Andric   if (Cast0 && Cast1 && Cast0->getOpcode() == Cast1->getOpcode() &&
19070b57cec5SDimitry Andric       Cast0->getSrcTy() == Cast1->getSrcTy()) {
19080b57cec5SDimitry Andric     Op0 = Cast0->getOperand(0);
19090b57cec5SDimitry Andric     Op1 = Cast1->getOperand(0);
19100b57cec5SDimitry Andric   }
19110b57cec5SDimitry Andric 
19120b57cec5SDimitry Andric   Value *V = nullptr;
19130b57cec5SDimitry Andric   auto *ICmp0 = dyn_cast<ICmpInst>(Op0);
19140b57cec5SDimitry Andric   auto *ICmp1 = dyn_cast<ICmpInst>(Op1);
19150b57cec5SDimitry Andric   if (ICmp0 && ICmp1)
19168bcb0991SDimitry Andric     V = IsAnd ? simplifyAndOfICmps(ICmp0, ICmp1, Q)
19178bcb0991SDimitry Andric               : simplifyOrOfICmps(ICmp0, ICmp1, Q);
19180b57cec5SDimitry Andric 
19190b57cec5SDimitry Andric   auto *FCmp0 = dyn_cast<FCmpInst>(Op0);
19200b57cec5SDimitry Andric   auto *FCmp1 = dyn_cast<FCmpInst>(Op1);
19210b57cec5SDimitry Andric   if (FCmp0 && FCmp1)
192206c3fb27SDimitry Andric     V = simplifyAndOrOfFCmps(Q, FCmp0, FCmp1, IsAnd);
19230b57cec5SDimitry Andric 
19240b57cec5SDimitry Andric   if (!V)
19250b57cec5SDimitry Andric     return nullptr;
19260b57cec5SDimitry Andric   if (!Cast0)
19270b57cec5SDimitry Andric     return V;
19280b57cec5SDimitry Andric 
19290b57cec5SDimitry Andric   // If we looked through casts, we can only handle a constant simplification
19300b57cec5SDimitry Andric   // because we are not allowed to create a cast instruction here.
19310b57cec5SDimitry Andric   if (auto *C = dyn_cast<Constant>(V))
19325f757f3fSDimitry Andric     return ConstantFoldCastOperand(Cast0->getOpcode(), C, Cast0->getType(),
19335f757f3fSDimitry Andric                                    Q.DL);
19345f757f3fSDimitry Andric 
19355f757f3fSDimitry Andric   return nullptr;
19365f757f3fSDimitry Andric }
19375f757f3fSDimitry Andric 
19385f757f3fSDimitry Andric static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
19395f757f3fSDimitry Andric                                      const SimplifyQuery &Q,
19405f757f3fSDimitry Andric                                      bool AllowRefinement,
19415f757f3fSDimitry Andric                                      SmallVectorImpl<Instruction *> *DropFlags,
19425f757f3fSDimitry Andric                                      unsigned MaxRecurse);
19435f757f3fSDimitry Andric 
19445f757f3fSDimitry Andric static Value *simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1,
19455f757f3fSDimitry Andric                                       const SimplifyQuery &Q,
19465f757f3fSDimitry Andric                                       unsigned MaxRecurse) {
19475f757f3fSDimitry Andric   assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
19485f757f3fSDimitry Andric          "Must be and/or");
19495f757f3fSDimitry Andric   ICmpInst::Predicate Pred;
19505f757f3fSDimitry Andric   Value *A, *B;
19515f757f3fSDimitry Andric   if (!match(Op0, m_ICmp(Pred, m_Value(A), m_Value(B))) ||
19525f757f3fSDimitry Andric       !ICmpInst::isEquality(Pred))
19535f757f3fSDimitry Andric     return nullptr;
19545f757f3fSDimitry Andric 
19555f757f3fSDimitry Andric   auto Simplify = [&](Value *Res) -> Value * {
19565f757f3fSDimitry Andric     Constant *Absorber = ConstantExpr::getBinOpAbsorber(Opcode, Res->getType());
19575f757f3fSDimitry Andric 
19585f757f3fSDimitry Andric     // and (icmp eq a, b), x implies (a==b) inside x.
19595f757f3fSDimitry Andric     // or (icmp ne a, b), x implies (a==b) inside x.
19605f757f3fSDimitry Andric     // If x simplifies to true/false, we can simplify the and/or.
19615f757f3fSDimitry Andric     if (Pred ==
19625f757f3fSDimitry Andric         (Opcode == Instruction::And ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE)) {
19635f757f3fSDimitry Andric       if (Res == Absorber)
19645f757f3fSDimitry Andric         return Absorber;
19655f757f3fSDimitry Andric       if (Res == ConstantExpr::getBinOpIdentity(Opcode, Res->getType()))
19665f757f3fSDimitry Andric         return Op0;
19675f757f3fSDimitry Andric       return nullptr;
19685f757f3fSDimitry Andric     }
19695f757f3fSDimitry Andric 
19705f757f3fSDimitry Andric     // If we have and (icmp ne a, b), x and for a==b we can simplify x to false,
19715f757f3fSDimitry Andric     // then we can drop the icmp, as x will already be false in the case where
19725f757f3fSDimitry Andric     // the icmp is false. Similar for or and true.
19735f757f3fSDimitry Andric     if (Res == Absorber)
19745f757f3fSDimitry Andric       return Op1;
19755f757f3fSDimitry Andric     return nullptr;
19765f757f3fSDimitry Andric   };
19775f757f3fSDimitry Andric 
1978*0fca6ea1SDimitry Andric   // In the final case (Res == Absorber with inverted predicate), it is safe to
1979*0fca6ea1SDimitry Andric   // refine poison during simplification, but not undef. For simplicity always
1980*0fca6ea1SDimitry Andric   // disable undef-based folds here.
1981*0fca6ea1SDimitry Andric   if (Value *Res = simplifyWithOpReplaced(Op1, A, B, Q.getWithoutUndef(),
1982*0fca6ea1SDimitry Andric                                           /* AllowRefinement */ true,
19835f757f3fSDimitry Andric                                           /* DropFlags */ nullptr, MaxRecurse))
19845f757f3fSDimitry Andric     return Simplify(Res);
1985*0fca6ea1SDimitry Andric   if (Value *Res = simplifyWithOpReplaced(Op1, B, A, Q.getWithoutUndef(),
1986*0fca6ea1SDimitry Andric                                           /* AllowRefinement */ true,
19875f757f3fSDimitry Andric                                           /* DropFlags */ nullptr, MaxRecurse))
19885f757f3fSDimitry Andric     return Simplify(Res);
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric   return nullptr;
19910b57cec5SDimitry Andric }
19920b57cec5SDimitry Andric 
1993e8d8bef9SDimitry Andric /// Given a bitwise logic op, check if the operands are add/sub with a common
1994e8d8bef9SDimitry Andric /// source value and inverted constant (identity: C - X -> ~(X + ~C)).
1995e8d8bef9SDimitry Andric static Value *simplifyLogicOfAddSub(Value *Op0, Value *Op1,
1996e8d8bef9SDimitry Andric                                     Instruction::BinaryOps Opcode) {
1997e8d8bef9SDimitry Andric   assert(Op0->getType() == Op1->getType() && "Mismatched binop types");
1998e8d8bef9SDimitry Andric   assert(BinaryOperator::isBitwiseLogicOp(Opcode) && "Expected logic op");
1999e8d8bef9SDimitry Andric   Value *X;
2000e8d8bef9SDimitry Andric   Constant *C1, *C2;
2001e8d8bef9SDimitry Andric   if ((match(Op0, m_Add(m_Value(X), m_Constant(C1))) &&
2002e8d8bef9SDimitry Andric        match(Op1, m_Sub(m_Constant(C2), m_Specific(X)))) ||
2003e8d8bef9SDimitry Andric       (match(Op1, m_Add(m_Value(X), m_Constant(C1))) &&
2004e8d8bef9SDimitry Andric        match(Op0, m_Sub(m_Constant(C2), m_Specific(X))))) {
2005e8d8bef9SDimitry Andric     if (ConstantExpr::getNot(C1) == C2) {
2006e8d8bef9SDimitry Andric       // (X + C) & (~C - X) --> (X + C) & ~(X + C) --> 0
2007e8d8bef9SDimitry Andric       // (X + C) | (~C - X) --> (X + C) | ~(X + C) --> -1
2008e8d8bef9SDimitry Andric       // (X + C) ^ (~C - X) --> (X + C) ^ ~(X + C) --> -1
2009e8d8bef9SDimitry Andric       Type *Ty = Op0->getType();
2010e8d8bef9SDimitry Andric       return Opcode == Instruction::And ? ConstantInt::getNullValue(Ty)
2011e8d8bef9SDimitry Andric                                         : ConstantInt::getAllOnesValue(Ty);
2012e8d8bef9SDimitry Andric     }
2013e8d8bef9SDimitry Andric   }
2014e8d8bef9SDimitry Andric   return nullptr;
2015e8d8bef9SDimitry Andric }
2016e8d8bef9SDimitry Andric 
20175f757f3fSDimitry Andric // Commutative patterns for and that will be tried with both operand orders.
20185f757f3fSDimitry Andric static Value *simplifyAndCommutative(Value *Op0, Value *Op1,
20195f757f3fSDimitry Andric                                      const SimplifyQuery &Q,
20205f757f3fSDimitry Andric                                      unsigned MaxRecurse) {
20215f757f3fSDimitry Andric   // ~A & A =  0
20225f757f3fSDimitry Andric   if (match(Op0, m_Not(m_Specific(Op1))))
20235f757f3fSDimitry Andric     return Constant::getNullValue(Op0->getType());
20245f757f3fSDimitry Andric 
20255f757f3fSDimitry Andric   // (A | ?) & A = A
20265f757f3fSDimitry Andric   if (match(Op0, m_c_Or(m_Specific(Op1), m_Value())))
20275f757f3fSDimitry Andric     return Op1;
20285f757f3fSDimitry Andric 
20295f757f3fSDimitry Andric   // (X | ~Y) & (X | Y) --> X
20305f757f3fSDimitry Andric   Value *X, *Y;
20315f757f3fSDimitry Andric   if (match(Op0, m_c_Or(m_Value(X), m_Not(m_Value(Y)))) &&
2032*0fca6ea1SDimitry Andric       match(Op1, m_c_Or(m_Specific(X), m_Specific(Y))))
20335f757f3fSDimitry Andric     return X;
20345f757f3fSDimitry Andric 
20355f757f3fSDimitry Andric   // If we have a multiplication overflow check that is being 'and'ed with a
20365f757f3fSDimitry Andric   // check that one of the multipliers is not zero, we can omit the 'and', and
20375f757f3fSDimitry Andric   // only keep the overflow check.
20385f757f3fSDimitry Andric   if (isCheckForZeroAndMulWithOverflow(Op0, Op1, true))
20395f757f3fSDimitry Andric     return Op1;
20405f757f3fSDimitry Andric 
20415f757f3fSDimitry Andric   // -A & A = A if A is a power of two or zero.
20425f757f3fSDimitry Andric   if (match(Op0, m_Neg(m_Specific(Op1))) &&
20435f757f3fSDimitry Andric       isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
20445f757f3fSDimitry Andric     return Op1;
20455f757f3fSDimitry Andric 
20465f757f3fSDimitry Andric   // This is a similar pattern used for checking if a value is a power-of-2:
20475f757f3fSDimitry Andric   // (A - 1) & A --> 0 (if A is a power-of-2 or 0)
20485f757f3fSDimitry Andric   if (match(Op0, m_Add(m_Specific(Op1), m_AllOnes())) &&
20495f757f3fSDimitry Andric       isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
20505f757f3fSDimitry Andric     return Constant::getNullValue(Op1->getType());
20515f757f3fSDimitry Andric 
20525f757f3fSDimitry Andric   // (x << N) & ((x << M) - 1) --> 0, where x is known to be a power of 2 and
20535f757f3fSDimitry Andric   // M <= N.
20545f757f3fSDimitry Andric   const APInt *Shift1, *Shift2;
20555f757f3fSDimitry Andric   if (match(Op0, m_Shl(m_Value(X), m_APInt(Shift1))) &&
20565f757f3fSDimitry Andric       match(Op1, m_Add(m_Shl(m_Specific(X), m_APInt(Shift2)), m_AllOnes())) &&
20575f757f3fSDimitry Andric       isKnownToBeAPowerOfTwo(X, Q.DL, /*OrZero*/ true, /*Depth*/ 0, Q.AC,
20585f757f3fSDimitry Andric                              Q.CxtI) &&
20595f757f3fSDimitry Andric       Shift1->uge(*Shift2))
20605f757f3fSDimitry Andric     return Constant::getNullValue(Op0->getType());
20615f757f3fSDimitry Andric 
20625f757f3fSDimitry Andric   if (Value *V =
20635f757f3fSDimitry Andric           simplifyAndOrWithICmpEq(Instruction::And, Op0, Op1, Q, MaxRecurse))
20645f757f3fSDimitry Andric     return V;
20655f757f3fSDimitry Andric 
20665f757f3fSDimitry Andric   return nullptr;
20675f757f3fSDimitry Andric }
20685f757f3fSDimitry Andric 
20690b57cec5SDimitry Andric /// Given operands for an And, see if we can fold the result.
20700b57cec5SDimitry Andric /// If not, this returns null.
207181ad6265SDimitry Andric static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
20720b57cec5SDimitry Andric                               unsigned MaxRecurse) {
20730b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Instruction::And, Op0, Op1, Q))
20740b57cec5SDimitry Andric     return C;
20750b57cec5SDimitry Andric 
2076fe6060f1SDimitry Andric   // X & poison -> poison
2077fe6060f1SDimitry Andric   if (isa<PoisonValue>(Op1))
2078fe6060f1SDimitry Andric     return Op1;
2079fe6060f1SDimitry Andric 
20800b57cec5SDimitry Andric   // X & undef -> 0
2081e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op1))
20820b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
20830b57cec5SDimitry Andric 
20840b57cec5SDimitry Andric   // X & X = X
20850b57cec5SDimitry Andric   if (Op0 == Op1)
20860b57cec5SDimitry Andric     return Op0;
20870b57cec5SDimitry Andric 
20880b57cec5SDimitry Andric   // X & 0 = 0
20890b57cec5SDimitry Andric   if (match(Op1, m_Zero()))
20900b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric   // X & -1 = X
20930b57cec5SDimitry Andric   if (match(Op1, m_AllOnes()))
20940b57cec5SDimitry Andric     return Op0;
20950b57cec5SDimitry Andric 
20965f757f3fSDimitry Andric   if (Value *Res = simplifyAndCommutative(Op0, Op1, Q, MaxRecurse))
20975f757f3fSDimitry Andric     return Res;
20985f757f3fSDimitry Andric   if (Value *Res = simplifyAndCommutative(Op1, Op0, Q, MaxRecurse))
20995f757f3fSDimitry Andric     return Res;
2100349cc55cSDimitry Andric 
2101e8d8bef9SDimitry Andric   if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::And))
2102e8d8bef9SDimitry Andric     return V;
2103e8d8bef9SDimitry Andric 
21040b57cec5SDimitry Andric   // A mask that only clears known zeros of a shifted value is a no-op.
21050b57cec5SDimitry Andric   const APInt *Mask;
21060b57cec5SDimitry Andric   const APInt *ShAmt;
21075f757f3fSDimitry Andric   Value *X, *Y;
21080b57cec5SDimitry Andric   if (match(Op1, m_APInt(Mask))) {
21090b57cec5SDimitry Andric     // If all bits in the inverted and shifted mask are clear:
21100b57cec5SDimitry Andric     // and (shl X, ShAmt), Mask --> shl X, ShAmt
21110b57cec5SDimitry Andric     if (match(Op0, m_Shl(m_Value(X), m_APInt(ShAmt))) &&
2112349cc55cSDimitry Andric         (~(*Mask)).lshr(*ShAmt).isZero())
21130b57cec5SDimitry Andric       return Op0;
21140b57cec5SDimitry Andric 
21150b57cec5SDimitry Andric     // If all bits in the inverted and shifted mask are clear:
21160b57cec5SDimitry Andric     // and (lshr X, ShAmt), Mask --> lshr X, ShAmt
21170b57cec5SDimitry Andric     if (match(Op0, m_LShr(m_Value(X), m_APInt(ShAmt))) &&
2118349cc55cSDimitry Andric         (~(*Mask)).shl(*ShAmt).isZero())
21190b57cec5SDimitry Andric       return Op0;
21200b57cec5SDimitry Andric   }
21210b57cec5SDimitry Andric 
21225f757f3fSDimitry Andric   // and 2^x-1, 2^C --> 0 where x <= C.
21235f757f3fSDimitry Andric   const APInt *PowerC;
21245f757f3fSDimitry Andric   Value *Shift;
21255f757f3fSDimitry Andric   if (match(Op1, m_Power2(PowerC)) &&
21265f757f3fSDimitry Andric       match(Op0, m_Add(m_Value(Shift), m_AllOnes())) &&
21275f757f3fSDimitry Andric       isKnownToBeAPowerOfTwo(Shift, Q.DL, /*OrZero*/ false, 0, Q.AC, Q.CxtI,
21285f757f3fSDimitry Andric                              Q.DT)) {
21295f757f3fSDimitry Andric     KnownBits Known = computeKnownBits(Shift, /* Depth */ 0, Q);
21305f757f3fSDimitry Andric     // Use getActiveBits() to make use of the additional power of two knowledge
21315f757f3fSDimitry Andric     if (PowerC->getActiveBits() >= Known.getMaxValue().getActiveBits())
21325f757f3fSDimitry Andric       return ConstantInt::getNullValue(Op1->getType());
21330b57cec5SDimitry Andric   }
21340b57cec5SDimitry Andric 
21350b57cec5SDimitry Andric   if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, true))
21360b57cec5SDimitry Andric     return V;
21370b57cec5SDimitry Andric 
21380b57cec5SDimitry Andric   // Try some generic simplifications for associative operations.
213981ad6265SDimitry Andric   if (Value *V =
214081ad6265SDimitry Andric           simplifyAssociativeBinOp(Instruction::And, Op0, Op1, Q, MaxRecurse))
21410b57cec5SDimitry Andric     return V;
21420b57cec5SDimitry Andric 
21430b57cec5SDimitry Andric   // And distributes over Or.  Try some generic simplifications based on this.
2144e8d8bef9SDimitry Andric   if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
2145e8d8bef9SDimitry Andric                                         Instruction::Or, Q, MaxRecurse))
21460b57cec5SDimitry Andric     return V;
21470b57cec5SDimitry Andric 
21480b57cec5SDimitry Andric   // And distributes over Xor.  Try some generic simplifications based on this.
2149e8d8bef9SDimitry Andric   if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
2150e8d8bef9SDimitry Andric                                         Instruction::Xor, Q, MaxRecurse))
21510b57cec5SDimitry Andric     return V;
21520b57cec5SDimitry Andric 
2153e8d8bef9SDimitry Andric   if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
2154e8d8bef9SDimitry Andric     if (Op0->getType()->isIntOrIntVectorTy(1)) {
2155e8d8bef9SDimitry Andric       // A & (A && B) -> A && B
2156e8d8bef9SDimitry Andric       if (match(Op1, m_Select(m_Specific(Op0), m_Value(), m_Zero())))
2157e8d8bef9SDimitry Andric         return Op1;
2158e8d8bef9SDimitry Andric       else if (match(Op0, m_Select(m_Specific(Op1), m_Value(), m_Zero())))
2159e8d8bef9SDimitry Andric         return Op0;
2160e8d8bef9SDimitry Andric     }
2161e8d8bef9SDimitry Andric     // If the operation is with the result of a select instruction, check
2162e8d8bef9SDimitry Andric     // whether operating on either branch of the select always yields the same
2163e8d8bef9SDimitry Andric     // value.
216481ad6265SDimitry Andric     if (Value *V =
216581ad6265SDimitry Andric             threadBinOpOverSelect(Instruction::And, Op0, Op1, Q, MaxRecurse))
21660b57cec5SDimitry Andric       return V;
2167e8d8bef9SDimitry Andric   }
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric   // If the operation is with the result of a phi instruction, check whether
21700b57cec5SDimitry Andric   // operating on all incoming values of the phi always yields the same value.
21710b57cec5SDimitry Andric   if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
217281ad6265SDimitry Andric     if (Value *V =
217381ad6265SDimitry Andric             threadBinOpOverPHI(Instruction::And, Op0, Op1, Q, MaxRecurse))
21740b57cec5SDimitry Andric       return V;
21750b57cec5SDimitry Andric 
21760b57cec5SDimitry Andric   // Assuming the effective width of Y is not larger than A, i.e. all bits
21770b57cec5SDimitry Andric   // from X and Y are disjoint in (X << A) | Y,
21780b57cec5SDimitry Andric   // if the mask of this AND op covers all bits of X or Y, while it covers
21790b57cec5SDimitry Andric   // no bits from the other, we can bypass this AND op. E.g.,
21800b57cec5SDimitry Andric   // ((X << A) | Y) & Mask -> Y,
21810b57cec5SDimitry Andric   //     if Mask = ((1 << effective_width_of(Y)) - 1)
21820b57cec5SDimitry Andric   // ((X << A) | Y) & Mask -> X << A,
21830b57cec5SDimitry Andric   //     if Mask = ((1 << effective_width_of(X)) - 1) << A
21840b57cec5SDimitry Andric   // SimplifyDemandedBits in InstCombine can optimize the general case.
21850b57cec5SDimitry Andric   // This pattern aims to help other passes for a common case.
2186349cc55cSDimitry Andric   Value *XShifted;
21875f757f3fSDimitry Andric   if (Q.IIQ.UseInstrInfo && match(Op1, m_APInt(Mask)) &&
21880b57cec5SDimitry Andric       match(Op0, m_c_Or(m_CombineAnd(m_NUWShl(m_Value(X), m_APInt(ShAmt)),
21890b57cec5SDimitry Andric                                      m_Value(XShifted)),
21900b57cec5SDimitry Andric                         m_Value(Y)))) {
21910b57cec5SDimitry Andric     const unsigned Width = Op0->getType()->getScalarSizeInBits();
21920b57cec5SDimitry Andric     const unsigned ShftCnt = ShAmt->getLimitedValue(Width);
21935f757f3fSDimitry Andric     const KnownBits YKnown = computeKnownBits(Y, /* Depth */ 0, Q);
2194349cc55cSDimitry Andric     const unsigned EffWidthY = YKnown.countMaxActiveBits();
21950b57cec5SDimitry Andric     if (EffWidthY <= ShftCnt) {
21965f757f3fSDimitry Andric       const KnownBits XKnown = computeKnownBits(X, /* Depth */ 0, Q);
2197349cc55cSDimitry Andric       const unsigned EffWidthX = XKnown.countMaxActiveBits();
21980b57cec5SDimitry Andric       const APInt EffBitsY = APInt::getLowBitsSet(Width, EffWidthY);
21990b57cec5SDimitry Andric       const APInt EffBitsX = APInt::getLowBitsSet(Width, EffWidthX) << ShftCnt;
22000b57cec5SDimitry Andric       // If the mask is extracting all bits from X or Y as is, we can skip
22010b57cec5SDimitry Andric       // this AND op.
22020b57cec5SDimitry Andric       if (EffBitsY.isSubsetOf(*Mask) && !EffBitsX.intersects(*Mask))
22030b57cec5SDimitry Andric         return Y;
22040b57cec5SDimitry Andric       if (EffBitsX.isSubsetOf(*Mask) && !EffBitsY.intersects(*Mask))
22050b57cec5SDimitry Andric         return XShifted;
22060b57cec5SDimitry Andric     }
22070b57cec5SDimitry Andric   }
22080b57cec5SDimitry Andric 
22090eae32dcSDimitry Andric   // ((X | Y) ^ X ) & ((X | Y) ^ Y) --> 0
22100eae32dcSDimitry Andric   // ((X | Y) ^ Y ) & ((X | Y) ^ X) --> 0
22110eae32dcSDimitry Andric   BinaryOperator *Or;
22120eae32dcSDimitry Andric   if (match(Op0, m_c_Xor(m_Value(X),
22130eae32dcSDimitry Andric                          m_CombineAnd(m_BinOp(Or),
22140eae32dcSDimitry Andric                                       m_c_Or(m_Deferred(X), m_Value(Y))))) &&
22150eae32dcSDimitry Andric       match(Op1, m_c_Xor(m_Specific(Or), m_Specific(Y))))
22160eae32dcSDimitry Andric     return Constant::getNullValue(Op0->getType());
22170eae32dcSDimitry Andric 
22181db9f3b2SDimitry Andric   const APInt *C1;
22191db9f3b2SDimitry Andric   Value *A;
22201db9f3b2SDimitry Andric   // (A ^ C) & (A ^ ~C) -> 0
22211db9f3b2SDimitry Andric   if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
22221db9f3b2SDimitry Andric       match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))
22231db9f3b2SDimitry Andric     return Constant::getNullValue(Op0->getType());
22241db9f3b2SDimitry Andric 
222581ad6265SDimitry Andric   if (Op0->getType()->isIntOrIntVectorTy(1)) {
2226bdd1243dSDimitry Andric     if (std::optional<bool> Implied = isImpliedCondition(Op0, Op1, Q.DL)) {
2227bdd1243dSDimitry Andric       // If Op0 is true implies Op1 is true, then Op0 is a subset of Op1.
2228bdd1243dSDimitry Andric       if (*Implied == true)
222981ad6265SDimitry Andric         return Op0;
2230bdd1243dSDimitry Andric       // If Op0 is true implies Op1 is false, then they are not true together.
2231bdd1243dSDimitry Andric       if (*Implied == false)
2232bdd1243dSDimitry Andric         return ConstantInt::getFalse(Op0->getType());
223381ad6265SDimitry Andric     }
2234bdd1243dSDimitry Andric     if (std::optional<bool> Implied = isImpliedCondition(Op1, Op0, Q.DL)) {
2235bdd1243dSDimitry Andric       // If Op1 is true implies Op0 is true, then Op1 is a subset of Op0.
2236bdd1243dSDimitry Andric       if (*Implied)
2237bdd1243dSDimitry Andric         return Op1;
2238bdd1243dSDimitry Andric       // If Op1 is true implies Op0 is false, then they are not true together.
2239bdd1243dSDimitry Andric       if (!*Implied)
2240bdd1243dSDimitry Andric         return ConstantInt::getFalse(Op1->getType());
2241bdd1243dSDimitry Andric     }
2242bdd1243dSDimitry Andric   }
2243bdd1243dSDimitry Andric 
2244bdd1243dSDimitry Andric   if (Value *V = simplifyByDomEq(Instruction::And, Op0, Op1, Q, MaxRecurse))
2245bdd1243dSDimitry Andric     return V;
224681ad6265SDimitry Andric 
22470b57cec5SDimitry Andric   return nullptr;
22480b57cec5SDimitry Andric }
22490b57cec5SDimitry Andric 
225081ad6265SDimitry Andric Value *llvm::simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
225181ad6265SDimitry Andric   return ::simplifyAndInst(Op0, Op1, Q, RecursionLimit);
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric 
2254bdd1243dSDimitry Andric // TODO: Many of these folds could use LogicalAnd/LogicalOr.
22554824e7fdSDimitry Andric static Value *simplifyOrLogic(Value *X, Value *Y) {
22564824e7fdSDimitry Andric   assert(X->getType() == Y->getType() && "Expected same type for 'or' ops");
22574824e7fdSDimitry Andric   Type *Ty = X->getType();
22584824e7fdSDimitry Andric 
22594824e7fdSDimitry Andric   // X | ~X --> -1
22604824e7fdSDimitry Andric   if (match(Y, m_Not(m_Specific(X))))
22614824e7fdSDimitry Andric     return ConstantInt::getAllOnesValue(Ty);
22624824e7fdSDimitry Andric 
22634824e7fdSDimitry Andric   // X | ~(X & ?) = -1
22644824e7fdSDimitry Andric   if (match(Y, m_Not(m_c_And(m_Specific(X), m_Value()))))
22654824e7fdSDimitry Andric     return ConstantInt::getAllOnesValue(Ty);
22664824e7fdSDimitry Andric 
22674824e7fdSDimitry Andric   // X | (X & ?) --> X
22684824e7fdSDimitry Andric   if (match(Y, m_c_And(m_Specific(X), m_Value())))
22694824e7fdSDimitry Andric     return X;
22704824e7fdSDimitry Andric 
22714824e7fdSDimitry Andric   Value *A, *B;
22724824e7fdSDimitry Andric 
22730eae32dcSDimitry Andric   // (A ^ B) | (A | B) --> A | B
22740eae32dcSDimitry Andric   // (A ^ B) | (B | A) --> B | A
22750eae32dcSDimitry Andric   if (match(X, m_Xor(m_Value(A), m_Value(B))) &&
22760eae32dcSDimitry Andric       match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
22770eae32dcSDimitry Andric     return Y;
22780eae32dcSDimitry Andric 
22790eae32dcSDimitry Andric   // ~(A ^ B) | (A | B) --> -1
22800eae32dcSDimitry Andric   // ~(A ^ B) | (B | A) --> -1
22810eae32dcSDimitry Andric   if (match(X, m_Not(m_Xor(m_Value(A), m_Value(B)))) &&
22820eae32dcSDimitry Andric       match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
22830eae32dcSDimitry Andric     return ConstantInt::getAllOnesValue(Ty);
22840eae32dcSDimitry Andric 
22854824e7fdSDimitry Andric   // (A & ~B) | (A ^ B) --> A ^ B
22864824e7fdSDimitry Andric   // (~B & A) | (A ^ B) --> A ^ B
22874824e7fdSDimitry Andric   // (A & ~B) | (B ^ A) --> B ^ A
22884824e7fdSDimitry Andric   // (~B & A) | (B ^ A) --> B ^ A
22894824e7fdSDimitry Andric   if (match(X, m_c_And(m_Value(A), m_Not(m_Value(B)))) &&
22904824e7fdSDimitry Andric       match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
22914824e7fdSDimitry Andric     return Y;
22924824e7fdSDimitry Andric 
22934824e7fdSDimitry Andric   // (~A ^ B) | (A & B) --> ~A ^ B
22944824e7fdSDimitry Andric   // (B ^ ~A) | (A & B) --> B ^ ~A
22954824e7fdSDimitry Andric   // (~A ^ B) | (B & A) --> ~A ^ B
22964824e7fdSDimitry Andric   // (B ^ ~A) | (B & A) --> B ^ ~A
2297*0fca6ea1SDimitry Andric   if (match(X, m_c_Xor(m_Not(m_Value(A)), m_Value(B))) &&
22984824e7fdSDimitry Andric       match(Y, m_c_And(m_Specific(A), m_Specific(B))))
22994824e7fdSDimitry Andric     return X;
23004824e7fdSDimitry Andric 
23010eae32dcSDimitry Andric   // (~A | B) | (A ^ B) --> -1
23020eae32dcSDimitry Andric   // (~A | B) | (B ^ A) --> -1
23030eae32dcSDimitry Andric   // (B | ~A) | (A ^ B) --> -1
23040eae32dcSDimitry Andric   // (B | ~A) | (B ^ A) --> -1
23050eae32dcSDimitry Andric   if (match(X, m_c_Or(m_Not(m_Value(A)), m_Value(B))) &&
23060eae32dcSDimitry Andric       match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
23074824e7fdSDimitry Andric     return ConstantInt::getAllOnesValue(Ty);
23084824e7fdSDimitry Andric 
23090eae32dcSDimitry Andric   // (~A & B) | ~(A | B) --> ~A
23100eae32dcSDimitry Andric   // (~A & B) | ~(B | A) --> ~A
23110eae32dcSDimitry Andric   // (B & ~A) | ~(A | B) --> ~A
23120eae32dcSDimitry Andric   // (B & ~A) | ~(B | A) --> ~A
23130eae32dcSDimitry Andric   Value *NotA;
2314*0fca6ea1SDimitry Andric   if (match(X, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
23150eae32dcSDimitry Andric                        m_Value(B))) &&
23160eae32dcSDimitry Andric       match(Y, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
23170eae32dcSDimitry Andric     return NotA;
2318bdd1243dSDimitry Andric   // The same is true of Logical And
2319bdd1243dSDimitry Andric   // TODO: This could share the logic of the version above if there was a
2320bdd1243dSDimitry Andric   // version of LogicalAnd that allowed more than just i1 types.
2321*0fca6ea1SDimitry Andric   if (match(X, m_c_LogicalAnd(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
2322bdd1243dSDimitry Andric                               m_Value(B))) &&
2323bdd1243dSDimitry Andric       match(Y, m_Not(m_c_LogicalOr(m_Specific(A), m_Specific(B)))))
2324bdd1243dSDimitry Andric     return NotA;
23250eae32dcSDimitry Andric 
232604eeddc0SDimitry Andric   // ~(A ^ B) | (A & B) --> ~(A ^ B)
232704eeddc0SDimitry Andric   // ~(A ^ B) | (B & A) --> ~(A ^ B)
23280eae32dcSDimitry Andric   Value *NotAB;
2329*0fca6ea1SDimitry Andric   if (match(X, m_CombineAnd(m_Not(m_Xor(m_Value(A), m_Value(B))),
23300eae32dcSDimitry Andric                             m_Value(NotAB))) &&
23310eae32dcSDimitry Andric       match(Y, m_c_And(m_Specific(A), m_Specific(B))))
23320eae32dcSDimitry Andric     return NotAB;
23330eae32dcSDimitry Andric 
233404eeddc0SDimitry Andric   // ~(A & B) | (A ^ B) --> ~(A & B)
233504eeddc0SDimitry Andric   // ~(A & B) | (B ^ A) --> ~(A & B)
2336*0fca6ea1SDimitry Andric   if (match(X, m_CombineAnd(m_Not(m_And(m_Value(A), m_Value(B))),
233704eeddc0SDimitry Andric                             m_Value(NotAB))) &&
233804eeddc0SDimitry Andric       match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
233904eeddc0SDimitry Andric     return NotAB;
234004eeddc0SDimitry Andric 
23414824e7fdSDimitry Andric   return nullptr;
23424824e7fdSDimitry Andric }
23434824e7fdSDimitry Andric 
23440b57cec5SDimitry Andric /// Given operands for an Or, see if we can fold the result.
23450b57cec5SDimitry Andric /// If not, this returns null.
234681ad6265SDimitry Andric static Value *simplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
23470b57cec5SDimitry Andric                              unsigned MaxRecurse) {
23480b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Instruction::Or, Op0, Op1, Q))
23490b57cec5SDimitry Andric     return C;
23500b57cec5SDimitry Andric 
2351fe6060f1SDimitry Andric   // X | poison -> poison
2352fe6060f1SDimitry Andric   if (isa<PoisonValue>(Op1))
2353fe6060f1SDimitry Andric     return Op1;
2354fe6060f1SDimitry Andric 
23550b57cec5SDimitry Andric   // X | undef -> -1
23560b57cec5SDimitry Andric   // X | -1 = -1
23570b57cec5SDimitry Andric   // Do not return Op1 because it may contain undef elements if it's a vector.
2358e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op1) || match(Op1, m_AllOnes()))
23590b57cec5SDimitry Andric     return Constant::getAllOnesValue(Op0->getType());
23600b57cec5SDimitry Andric 
23610b57cec5SDimitry Andric   // X | X = X
23620b57cec5SDimitry Andric   // X | 0 = X
23630b57cec5SDimitry Andric   if (Op0 == Op1 || match(Op1, m_Zero()))
23640b57cec5SDimitry Andric     return Op0;
23650b57cec5SDimitry Andric 
23664824e7fdSDimitry Andric   if (Value *R = simplifyOrLogic(Op0, Op1))
23674824e7fdSDimitry Andric     return R;
23684824e7fdSDimitry Andric   if (Value *R = simplifyOrLogic(Op1, Op0))
23694824e7fdSDimitry Andric     return R;
23700b57cec5SDimitry Andric 
2371e8d8bef9SDimitry Andric   if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Or))
2372e8d8bef9SDimitry Andric     return V;
2373e8d8bef9SDimitry Andric 
2374349cc55cSDimitry Andric   // Rotated -1 is still -1:
2375349cc55cSDimitry Andric   // (-1 << X) | (-1 >> (C - X)) --> -1
2376349cc55cSDimitry Andric   // (-1 >> X) | (-1 << (C - X)) --> -1
2377349cc55cSDimitry Andric   // ...with C <= bitwidth (and commuted variants).
2378349cc55cSDimitry Andric   Value *X, *Y;
2379349cc55cSDimitry Andric   if ((match(Op0, m_Shl(m_AllOnes(), m_Value(X))) &&
2380349cc55cSDimitry Andric        match(Op1, m_LShr(m_AllOnes(), m_Value(Y)))) ||
2381349cc55cSDimitry Andric       (match(Op1, m_Shl(m_AllOnes(), m_Value(X))) &&
2382349cc55cSDimitry Andric        match(Op0, m_LShr(m_AllOnes(), m_Value(Y))))) {
2383349cc55cSDimitry Andric     const APInt *C;
2384349cc55cSDimitry Andric     if ((match(X, m_Sub(m_APInt(C), m_Specific(Y))) ||
2385349cc55cSDimitry Andric          match(Y, m_Sub(m_APInt(C), m_Specific(X)))) &&
2386349cc55cSDimitry Andric         C->ule(X->getType()->getScalarSizeInBits())) {
2387349cc55cSDimitry Andric       return ConstantInt::getAllOnesValue(X->getType());
2388349cc55cSDimitry Andric     }
2389349cc55cSDimitry Andric   }
2390349cc55cSDimitry Andric 
239181ad6265SDimitry Andric   // A funnel shift (rotate) can be decomposed into simpler shifts. See if we
239281ad6265SDimitry Andric   // are mixing in another shift that is redundant with the funnel shift.
239381ad6265SDimitry Andric 
239481ad6265SDimitry Andric   // (fshl X, ?, Y) | (shl X, Y) --> fshl X, ?, Y
239581ad6265SDimitry Andric   // (shl X, Y) | (fshl X, ?, Y) --> fshl X, ?, Y
239681ad6265SDimitry Andric   if (match(Op0,
239781ad6265SDimitry Andric             m_Intrinsic<Intrinsic::fshl>(m_Value(X), m_Value(), m_Value(Y))) &&
239881ad6265SDimitry Andric       match(Op1, m_Shl(m_Specific(X), m_Specific(Y))))
239981ad6265SDimitry Andric     return Op0;
240081ad6265SDimitry Andric   if (match(Op1,
240181ad6265SDimitry Andric             m_Intrinsic<Intrinsic::fshl>(m_Value(X), m_Value(), m_Value(Y))) &&
240281ad6265SDimitry Andric       match(Op0, m_Shl(m_Specific(X), m_Specific(Y))))
240381ad6265SDimitry Andric     return Op1;
240481ad6265SDimitry Andric 
240581ad6265SDimitry Andric   // (fshr ?, X, Y) | (lshr X, Y) --> fshr ?, X, Y
240681ad6265SDimitry Andric   // (lshr X, Y) | (fshr ?, X, Y) --> fshr ?, X, Y
240781ad6265SDimitry Andric   if (match(Op0,
240881ad6265SDimitry Andric             m_Intrinsic<Intrinsic::fshr>(m_Value(), m_Value(X), m_Value(Y))) &&
240981ad6265SDimitry Andric       match(Op1, m_LShr(m_Specific(X), m_Specific(Y))))
241081ad6265SDimitry Andric     return Op0;
241181ad6265SDimitry Andric   if (match(Op1,
241281ad6265SDimitry Andric             m_Intrinsic<Intrinsic::fshr>(m_Value(), m_Value(X), m_Value(Y))) &&
241381ad6265SDimitry Andric       match(Op0, m_LShr(m_Specific(X), m_Specific(Y))))
241481ad6265SDimitry Andric     return Op1;
241581ad6265SDimitry Andric 
24165f757f3fSDimitry Andric   if (Value *V =
24175f757f3fSDimitry Andric           simplifyAndOrWithICmpEq(Instruction::Or, Op0, Op1, Q, MaxRecurse))
24185f757f3fSDimitry Andric     return V;
24195f757f3fSDimitry Andric   if (Value *V =
24205f757f3fSDimitry Andric           simplifyAndOrWithICmpEq(Instruction::Or, Op1, Op0, Q, MaxRecurse))
24215f757f3fSDimitry Andric     return V;
24225f757f3fSDimitry Andric 
24230b57cec5SDimitry Andric   if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
24240b57cec5SDimitry Andric     return V;
24250b57cec5SDimitry Andric 
24268bcb0991SDimitry Andric   // If we have a multiplication overflow check that is being 'and'ed with a
24278bcb0991SDimitry Andric   // check that one of the multipliers is not zero, we can omit the 'and', and
24288bcb0991SDimitry Andric   // only keep the overflow check.
2429fe6060f1SDimitry Andric   if (isCheckForZeroAndMulWithOverflow(Op0, Op1, false))
2430fe6060f1SDimitry Andric     return Op1;
2431fe6060f1SDimitry Andric   if (isCheckForZeroAndMulWithOverflow(Op1, Op0, false))
2432fe6060f1SDimitry Andric     return Op0;
24338bcb0991SDimitry Andric 
24340b57cec5SDimitry Andric   // Try some generic simplifications for associative operations.
243581ad6265SDimitry Andric   if (Value *V =
243681ad6265SDimitry Andric           simplifyAssociativeBinOp(Instruction::Or, Op0, Op1, Q, MaxRecurse))
24370b57cec5SDimitry Andric     return V;
24380b57cec5SDimitry Andric 
24390b57cec5SDimitry Andric   // Or distributes over And.  Try some generic simplifications based on this.
2440e8d8bef9SDimitry Andric   if (Value *V = expandCommutativeBinOp(Instruction::Or, Op0, Op1,
2441e8d8bef9SDimitry Andric                                         Instruction::And, Q, MaxRecurse))
24420b57cec5SDimitry Andric     return V;
24430b57cec5SDimitry Andric 
2444e8d8bef9SDimitry Andric   if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
2445e8d8bef9SDimitry Andric     if (Op0->getType()->isIntOrIntVectorTy(1)) {
2446e8d8bef9SDimitry Andric       // A | (A || B) -> A || B
2447e8d8bef9SDimitry Andric       if (match(Op1, m_Select(m_Specific(Op0), m_One(), m_Value())))
2448e8d8bef9SDimitry Andric         return Op1;
2449e8d8bef9SDimitry Andric       else if (match(Op0, m_Select(m_Specific(Op1), m_One(), m_Value())))
2450e8d8bef9SDimitry Andric         return Op0;
2451e8d8bef9SDimitry Andric     }
2452e8d8bef9SDimitry Andric     // If the operation is with the result of a select instruction, check
2453e8d8bef9SDimitry Andric     // whether operating on either branch of the select always yields the same
2454e8d8bef9SDimitry Andric     // value.
245581ad6265SDimitry Andric     if (Value *V =
245681ad6265SDimitry Andric             threadBinOpOverSelect(Instruction::Or, Op0, Op1, Q, MaxRecurse))
24570b57cec5SDimitry Andric       return V;
2458e8d8bef9SDimitry Andric   }
24590b57cec5SDimitry Andric 
24600b57cec5SDimitry Andric   // (A & C1)|(B & C2)
24610eae32dcSDimitry Andric   Value *A, *B;
24620b57cec5SDimitry Andric   const APInt *C1, *C2;
24630b57cec5SDimitry Andric   if (match(Op0, m_And(m_Value(A), m_APInt(C1))) &&
24640b57cec5SDimitry Andric       match(Op1, m_And(m_Value(B), m_APInt(C2)))) {
24650b57cec5SDimitry Andric     if (*C1 == ~*C2) {
24660b57cec5SDimitry Andric       // (A & C1)|(B & C2)
24670b57cec5SDimitry Andric       // If we have: ((V + N) & C1) | (V & C2)
24680b57cec5SDimitry Andric       // .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
24690b57cec5SDimitry Andric       // replace with V+N.
24700b57cec5SDimitry Andric       Value *N;
24710b57cec5SDimitry Andric       if (C2->isMask() && // C2 == 0+1+
24720b57cec5SDimitry Andric           match(A, m_c_Add(m_Specific(B), m_Value(N)))) {
24730b57cec5SDimitry Andric         // Add commutes, try both ways.
24745f757f3fSDimitry Andric         if (MaskedValueIsZero(N, *C2, Q))
24750b57cec5SDimitry Andric           return A;
24760b57cec5SDimitry Andric       }
24770b57cec5SDimitry Andric       // Or commutes, try both ways.
247881ad6265SDimitry Andric       if (C1->isMask() && match(B, m_c_Add(m_Specific(A), m_Value(N)))) {
24790b57cec5SDimitry Andric         // Add commutes, try both ways.
24805f757f3fSDimitry Andric         if (MaskedValueIsZero(N, *C1, Q))
24810b57cec5SDimitry Andric           return B;
24820b57cec5SDimitry Andric       }
24830b57cec5SDimitry Andric     }
24840b57cec5SDimitry Andric   }
24850b57cec5SDimitry Andric 
24860b57cec5SDimitry Andric   // If the operation is with the result of a phi instruction, check whether
24870b57cec5SDimitry Andric   // operating on all incoming values of the phi always yields the same value.
24880b57cec5SDimitry Andric   if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
248981ad6265SDimitry Andric     if (Value *V = threadBinOpOverPHI(Instruction::Or, Op0, Op1, Q, MaxRecurse))
24900b57cec5SDimitry Andric       return V;
24910b57cec5SDimitry Andric 
24921db9f3b2SDimitry Andric   // (A ^ C) | (A ^ ~C) -> -1, i.e. all bits set to one.
24931db9f3b2SDimitry Andric   if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
24941db9f3b2SDimitry Andric       match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))
24951db9f3b2SDimitry Andric     return Constant::getAllOnesValue(Op0->getType());
24961db9f3b2SDimitry Andric 
249781ad6265SDimitry Andric   if (Op0->getType()->isIntOrIntVectorTy(1)) {
2498bdd1243dSDimitry Andric     if (std::optional<bool> Implied =
2499bdd1243dSDimitry Andric             isImpliedCondition(Op0, Op1, Q.DL, false)) {
2500bdd1243dSDimitry Andric       // If Op0 is false implies Op1 is false, then Op1 is a subset of Op0.
2501bdd1243dSDimitry Andric       if (*Implied == false)
250281ad6265SDimitry Andric         return Op0;
2503bdd1243dSDimitry Andric       // If Op0 is false implies Op1 is true, then at least one is always true.
2504bdd1243dSDimitry Andric       if (*Implied == true)
2505bdd1243dSDimitry Andric         return ConstantInt::getTrue(Op0->getType());
250681ad6265SDimitry Andric     }
2507bdd1243dSDimitry Andric     if (std::optional<bool> Implied =
2508bdd1243dSDimitry Andric             isImpliedCondition(Op1, Op0, Q.DL, false)) {
2509bdd1243dSDimitry Andric       // If Op1 is false implies Op0 is false, then Op0 is a subset of Op1.
2510bdd1243dSDimitry Andric       if (*Implied == false)
2511bdd1243dSDimitry Andric         return Op1;
2512bdd1243dSDimitry Andric       // If Op1 is false implies Op0 is true, then at least one is always true.
2513bdd1243dSDimitry Andric       if (*Implied == true)
2514bdd1243dSDimitry Andric         return ConstantInt::getTrue(Op1->getType());
2515bdd1243dSDimitry Andric     }
2516bdd1243dSDimitry Andric   }
2517bdd1243dSDimitry Andric 
2518bdd1243dSDimitry Andric   if (Value *V = simplifyByDomEq(Instruction::Or, Op0, Op1, Q, MaxRecurse))
2519bdd1243dSDimitry Andric     return V;
252081ad6265SDimitry Andric 
25210b57cec5SDimitry Andric   return nullptr;
25220b57cec5SDimitry Andric }
25230b57cec5SDimitry Andric 
252481ad6265SDimitry Andric Value *llvm::simplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
252581ad6265SDimitry Andric   return ::simplifyOrInst(Op0, Op1, Q, RecursionLimit);
25260b57cec5SDimitry Andric }
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric /// Given operands for a Xor, see if we can fold the result.
25290b57cec5SDimitry Andric /// If not, this returns null.
253081ad6265SDimitry Andric static Value *simplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
25310b57cec5SDimitry Andric                               unsigned MaxRecurse) {
25320b57cec5SDimitry Andric   if (Constant *C = foldOrCommuteConstant(Instruction::Xor, Op0, Op1, Q))
25330b57cec5SDimitry Andric     return C;
25340b57cec5SDimitry Andric 
25351fd87a68SDimitry Andric   // X ^ poison -> poison
25361fd87a68SDimitry Andric   if (isa<PoisonValue>(Op1))
25371fd87a68SDimitry Andric     return Op1;
25381fd87a68SDimitry Andric 
25390b57cec5SDimitry Andric   // A ^ undef -> undef
2540e8d8bef9SDimitry Andric   if (Q.isUndefValue(Op1))
25410b57cec5SDimitry Andric     return Op1;
25420b57cec5SDimitry Andric 
25430b57cec5SDimitry Andric   // A ^ 0 = A
25440b57cec5SDimitry Andric   if (match(Op1, m_Zero()))
25450b57cec5SDimitry Andric     return Op0;
25460b57cec5SDimitry Andric 
25470b57cec5SDimitry Andric   // A ^ A = 0
25480b57cec5SDimitry Andric   if (Op0 == Op1)
25490b57cec5SDimitry Andric     return Constant::getNullValue(Op0->getType());
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric   // A ^ ~A  =  ~A ^ A  =  -1
255281ad6265SDimitry Andric   if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0))))
25530b57cec5SDimitry Andric     return Constant::getAllOnesValue(Op0->getType());
25540b57cec5SDimitry Andric 
25554824e7fdSDimitry Andric   auto foldAndOrNot = [](Value *X, Value *Y) -> Value * {
25564824e7fdSDimitry Andric     Value *A, *B;
25574824e7fdSDimitry Andric     // (~A & B) ^ (A | B) --> A -- There are 8 commuted variants.
25584824e7fdSDimitry Andric     if (match(X, m_c_And(m_Not(m_Value(A)), m_Value(B))) &&
25594824e7fdSDimitry Andric         match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
25604824e7fdSDimitry Andric       return A;
25614824e7fdSDimitry Andric 
25624824e7fdSDimitry Andric     // (~A | B) ^ (A & B) --> ~A -- There are 8 commuted variants.
25634824e7fdSDimitry Andric     // The 'not' op must contain a complete -1 operand (no undef elements for
25644824e7fdSDimitry Andric     // vector) for the transform to be safe.
25654824e7fdSDimitry Andric     Value *NotA;
2566*0fca6ea1SDimitry Andric     if (match(X, m_c_Or(m_CombineAnd(m_Not(m_Value(A)), m_Value(NotA)),
25674824e7fdSDimitry Andric                         m_Value(B))) &&
25684824e7fdSDimitry Andric         match(Y, m_c_And(m_Specific(A), m_Specific(B))))
25694824e7fdSDimitry Andric       return NotA;
25704824e7fdSDimitry Andric 
25714824e7fdSDimitry Andric     return nullptr;
25724824e7fdSDimitry Andric   };
25734824e7fdSDimitry Andric   if (Value *R = foldAndOrNot(Op0, Op1))
25744824e7fdSDimitry Andric     return R;
25754824e7fdSDimitry Andric   if (Value *R = foldAndOrNot(Op1, Op0))
25764824e7fdSDimitry Andric     return R;
25774824e7fdSDimitry Andric 
2578e8d8bef9SDimitry Andric   if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Xor))
2579e8d8bef9SDimitry Andric     return V;
2580e8d8bef9SDimitry Andric 
25810b57cec5SDimitry Andric   // Try some generic simplifications for associative operations.
258281ad6265SDimitry Andric   if (Value *V =
258381ad6265SDimitry Andric           simplifyAssociativeBinOp(Instruction::Xor, Op0, Op1, Q, MaxRecurse))
25840b57cec5SDimitry Andric     return V;
25850b57cec5SDimitry Andric 
25860b57cec5SDimitry Andric   // Threading Xor over selects and phi nodes is pointless, so don't bother.
25870b57cec5SDimitry Andric   // Threading over the select in "A ^ select(cond, B, C)" means evaluating
25880b57cec5SDimitry Andric   // "A^B" and "A^C" and seeing if they are equal; but they are equal if and
25890b57cec5SDimitry Andric   // only if B and C are equal.  If B and C are equal then (since we assume
25900b57cec5SDimitry Andric   // that operands have already been simplified) "select(cond, B, C)" should
25910b57cec5SDimitry Andric   // have been simplified to the common value of B and C already.  Analysing
25920b57cec5SDimitry Andric   // "A^B" and "A^C" thus gains nothing, but costs compile time.  Similarly
25930b57cec5SDimitry Andric   // for threading over phi nodes.
25940b57cec5SDimitry Andric 
2595bdd1243dSDimitry Andric   if (Value *V = simplifyByDomEq(Instruction::Xor, Op0, Op1, Q, MaxRecurse))
2596bdd1243dSDimitry Andric     return V;
2597bdd1243dSDimitry Andric 
25980b57cec5SDimitry Andric   return nullptr;
25990b57cec5SDimitry Andric }
26000b57cec5SDimitry Andric 
260181ad6265SDimitry Andric Value *llvm::simplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
260281ad6265SDimitry Andric   return ::simplifyXorInst(Op0, Op1, Q, RecursionLimit);
26030b57cec5SDimitry Andric }
26040b57cec5SDimitry Andric 
260581ad6265SDimitry Andric static Type *getCompareTy(Value *Op) {
26060b57cec5SDimitry Andric   return CmpInst::makeCmpResultType(Op->getType());
26070b57cec5SDimitry Andric }
26080b57cec5SDimitry Andric 
26090b57cec5SDimitry Andric /// Rummage around inside V looking for something equivalent to the comparison
26100b57cec5SDimitry Andric /// "LHS Pred RHS". Return such a value if found, otherwise return null.
26110b57cec5SDimitry Andric /// Helper function for analyzing max/min idioms.
261281ad6265SDimitry Andric static Value *extractEquivalentCondition(Value *V, CmpInst::Predicate Pred,
26130b57cec5SDimitry Andric                                          Value *LHS, Value *RHS) {
26140b57cec5SDimitry Andric   SelectInst *SI = dyn_cast<SelectInst>(V);
26150b57cec5SDimitry Andric   if (!SI)
26160b57cec5SDimitry Andric     return nullptr;
26170b57cec5SDimitry Andric   CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition());
26180b57cec5SDimitry Andric   if (!Cmp)
26190b57cec5SDimitry Andric     return nullptr;
26200b57cec5SDimitry Andric   Value *CmpLHS = Cmp->getOperand(0), *CmpRHS = Cmp->getOperand(1);
26210b57cec5SDimitry Andric   if (Pred == Cmp->getPredicate() && LHS == CmpLHS && RHS == CmpRHS)
26220b57cec5SDimitry Andric     return Cmp;
26230b57cec5SDimitry Andric   if (Pred == CmpInst::getSwappedPredicate(Cmp->getPredicate()) &&
26240b57cec5SDimitry Andric       LHS == CmpRHS && RHS == CmpLHS)
26250b57cec5SDimitry Andric     return Cmp;
26260b57cec5SDimitry Andric   return nullptr;
26270b57cec5SDimitry Andric }
26280b57cec5SDimitry Andric 
262981ad6265SDimitry Andric /// Return true if the underlying object (storage) must be disjoint from
263081ad6265SDimitry Andric /// storage returned by any noalias return call.
263181ad6265SDimitry Andric static bool isAllocDisjoint(const Value *V) {
263281ad6265SDimitry Andric   // For allocas, we consider only static ones (dynamic
263381ad6265SDimitry Andric   // allocas might be transformed into calls to malloc not simultaneously
263481ad6265SDimitry Andric   // live with the compared-to allocation). For globals, we exclude symbols
263581ad6265SDimitry Andric   // that might be resolve lazily to symbols in another dynamically-loaded
263681ad6265SDimitry Andric   // library (and, thus, could be malloc'ed by the implementation).
263781ad6265SDimitry Andric   if (const AllocaInst *AI = dyn_cast<AllocaInst>(V))
263806c3fb27SDimitry Andric     return AI->isStaticAlloca();
263981ad6265SDimitry Andric   if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
264081ad6265SDimitry Andric     return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
264181ad6265SDimitry Andric             GV->hasProtectedVisibility() || GV->hasGlobalUnnamedAddr()) &&
264281ad6265SDimitry Andric            !GV->isThreadLocal();
264381ad6265SDimitry Andric   if (const Argument *A = dyn_cast<Argument>(V))
264481ad6265SDimitry Andric     return A->hasByValAttr();
264581ad6265SDimitry Andric   return false;
264681ad6265SDimitry Andric }
264781ad6265SDimitry Andric 
264881ad6265SDimitry Andric /// Return true if V1 and V2 are each the base of some distict storage region
264981ad6265SDimitry Andric /// [V, object_size(V)] which do not overlap.  Note that zero sized regions
265081ad6265SDimitry Andric /// *are* possible, and that zero sized regions do not overlap with any other.
265181ad6265SDimitry Andric static bool haveNonOverlappingStorage(const Value *V1, const Value *V2) {
265281ad6265SDimitry Andric   // Global variables always exist, so they always exist during the lifetime
265381ad6265SDimitry Andric   // of each other and all allocas.  Global variables themselves usually have
265481ad6265SDimitry Andric   // non-overlapping storage, but since their addresses are constants, the
265581ad6265SDimitry Andric   // case involving two globals does not reach here and is instead handled in
265681ad6265SDimitry Andric   // constant folding.
265781ad6265SDimitry Andric   //
265881ad6265SDimitry Andric   // Two different allocas usually have different addresses...
265981ad6265SDimitry Andric   //
266081ad6265SDimitry Andric   // However, if there's an @llvm.stackrestore dynamically in between two
266181ad6265SDimitry Andric   // allocas, they may have the same address. It's tempting to reduce the
266281ad6265SDimitry Andric   // scope of the problem by only looking at *static* allocas here. That would
266381ad6265SDimitry Andric   // cover the majority of allocas while significantly reducing the likelihood
266481ad6265SDimitry Andric   // of having an @llvm.stackrestore pop up in the middle. However, it's not
266581ad6265SDimitry Andric   // actually impossible for an @llvm.stackrestore to pop up in the middle of
266681ad6265SDimitry Andric   // an entry block. Also, if we have a block that's not attached to a
266781ad6265SDimitry Andric   // function, we can't tell if it's "static" under the current definition.
266881ad6265SDimitry Andric   // Theoretically, this problem could be fixed by creating a new kind of
266981ad6265SDimitry Andric   // instruction kind specifically for static allocas. Such a new instruction
267081ad6265SDimitry Andric   // could be required to be at the top of the entry block, thus preventing it
267181ad6265SDimitry Andric   // from being subject to a @llvm.stackrestore. Instcombine could even
267281ad6265SDimitry Andric   // convert regular allocas into these special allocas. It'd be nifty.
267381ad6265SDimitry Andric   // However, until then, this problem remains open.
267481ad6265SDimitry Andric   //
267581ad6265SDimitry Andric   // So, we'll assume that two non-empty allocas have different addresses
267681ad6265SDimitry Andric   // for now.
267781ad6265SDimitry Andric   auto isByValArg = [](const Value *V) {
267881ad6265SDimitry Andric     const Argument *A = dyn_cast<Argument>(V);
267981ad6265SDimitry Andric     return A && A->hasByValAttr();
268081ad6265SDimitry Andric   };
268181ad6265SDimitry Andric 
268281ad6265SDimitry Andric   // Byval args are backed by store which does not overlap with each other,
268381ad6265SDimitry Andric   // allocas, or globals.
268481ad6265SDimitry Andric   if (isByValArg(V1))
268581ad6265SDimitry Andric     return isa<AllocaInst>(V2) || isa<GlobalVariable>(V2) || isByValArg(V2);
268681ad6265SDimitry Andric   if (isByValArg(V2))
268781ad6265SDimitry Andric     return isa<AllocaInst>(V1) || isa<GlobalVariable>(V1) || isByValArg(V1);
268881ad6265SDimitry Andric 
268981ad6265SDimitry Andric   return isa<AllocaInst>(V1) &&
269081ad6265SDimitry Andric          (isa<AllocaInst>(V2) || isa<GlobalVariable>(V2));
269181ad6265SDimitry Andric }
269281ad6265SDimitry Andric 
26930b57cec5SDimitry Andric // A significant optimization not implemented here is assuming that alloca
26940b57cec5SDimitry Andric // addresses are not equal to incoming argument values. They don't *alias*,
26950b57cec5SDimitry Andric // as we say, but that doesn't mean they aren't equal, so we take a
26960b57cec5SDimitry Andric // conservative approach.
26970b57cec5SDimitry Andric //
26980b57cec5SDimitry Andric // This is inspired in part by C++11 5.10p1:
26990b57cec5SDimitry Andric //   "Two pointers of the same type compare equal if and only if they are both
27000b57cec5SDimitry Andric //    null, both point to the same function, or both represent the same
27010b57cec5SDimitry Andric //    address."
27020b57cec5SDimitry Andric //
27030b57cec5SDimitry Andric // This is pretty permissive.
27040b57cec5SDimitry Andric //
27050b57cec5SDimitry Andric // It's also partly due to C11 6.5.9p6:
27060b57cec5SDimitry Andric //   "Two pointers compare equal if and only if both are null pointers, both are
27070b57cec5SDimitry Andric //    pointers to the same object (including a pointer to an object and a
27080b57cec5SDimitry Andric //    subobject at its beginning) or function, both are pointers to one past the
27090b57cec5SDimitry Andric //    last element of the same array object, or one is a pointer to one past the
27100b57cec5SDimitry Andric //    end of one array object and the other is a pointer to the start of a
27110b57cec5SDimitry Andric //    different array object that happens to immediately follow the first array
27120b57cec5SDimitry Andric //    object in the address space.)
27130b57cec5SDimitry Andric //
27140b57cec5SDimitry Andric // C11's version is more restrictive, however there's no reason why an argument
27150b57cec5SDimitry Andric // couldn't be a one-past-the-end value for a stack object in the caller and be
27160b57cec5SDimitry Andric // equal to the beginning of a stack object in the callee.
27170b57cec5SDimitry Andric //
27180b57cec5SDimitry Andric // If the C and C++ standards are ever made sufficiently restrictive in this
27190b57cec5SDimitry Andric // area, it may be possible to update LLVM's semantics accordingly and reinstate
27200b57cec5SDimitry Andric // this optimization.
272181ad6265SDimitry Andric static Constant *computePointerICmp(CmpInst::Predicate Pred, Value *LHS,
272281ad6265SDimitry Andric                                     Value *RHS, const SimplifyQuery &Q) {
272306c3fb27SDimitry Andric   assert(LHS->getType() == RHS->getType() && "Must have same types");
2724fe6060f1SDimitry Andric   const DataLayout &DL = Q.DL;
2725fe6060f1SDimitry Andric   const TargetLibraryInfo *TLI = Q.TLI;
27260b57cec5SDimitry Andric 
27270b57cec5SDimitry Andric   // We can only fold certain predicates on pointer comparisons.
27280b57cec5SDimitry Andric   switch (Pred) {
27290b57cec5SDimitry Andric   default:
27300b57cec5SDimitry Andric     return nullptr;
27310b57cec5SDimitry Andric 
2732bdd1243dSDimitry Andric     // Equality comparisons are easy to fold.
27330b57cec5SDimitry Andric   case CmpInst::ICMP_EQ:
27340b57cec5SDimitry Andric   case CmpInst::ICMP_NE:
27350b57cec5SDimitry Andric     break;
27360b57cec5SDimitry Andric 
27370b57cec5SDimitry Andric     // We can only handle unsigned relational comparisons because 'inbounds' on
27380b57cec5SDimitry Andric     // a GEP only protects against unsigned wrapping.
27390b57cec5SDimitry Andric   case CmpInst::ICMP_UGT:
27400b57cec5SDimitry Andric   case CmpInst::ICMP_UGE:
27410b57cec5SDimitry Andric   case CmpInst::ICMP_ULT:
27420b57cec5SDimitry Andric   case CmpInst::ICMP_ULE:
27430b57cec5SDimitry Andric     // However, we have to switch them to their signed variants to handle
27440b57cec5SDimitry Andric     // negative indices from the base pointer.
27450b57cec5SDimitry Andric     Pred = ICmpInst::getSignedPredicate(Pred);
27460b57cec5SDimitry Andric     break;
27470b57cec5SDimitry Andric   }
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric   // Strip off any constant offsets so that we can reason about them.
27500b57cec5SDimitry Andric   // It's tempting to use getUnderlyingObject or even just stripInBoundsOffsets
27510b57cec5SDimitry Andric   // here and compare base addresses like AliasAnalysis does, however there are
27520b57cec5SDimitry Andric   // numerous hazards. AliasAnalysis and its utilities rely on special rules
27530b57cec5SDimitry Andric   // governing loads and stores which don't apply to icmps. Also, AliasAnalysis
27540b57cec5SDimitry Andric   // doesn't need to guarantee pointer inequality when it says NoAlias.
2755d781ede6SDimitry Andric 
2756d781ede6SDimitry Andric   // Even if an non-inbounds GEP occurs along the path we can still optimize
2757d781ede6SDimitry Andric   // equality comparisons concerning the result.
2758d781ede6SDimitry Andric   bool AllowNonInbounds = ICmpInst::isEquality(Pred);
275906c3fb27SDimitry Andric   unsigned IndexSize = DL.getIndexTypeSizeInBits(LHS->getType());
276006c3fb27SDimitry Andric   APInt LHSOffset(IndexSize, 0), RHSOffset(IndexSize, 0);
276106c3fb27SDimitry Andric   LHS = LHS->stripAndAccumulateConstantOffsets(DL, LHSOffset, AllowNonInbounds);
276206c3fb27SDimitry Andric   RHS = RHS->stripAndAccumulateConstantOffsets(DL, RHSOffset, AllowNonInbounds);
27630b57cec5SDimitry Andric 
27640b57cec5SDimitry Andric   // If LHS and RHS are related via constant offsets to the same base
27650b57cec5SDimitry Andric   // value, we can replace it with an icmp which just compares the offsets.
27660b57cec5SDimitry Andric   if (LHS == RHS)
276781ad6265SDimitry Andric     return ConstantInt::get(getCompareTy(LHS),
276881ad6265SDimitry Andric                             ICmpInst::compare(LHSOffset, RHSOffset, Pred));
27690b57cec5SDimitry Andric 
27700b57cec5SDimitry Andric   // Various optimizations for (in)equality comparisons.
27710b57cec5SDimitry Andric   if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) {
27720b57cec5SDimitry Andric     // Different non-empty allocations that exist at the same time have
277381ad6265SDimitry Andric     // different addresses (if the program can tell). If the offsets are
277481ad6265SDimitry Andric     // within the bounds of their allocations (and not one-past-the-end!
277581ad6265SDimitry Andric     // so we can't use inbounds!), and their allocations aren't the same,
277681ad6265SDimitry Andric     // the pointers are not equal.
277781ad6265SDimitry Andric     if (haveNonOverlappingStorage(LHS, RHS)) {
27780b57cec5SDimitry Andric       uint64_t LHSSize, RHSSize;
27790b57cec5SDimitry Andric       ObjectSizeOpts Opts;
278081ad6265SDimitry Andric       Opts.EvalMode = ObjectSizeOpts::Mode::Min;
278181ad6265SDimitry Andric       auto *F = [](Value *V) -> Function * {
278281ad6265SDimitry Andric         if (auto *I = dyn_cast<Instruction>(V))
278381ad6265SDimitry Andric           return I->getFunction();
278481ad6265SDimitry Andric         if (auto *A = dyn_cast<Argument>(V))
278581ad6265SDimitry Andric           return A->getParent();
278681ad6265SDimitry Andric         return nullptr;
278781ad6265SDimitry Andric       }(LHS);
278881ad6265SDimitry Andric       Opts.NullIsUnknownSize = F ? NullPointerIsDefined(F) : true;
278981ad6265SDimitry Andric       if (getObjectSize(LHS, LHSSize, DL, TLI, Opts) &&
279006c3fb27SDimitry Andric           getObjectSize(RHS, RHSSize, DL, TLI, Opts)) {
279106c3fb27SDimitry Andric         APInt Dist = LHSOffset - RHSOffset;
279206c3fb27SDimitry Andric         if (Dist.isNonNegative() ? Dist.ult(LHSSize) : (-Dist).ult(RHSSize))
279381ad6265SDimitry Andric           return ConstantInt::get(getCompareTy(LHS),
27940b57cec5SDimitry Andric                                   !CmpInst::isTrueWhenEqual(Pred));
27950b57cec5SDimitry Andric       }
27960b57cec5SDimitry Andric     }
27970b57cec5SDimitry Andric 
27980b57cec5SDimitry Andric     // If one side of the equality comparison must come from a noalias call
27990b57cec5SDimitry Andric     // (meaning a system memory allocation function), and the other side must
28000b57cec5SDimitry Andric     // come from a pointer that cannot overlap with dynamically-allocated
28010b57cec5SDimitry Andric     // memory within the lifetime of the current function (allocas, byval
28020b57cec5SDimitry Andric     // arguments, globals), then determine the comparison result here.
28030b57cec5SDimitry Andric     SmallVector<const Value *, 8> LHSUObjs, RHSUObjs;
2804e8d8bef9SDimitry Andric     getUnderlyingObjects(LHS, LHSUObjs);
2805e8d8bef9SDimitry Andric     getUnderlyingObjects(RHS, RHSUObjs);
28060b57cec5SDimitry Andric 
28070b57cec5SDimitry Andric     // Is the set of underlying objects all noalias calls?
28080b57cec5SDimitry Andric     auto IsNAC = [](ArrayRef<const Value *> Objects) {
28090b57cec5SDimitry Andric       return all_of(Objects, isNoAliasCall);
28100b57cec5SDimitry Andric     };
28110b57cec5SDimitry Andric 
28120b57cec5SDimitry Andric     // Is the set of underlying objects all things which must be disjoint from
281381ad6265SDimitry Andric     // noalias calls.  We assume that indexing from such disjoint storage
281481ad6265SDimitry Andric     // into the heap is undefined, and thus offsets can be safely ignored.
28150b57cec5SDimitry Andric     auto IsAllocDisjoint = [](ArrayRef<const Value *> Objects) {
281681ad6265SDimitry Andric       return all_of(Objects, ::isAllocDisjoint);
28170b57cec5SDimitry Andric     };
28180b57cec5SDimitry Andric 
28190b57cec5SDimitry Andric     if ((IsNAC(LHSUObjs) && IsAllocDisjoint(RHSUObjs)) ||
28200b57cec5SDimitry Andric         (IsNAC(RHSUObjs) && IsAllocDisjoint(LHSUObjs)))
282181ad6265SDimitry Andric       return ConstantInt::get(getCompareTy(LHS),
28220b57cec5SDimitry Andric                               !CmpInst::isTrueWhenEqual(Pred));
28230b57cec5SDimitry Andric 
28240b57cec5SDimitry Andric     // Fold comparisons for non-escaping pointer even if the allocation call
28250b57cec5SDimitry Andric     // cannot be elided. We cannot fold malloc comparison to null. Also, the
282604eeddc0SDimitry Andric     // dynamic allocation call could be either of the operands.  Note that
282704eeddc0SDimitry Andric     // the other operand can not be based on the alloc - if it were, then
282804eeddc0SDimitry Andric     // the cmp itself would be a capture.
28290b57cec5SDimitry Andric     Value *MI = nullptr;
2830*0fca6ea1SDimitry Andric     if (isAllocLikeFn(LHS, TLI) && llvm::isKnownNonZero(RHS, Q))
28310b57cec5SDimitry Andric       MI = LHS;
2832*0fca6ea1SDimitry Andric     else if (isAllocLikeFn(RHS, TLI) && llvm::isKnownNonZero(LHS, Q))
28330b57cec5SDimitry Andric       MI = RHS;
283406c3fb27SDimitry Andric     if (MI) {
283506c3fb27SDimitry Andric       // FIXME: This is incorrect, see PR54002. While we can assume that the
283606c3fb27SDimitry Andric       // allocation is at an address that makes the comparison false, this
283706c3fb27SDimitry Andric       // requires that *all* comparisons to that address be false, which
283806c3fb27SDimitry Andric       // InstSimplify cannot guarantee.
283906c3fb27SDimitry Andric       struct CustomCaptureTracker : public CaptureTracker {
284006c3fb27SDimitry Andric         bool Captured = false;
284106c3fb27SDimitry Andric         void tooManyUses() override { Captured = true; }
284206c3fb27SDimitry Andric         bool captured(const Use *U) override {
284306c3fb27SDimitry Andric           if (auto *ICmp = dyn_cast<ICmpInst>(U->getUser())) {
284406c3fb27SDimitry Andric             // Comparison against value stored in global variable. Given the
284506c3fb27SDimitry Andric             // pointer does not escape, its value cannot be guessed and stored
284606c3fb27SDimitry Andric             // separately in a global variable.
284706c3fb27SDimitry Andric             unsigned OtherIdx = 1 - U->getOperandNo();
284806c3fb27SDimitry Andric             auto *LI = dyn_cast<LoadInst>(ICmp->getOperand(OtherIdx));
284906c3fb27SDimitry Andric             if (LI && isa<GlobalVariable>(LI->getPointerOperand()))
285006c3fb27SDimitry Andric               return false;
285106c3fb27SDimitry Andric           }
285206c3fb27SDimitry Andric 
285306c3fb27SDimitry Andric           Captured = true;
285406c3fb27SDimitry Andric           return true;
285506c3fb27SDimitry Andric         }
285606c3fb27SDimitry Andric       };
285706c3fb27SDimitry Andric       CustomCaptureTracker Tracker;
285806c3fb27SDimitry Andric       PointerMayBeCaptured(MI, &Tracker);
285906c3fb27SDimitry Andric       if (!Tracker.Captured)
286081ad6265SDimitry Andric         return ConstantInt::get(getCompareTy(LHS),
28610b57cec5SDimitry Andric                                 CmpInst::isFalseWhenEqual(Pred));
28620b57cec5SDimitry Andric     }
286306c3fb27SDimitry Andric   }
28640b57cec5SDimitry Andric 
28650b57cec5SDimitry Andric   // Otherwise, fail.
28660b57cec5SDimitry Andric   return nullptr;
28670b57cec5SDimitry Andric }
28680b57cec5SDimitry Andric 
28690b57cec5SDimitry Andric /// Fold an icmp when its operands have i1 scalar type.
28700b57cec5SDimitry Andric static Value *simplifyICmpOfBools(CmpInst::Predicate Pred, Value *LHS,
28710b57cec5SDimitry Andric                                   Value *RHS, const SimplifyQuery &Q) {
287281ad6265SDimitry Andric   Type *ITy = getCompareTy(LHS); // The return type.
28730b57cec5SDimitry Andric   Type *OpTy = LHS->getType();   // The operand type.
28740b57cec5SDimitry Andric   if (!OpTy->isIntOrIntVectorTy(1))
28750b57cec5SDimitry Andric     return nullptr;
28760b57cec5SDimitry Andric 
28770eae32dcSDimitry Andric   // A boolean compared to true/false can be reduced in 14 out of the 20
28780eae32dcSDimitry Andric   // (10 predicates * 2 constants) possible combinations. The other
28790eae32dcSDimitry Andric   // 6 cases require a 'not' of the LHS.
28800eae32dcSDimitry Andric 
28810eae32dcSDimitry Andric   auto ExtractNotLHS = [](Value *V) -> Value * {
28820eae32dcSDimitry Andric     Value *X;
28830eae32dcSDimitry Andric     if (match(V, m_Not(m_Value(X))))
28840eae32dcSDimitry Andric       return X;
28850eae32dcSDimitry Andric     return nullptr;
28860eae32dcSDimitry Andric   };
28870eae32dcSDimitry Andric 
28880b57cec5SDimitry Andric   if (match(RHS, m_Zero())) {
28890b57cec5SDimitry Andric     switch (Pred) {
28900b57cec5SDimitry Andric     case CmpInst::ICMP_NE:  // X !=  0 -> X
28910b57cec5SDimitry Andric     case CmpInst::ICMP_UGT: // X >u  0 -> X
28920b57cec5SDimitry Andric     case CmpInst::ICMP_SLT: // X <s  0 -> X
28930b57cec5SDimitry Andric       return LHS;
28940b57cec5SDimitry Andric 
28950eae32dcSDimitry Andric     case CmpInst::ICMP_EQ:  // not(X) ==  0 -> X != 0 -> X
28960eae32dcSDimitry Andric     case CmpInst::ICMP_ULE: // not(X) <=u 0 -> X >u 0 -> X
28970eae32dcSDimitry Andric     case CmpInst::ICMP_SGE: // not(X) >=s 0 -> X <s 0 -> X
28980eae32dcSDimitry Andric       if (Value *X = ExtractNotLHS(LHS))
28990eae32dcSDimitry Andric         return X;
29000eae32dcSDimitry Andric       break;
29010eae32dcSDimitry Andric 
29020b57cec5SDimitry Andric     case CmpInst::ICMP_ULT: // X <u  0 -> false
29030b57cec5SDimitry Andric     case CmpInst::ICMP_SGT: // X >s  0 -> false
29040b57cec5SDimitry Andric       return getFalse(ITy);
29050b57cec5SDimitry Andric 
29060b57cec5SDimitry Andric     case CmpInst::ICMP_UGE: // X >=u 0 -> true
29070b57cec5SDimitry Andric     case CmpInst::ICMP_SLE: // X <=s 0 -> true
29080b57cec5SDimitry Andric       return getTrue(ITy);
29090b57cec5SDimitry Andric 
291081ad6265SDimitry Andric     default:
291181ad6265SDimitry Andric       break;
29120b57cec5SDimitry Andric     }
29130b57cec5SDimitry Andric   } else if (match(RHS, m_One())) {
29140b57cec5SDimitry Andric     switch (Pred) {
29150b57cec5SDimitry Andric     case CmpInst::ICMP_EQ:  // X ==   1 -> X
29160b57cec5SDimitry Andric     case CmpInst::ICMP_UGE: // X >=u  1 -> X
29170b57cec5SDimitry Andric     case CmpInst::ICMP_SLE: // X <=s -1 -> X
29180b57cec5SDimitry Andric       return LHS;
29190b57cec5SDimitry Andric 
29200eae32dcSDimitry Andric     case CmpInst::ICMP_NE:  // not(X) !=  1 -> X ==   1 -> X
29210eae32dcSDimitry Andric     case CmpInst::ICMP_ULT: // not(X) <=u 1 -> X >=u  1 -> X
29220eae32dcSDimitry Andric     case CmpInst::ICMP_SGT: // not(X) >s  1 -> X <=s -1 -> X
29230eae32dcSDimitry Andric       if (Value *X = ExtractNotLHS(LHS))
29240eae32dcSDimitry Andric         return X;
29250eae32dcSDimitry Andric       break;
29260eae32dcSDimitry Andric 
29270b57cec5SDimitry Andric     case CmpInst::ICMP_UGT: // X >u   1 -> false
29280b57cec5SDimitry Andric     case CmpInst::ICMP_SLT: // X <s  -1 -> false
29290b57cec5SDimitry Andric       return getFalse(ITy);
29300b57cec5SDimitry Andric 
29310b57cec5SDimitry Andric     case CmpInst::ICMP_ULE: // X <=u  1 -> true
29320b57cec5SDimitry Andric     case CmpInst::ICMP_SGE: // X >=s -1 -> true
29330b57cec5SDimitry Andric       return getTrue(ITy);
29340b57cec5SDimitry Andric 
293581ad6265SDimitry Andric     default:
293681ad6265SDimitry Andric       break;
29370b57cec5SDimitry Andric     }
29380b57cec5SDimitry Andric   }
29390b57cec5SDimitry Andric 
29400b57cec5SDimitry Andric   switch (Pred) {
29410b57cec5SDimitry Andric   default:
29420b57cec5SDimitry Andric     break;
29430b57cec5SDimitry Andric   case ICmpInst::ICMP_UGE:
294481ad6265SDimitry Andric     if (isImpliedCondition(RHS, LHS, Q.DL).value_or(false))
29450b57cec5SDimitry Andric       return getTrue(ITy);
29460b57cec5SDimitry Andric     break;
29470b57cec5SDimitry Andric   case ICmpInst::ICMP_SGE:
29480b57cec5SDimitry Andric     /// For signed comparison, the values for an i1 are 0 and -1
29490b57cec5SDimitry Andric     /// respectively. This maps into a truth table of:
29500b57cec5SDimitry Andric     /// LHS | RHS | LHS >=s RHS   | LHS implies RHS
29510b57cec5SDimitry Andric     ///  0  |  0  |  1 (0 >= 0)   |  1
29520b57cec5SDimitry Andric     ///  0  |  1  |  1 (0 >= -1)  |  1
29530b57cec5SDimitry Andric     ///  1  |  0  |  0 (-1 >= 0)  |  0
29540b57cec5SDimitry Andric     ///  1  |  1  |  1 (-1 >= -1) |  1
295581ad6265SDimitry Andric     if (isImpliedCondition(LHS, RHS, Q.DL).value_or(false))
29560b57cec5SDimitry Andric       return getTrue(ITy);
29570b57cec5SDimitry Andric     break;
29580b57cec5SDimitry Andric   case ICmpInst::ICMP_ULE:
295981ad6265SDimitry Andric     if (isImpliedCondition(LHS, RHS, Q.DL).value_or(false))
29600b57cec5SDimitry Andric       return getTrue(ITy);
29610b57cec5SDimitry Andric     break;
2962bdd1243dSDimitry Andric   case ICmpInst::ICMP_SLE:
2963bdd1243dSDimitry Andric     /// SLE follows the same logic as SGE with the LHS and RHS swapped.
2964bdd1243dSDimitry Andric     if (isImpliedCondition(RHS, LHS, Q.DL).value_or(false))
2965bdd1243dSDimitry Andric       return getTrue(ITy);
2966bdd1243dSDimitry Andric     break;
29670b57cec5SDimitry Andric   }
29680b57cec5SDimitry Andric 
29690b57cec5SDimitry Andric   return nullptr;
29700b57cec5SDimitry Andric }
29710b57cec5SDimitry Andric 
29720b57cec5SDimitry Andric /// Try hard to fold icmp with zero RHS because this is a common case.
29730b57cec5SDimitry Andric static Value *simplifyICmpWithZero(CmpInst::Predicate Pred, Value *LHS,
29740b57cec5SDimitry Andric                                    Value *RHS, const SimplifyQuery &Q) {
29750b57cec5SDimitry Andric   if (!match(RHS, m_Zero()))
29760b57cec5SDimitry Andric     return nullptr;
29770b57cec5SDimitry Andric 
297881ad6265SDimitry Andric   Type *ITy = getCompareTy(LHS); // The return type.
29790b57cec5SDimitry Andric   switch (Pred) {
29800b57cec5SDimitry Andric   default:
29810b57cec5SDimitry Andric     llvm_unreachable("Unknown ICmp predicate!");
29820b57cec5SDimitry Andric   case ICmpInst::ICMP_ULT:
29830b57cec5SDimitry Andric     return getFalse(ITy);
29840b57cec5SDimitry Andric   case ICmpInst::ICMP_UGE:
29850b57cec5SDimitry Andric     return getTrue(ITy);
29860b57cec5SDimitry Andric   case ICmpInst::ICMP_EQ:
29870b57cec5SDimitry Andric   case ICmpInst::ICMP_ULE:
2988*0fca6ea1SDimitry Andric     if (isKnownNonZero(LHS, Q))
29890b57cec5SDimitry Andric       return getFalse(ITy);
29900b57cec5SDimitry Andric     break;
29910b57cec5SDimitry Andric   case ICmpInst::ICMP_NE:
29920b57cec5SDimitry Andric   case ICmpInst::ICMP_UGT:
2993*0fca6ea1SDimitry Andric     if (isKnownNonZero(LHS, Q))
29940b57cec5SDimitry Andric       return getTrue(ITy);
29950b57cec5SDimitry Andric     break;
29960b57cec5SDimitry Andric   case ICmpInst::ICMP_SLT: {
29975f757f3fSDimitry Andric     KnownBits LHSKnown = computeKnownBits(LHS, /* Depth */ 0, Q);
29980b57cec5SDimitry Andric     if (LHSKnown.isNegative())
29990b57cec5SDimitry Andric       return getTrue(ITy);
30000b57cec5SDimitry Andric     if (LHSKnown.isNonNegative())
30010b57cec5SDimitry Andric       return getFalse(ITy);
30020b57cec5SDimitry Andric     break;
30030b57cec5SDimitry Andric   }
30040b57cec5SDimitry Andric   case ICmpInst::ICMP_SLE: {
30055f757f3fSDimitry Andric     KnownBits LHSKnown = computeKnownBits(LHS, /* Depth */ 0, Q);
30060b57cec5SDimitry Andric     if (LHSKnown.isNegative())
30070b57cec5SDimitry Andric       return getTrue(ITy);
3008*0fca6ea1SDimitry Andric     if (LHSKnown.isNonNegative() && isKnownNonZero(LHS, Q))
30090b57cec5SDimitry Andric       return getFalse(ITy);
30100b57cec5SDimitry Andric     break;
30110b57cec5SDimitry Andric   }
30120b57cec5SDimitry Andric   case ICmpInst::ICMP_SGE: {
30135f757f3fSDimitry Andric     KnownBits LHSKnown = computeKnownBits(LHS, /* Depth */ 0, Q);
30140b57cec5SDimitry Andric     if (LHSKnown.isNegative())
30150b57cec5SDimitry Andric       return getFalse(ITy);
30160b57cec5SDimitry Andric     if (LHSKnown.isNonNegative())
30170b57cec5SDimitry Andric       return getTrue(ITy);
30180b57cec5SDimitry Andric     break;
30190b57cec5SDimitry Andric   }
30200b57cec5SDimitry Andric   case ICmpInst::ICMP_SGT: {
30215f757f3fSDimitry Andric     KnownBits LHSKnown = computeKnownBits(LHS, /* Depth */ 0, Q);
30220b57cec5SDimitry Andric     if (LHSKnown.isNegative())
30230b57cec5SDimitry Andric       return getFalse(ITy);
3024*0fca6ea1SDimitry Andric     if (LHSKnown.isNonNegative() && isKnownNonZero(LHS, Q))
30250b57cec5SDimitry Andric       return getTrue(ITy);
30260b57cec5SDimitry Andric     break;
30270b57cec5SDimitry Andric   }
30280b57cec5SDimitry Andric   }
30290b57cec5SDimitry Andric 
30300b57cec5SDimitry Andric   return nullptr;
30310b57cec5SDimitry Andric }
30320b57cec5SDimitry Andric 
30330b57cec5SDimitry Andric static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
30340b57cec5SDimitry Andric                                        Value *RHS, const InstrInfoQuery &IIQ) {
303581ad6265SDimitry Andric   Type *ITy = getCompareTy(RHS); // The return type.
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric   Value *X;
3038*0fca6ea1SDimitry Andric   const APInt *C;
3039*0fca6ea1SDimitry Andric   if (!match(RHS, m_APIntAllowPoison(C)))
3040*0fca6ea1SDimitry Andric     return nullptr;
3041*0fca6ea1SDimitry Andric 
30420b57cec5SDimitry Andric   // Sign-bit checks can be optimized to true/false after unsigned
30430b57cec5SDimitry Andric   // floating-point casts:
30440b57cec5SDimitry Andric   // icmp slt (bitcast (uitofp X)),  0 --> false
30450b57cec5SDimitry Andric   // icmp sgt (bitcast (uitofp X)), -1 --> true
3046*0fca6ea1SDimitry Andric   if (match(LHS, m_ElementWiseBitCast(m_UIToFP(m_Value(X))))) {
3047*0fca6ea1SDimitry Andric     bool TrueIfSigned;
3048*0fca6ea1SDimitry Andric     if (isSignBitCheck(Pred, *C, TrueIfSigned))
3049*0fca6ea1SDimitry Andric       return ConstantInt::getBool(ITy, !TrueIfSigned);
30500b57cec5SDimitry Andric   }
30510b57cec5SDimitry Andric 
30520b57cec5SDimitry Andric   // Rule out tautological comparisons (eg., ult 0 or uge 0).
30530b57cec5SDimitry Andric   ConstantRange RHS_CR = ConstantRange::makeExactICmpRegion(Pred, *C);
30540b57cec5SDimitry Andric   if (RHS_CR.isEmptySet())
30550b57cec5SDimitry Andric     return ConstantInt::getFalse(ITy);
30560b57cec5SDimitry Andric   if (RHS_CR.isFullSet())
30570b57cec5SDimitry Andric     return ConstantInt::getTrue(ITy);
30580b57cec5SDimitry Andric 
305904eeddc0SDimitry Andric   ConstantRange LHS_CR =
306004eeddc0SDimitry Andric       computeConstantRange(LHS, CmpInst::isSigned(Pred), IIQ.UseInstrInfo);
30610b57cec5SDimitry Andric   if (!LHS_CR.isFullSet()) {
30620b57cec5SDimitry Andric     if (RHS_CR.contains(LHS_CR))
30630b57cec5SDimitry Andric       return ConstantInt::getTrue(ITy);
30640b57cec5SDimitry Andric     if (RHS_CR.inverse().contains(LHS_CR))
30650b57cec5SDimitry Andric       return ConstantInt::getFalse(ITy);
30660b57cec5SDimitry Andric   }
30670b57cec5SDimitry Andric 
3068e8d8bef9SDimitry Andric   // (mul nuw/nsw X, MulC) != C --> true  (if C is not a multiple of MulC)
3069e8d8bef9SDimitry Andric   // (mul nuw/nsw X, MulC) == C --> false (if C is not a multiple of MulC)
3070e8d8bef9SDimitry Andric   const APInt *MulC;
30715f757f3fSDimitry Andric   if (IIQ.UseInstrInfo && ICmpInst::isEquality(Pred) &&
3072*0fca6ea1SDimitry Andric       ((match(LHS, m_NUWMul(m_Value(), m_APIntAllowPoison(MulC))) &&
3073e8d8bef9SDimitry Andric         *MulC != 0 && C->urem(*MulC) != 0) ||
3074*0fca6ea1SDimitry Andric        (match(LHS, m_NSWMul(m_Value(), m_APIntAllowPoison(MulC))) &&
3075e8d8bef9SDimitry Andric         *MulC != 0 && C->srem(*MulC) != 0)))
3076e8d8bef9SDimitry Andric     return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
3077e8d8bef9SDimitry Andric 
30780b57cec5SDimitry Andric   return nullptr;
30790b57cec5SDimitry Andric }
30800b57cec5SDimitry Andric 
308181ad6265SDimitry Andric static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
308281ad6265SDimitry Andric                                          BinaryOperator *LBO, Value *RHS,
308381ad6265SDimitry Andric                                          const SimplifyQuery &Q,
308481ad6265SDimitry Andric                                          unsigned MaxRecurse) {
308581ad6265SDimitry Andric   Type *ITy = getCompareTy(RHS); // The return type.
3086e8d8bef9SDimitry Andric 
3087e8d8bef9SDimitry Andric   Value *Y = nullptr;
3088e8d8bef9SDimitry Andric   // icmp pred (or X, Y), X
3089e8d8bef9SDimitry Andric   if (match(LBO, m_c_Or(m_Value(Y), m_Specific(RHS)))) {
3090e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_ULT)
3091e8d8bef9SDimitry Andric       return getFalse(ITy);
3092e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_UGE)
3093e8d8bef9SDimitry Andric       return getTrue(ITy);
3094e8d8bef9SDimitry Andric 
3095e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {
30965f757f3fSDimitry Andric       KnownBits RHSKnown = computeKnownBits(RHS, /* Depth */ 0, Q);
30975f757f3fSDimitry Andric       KnownBits YKnown = computeKnownBits(Y, /* Depth */ 0, Q);
3098e8d8bef9SDimitry Andric       if (RHSKnown.isNonNegative() && YKnown.isNegative())
3099e8d8bef9SDimitry Andric         return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy);
3100e8d8bef9SDimitry Andric       if (RHSKnown.isNegative() || YKnown.isNonNegative())
3101e8d8bef9SDimitry Andric         return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy);
3102e8d8bef9SDimitry Andric     }
3103e8d8bef9SDimitry Andric   }
3104e8d8bef9SDimitry Andric 
3105e8d8bef9SDimitry Andric   // icmp pred (and X, Y), X
3106e8d8bef9SDimitry Andric   if (match(LBO, m_c_And(m_Value(), m_Specific(RHS)))) {
3107e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_UGT)
3108e8d8bef9SDimitry Andric       return getFalse(ITy);
3109e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_ULE)
3110e8d8bef9SDimitry Andric       return getTrue(ITy);
3111e8d8bef9SDimitry Andric   }
3112e8d8bef9SDimitry Andric 
3113e8d8bef9SDimitry Andric   // icmp pred (urem X, Y), Y
3114e8d8bef9SDimitry Andric   if (match(LBO, m_URem(m_Value(), m_Specific(RHS)))) {
3115e8d8bef9SDimitry Andric     switch (Pred) {
3116e8d8bef9SDimitry Andric     default:
3117e8d8bef9SDimitry Andric       break;
3118e8d8bef9SDimitry Andric     case ICmpInst::ICMP_SGT:
3119e8d8bef9SDimitry Andric     case ICmpInst::ICMP_SGE: {
31205f757f3fSDimitry Andric       KnownBits Known = computeKnownBits(RHS, /* Depth */ 0, Q);
3121e8d8bef9SDimitry Andric       if (!Known.isNonNegative())
3122e8d8bef9SDimitry Andric         break;
3123bdd1243dSDimitry Andric       [[fallthrough]];
3124e8d8bef9SDimitry Andric     }
3125e8d8bef9SDimitry Andric     case ICmpInst::ICMP_EQ:
3126e8d8bef9SDimitry Andric     case ICmpInst::ICMP_UGT:
3127e8d8bef9SDimitry Andric     case ICmpInst::ICMP_UGE:
3128e8d8bef9SDimitry Andric       return getFalse(ITy);
3129e8d8bef9SDimitry Andric     case ICmpInst::ICMP_SLT:
3130e8d8bef9SDimitry Andric     case ICmpInst::ICMP_SLE: {
31315f757f3fSDimitry Andric       KnownBits Known = computeKnownBits(RHS, /* Depth */ 0, Q);
3132e8d8bef9SDimitry Andric       if (!Known.isNonNegative())
3133e8d8bef9SDimitry Andric         break;
3134bdd1243dSDimitry Andric       [[fallthrough]];
3135e8d8bef9SDimitry Andric     }
3136e8d8bef9SDimitry Andric     case ICmpInst::ICMP_NE:
3137e8d8bef9SDimitry Andric     case ICmpInst::ICMP_ULT:
3138e8d8bef9SDimitry Andric     case ICmpInst::ICMP_ULE:
3139e8d8bef9SDimitry Andric       return getTrue(ITy);
3140e8d8bef9SDimitry Andric     }
3141e8d8bef9SDimitry Andric   }
3142e8d8bef9SDimitry Andric 
3143e8d8bef9SDimitry Andric   // icmp pred (urem X, Y), X
3144e8d8bef9SDimitry Andric   if (match(LBO, m_URem(m_Specific(RHS), m_Value()))) {
3145e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_ULE)
3146e8d8bef9SDimitry Andric       return getTrue(ITy);
3147e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_UGT)
3148e8d8bef9SDimitry Andric       return getFalse(ITy);
3149e8d8bef9SDimitry Andric   }
3150e8d8bef9SDimitry Andric 
31514824e7fdSDimitry Andric   // x >>u y <=u x --> true.
31524824e7fdSDimitry Andric   // x >>u y >u  x --> false.
31534824e7fdSDimitry Andric   // x udiv y <=u x --> true.
31544824e7fdSDimitry Andric   // x udiv y >u  x --> false.
3155e8d8bef9SDimitry Andric   if (match(LBO, m_LShr(m_Specific(RHS), m_Value())) ||
3156e8d8bef9SDimitry Andric       match(LBO, m_UDiv(m_Specific(RHS), m_Value()))) {
3157e8d8bef9SDimitry Andric     // icmp pred (X op Y), X
3158e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_UGT)
3159e8d8bef9SDimitry Andric       return getFalse(ITy);
3160e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_ULE)
3161e8d8bef9SDimitry Andric       return getTrue(ITy);
3162e8d8bef9SDimitry Andric   }
3163e8d8bef9SDimitry Andric 
31644824e7fdSDimitry Andric   // If x is nonzero:
31654824e7fdSDimitry Andric   // x >>u C <u  x --> true  for C != 0.
31664824e7fdSDimitry Andric   // x >>u C !=  x --> true  for C != 0.
31674824e7fdSDimitry Andric   // x >>u C >=u x --> false for C != 0.
31684824e7fdSDimitry Andric   // x >>u C ==  x --> false for C != 0.
31694824e7fdSDimitry Andric   // x udiv C <u  x --> true  for C != 1.
31704824e7fdSDimitry Andric   // x udiv C !=  x --> true  for C != 1.
31714824e7fdSDimitry Andric   // x udiv C >=u x --> false for C != 1.
31724824e7fdSDimitry Andric   // x udiv C ==  x --> false for C != 1.
31734824e7fdSDimitry Andric   // TODO: allow non-constant shift amount/divisor
31744824e7fdSDimitry Andric   const APInt *C;
31754824e7fdSDimitry Andric   if ((match(LBO, m_LShr(m_Specific(RHS), m_APInt(C))) && *C != 0) ||
31764824e7fdSDimitry Andric       (match(LBO, m_UDiv(m_Specific(RHS), m_APInt(C))) && *C != 1)) {
3177*0fca6ea1SDimitry Andric     if (isKnownNonZero(RHS, Q)) {
31784824e7fdSDimitry Andric       switch (Pred) {
31794824e7fdSDimitry Andric       default:
31804824e7fdSDimitry Andric         break;
31814824e7fdSDimitry Andric       case ICmpInst::ICMP_EQ:
31824824e7fdSDimitry Andric       case ICmpInst::ICMP_UGE:
31834824e7fdSDimitry Andric         return getFalse(ITy);
31844824e7fdSDimitry Andric       case ICmpInst::ICMP_NE:
31854824e7fdSDimitry Andric       case ICmpInst::ICMP_ULT:
31864824e7fdSDimitry Andric         return getTrue(ITy);
31874824e7fdSDimitry Andric       case ICmpInst::ICMP_UGT:
31884824e7fdSDimitry Andric       case ICmpInst::ICMP_ULE:
31894824e7fdSDimitry Andric         // UGT/ULE are handled by the more general case just above
31904824e7fdSDimitry Andric         llvm_unreachable("Unexpected UGT/ULE, should have been handled");
31914824e7fdSDimitry Andric       }
31924824e7fdSDimitry Andric     }
31934824e7fdSDimitry Andric   }
31944824e7fdSDimitry Andric 
3195e8d8bef9SDimitry Andric   // (x*C1)/C2 <= x for C1 <= C2.
3196e8d8bef9SDimitry Andric   // This holds even if the multiplication overflows: Assume that x != 0 and
3197e8d8bef9SDimitry Andric   // arithmetic is modulo M. For overflow to occur we must have C1 >= M/x and
3198e8d8bef9SDimitry Andric   // thus C2 >= M/x. It follows that (x*C1)/C2 <= (M-1)/C2 <= ((M-1)*x)/M < x.
3199e8d8bef9SDimitry Andric   //
3200e8d8bef9SDimitry Andric   // Additionally, either the multiplication and division might be represented
3201e8d8bef9SDimitry Andric   // as shifts:
3202e8d8bef9SDimitry Andric   // (x*C1)>>C2 <= x for C1 < 2**C2.
3203e8d8bef9SDimitry Andric   // (x<<C1)/C2 <= x for 2**C1 < C2.
3204e8d8bef9SDimitry Andric   const APInt *C1, *C2;
3205e8d8bef9SDimitry Andric   if ((match(LBO, m_UDiv(m_Mul(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
3206e8d8bef9SDimitry Andric        C1->ule(*C2)) ||
3207e8d8bef9SDimitry Andric       (match(LBO, m_LShr(m_Mul(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
3208e8d8bef9SDimitry Andric        C1->ule(APInt(C2->getBitWidth(), 1) << *C2)) ||
3209e8d8bef9SDimitry Andric       (match(LBO, m_UDiv(m_Shl(m_Specific(RHS), m_APInt(C1)), m_APInt(C2))) &&
3210e8d8bef9SDimitry Andric        (APInt(C1->getBitWidth(), 1) << *C1).ule(*C2))) {
3211e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_UGT)
3212e8d8bef9SDimitry Andric       return getFalse(ITy);
3213e8d8bef9SDimitry Andric     if (Pred == ICmpInst::ICMP_ULE)
3214e8d8bef9SDimitry Andric       return getTrue(ITy);
3215e8d8bef9SDimitry Andric   }
3216e8d8bef9SDimitry Andric 
3217bdd1243dSDimitry Andric   // (sub C, X) == X, C is odd  --> false
3218bdd1243dSDimitry Andric   // (sub C, X) != X, C is odd  --> true
3219*0fca6ea1SDimitry Andric   if (match(LBO, m_Sub(m_APIntAllowPoison(C), m_Specific(RHS))) &&
3220bdd1243dSDimitry Andric       (*C & 1) == 1 && ICmpInst::isEquality(Pred))
3221bdd1243dSDimitry Andric     return (Pred == ICmpInst::ICMP_EQ) ? getFalse(ITy) : getTrue(ITy);
3222bdd1243dSDimitry Andric 
3223e8d8bef9SDimitry Andric   return nullptr;
3224e8d8bef9SDimitry Andric }
3225e8d8bef9SDimitry Andric 
3226e8d8bef9SDimitry Andric // If only one of the icmp's operands has NSW flags, try to prove that:
3227e8d8bef9SDimitry Andric //
3228e8d8bef9SDimitry Andric //   icmp slt (x + C1), (x +nsw C2)
3229e8d8bef9SDimitry Andric //
3230e8d8bef9SDimitry Andric // is equivalent to:
3231e8d8bef9SDimitry Andric //
3232e8d8bef9SDimitry Andric //   icmp slt C1, C2
3233e8d8bef9SDimitry Andric //
3234e8d8bef9SDimitry Andric // which is true if x + C2 has the NSW flags set and:
3235e8d8bef9SDimitry Andric // *) C1 < C2 && C1 >= 0, or
3236e8d8bef9SDimitry Andric // *) C2 < C1 && C1 <= 0.
3237e8d8bef9SDimitry Andric //
3238e8d8bef9SDimitry Andric static bool trySimplifyICmpWithAdds(CmpInst::Predicate Pred, Value *LHS,
32395f757f3fSDimitry Andric                                     Value *RHS, const InstrInfoQuery &IIQ) {
3240e8d8bef9SDimitry Andric   // TODO: only support icmp slt for now.
32415f757f3fSDimitry Andric   if (Pred != CmpInst::ICMP_SLT || !IIQ.UseInstrInfo)
3242e8d8bef9SDimitry Andric     return false;
3243e8d8bef9SDimitry Andric 
3244e8d8bef9SDimitry Andric   // Canonicalize nsw add as RHS.
3245e8d8bef9SDimitry Andric   if (!match(RHS, m_NSWAdd(m_Value(), m_Value())))
3246e8d8bef9SDimitry Andric     std::swap(LHS, RHS);
3247e8d8bef9SDimitry Andric   if (!match(RHS, m_NSWAdd(m_Value(), m_Value())))
3248e8d8bef9SDimitry Andric     return false;
3249e8d8bef9SDimitry Andric 
3250e8d8bef9SDimitry Andric   Value *X;
3251e8d8bef9SDimitry Andric   const APInt *C1, *C2;
3252*0fca6ea1SDimitry Andric   if (!match(LHS, m_Add(m_Value(X), m_APInt(C1))) ||
3253*0fca6ea1SDimitry Andric       !match(RHS, m_Add(m_Specific(X), m_APInt(C2))))
3254e8d8bef9SDimitry Andric     return false;
3255e8d8bef9SDimitry Andric 
3256e8d8bef9SDimitry Andric   return (C1->slt(*C2) && C1->isNonNegative()) ||
3257e8d8bef9SDimitry Andric          (C2->slt(*C1) && C1->isNonPositive());
3258e8d8bef9SDimitry Andric }
3259e8d8bef9SDimitry Andric 
32600b57cec5SDimitry Andric /// TODO: A large part of this logic is duplicated in InstCombine's
32610b57cec5SDimitry Andric /// foldICmpBinOp(). We should be able to share that and avoid the code
32620b57cec5SDimitry Andric /// duplication.
32630b57cec5SDimitry Andric static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
32640b57cec5SDimitry Andric                                     Value *RHS, const SimplifyQuery &Q,
32650b57cec5SDimitry Andric                                     unsigned MaxRecurse) {
32660b57cec5SDimitry Andric   BinaryOperator *LBO = dyn_cast<BinaryOperator>(LHS);
32670b57cec5SDimitry Andric   BinaryOperator *RBO = dyn_cast<BinaryOperator>(RHS);
32680b57cec5SDimitry Andric   if (MaxRecurse && (LBO || RBO)) {
32690b57cec5SDimitry Andric     // Analyze the case when either LHS or RHS is an add instruction.
32700b57cec5SDimitry Andric     Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr;
32710b57cec5SDimitry Andric     // LHS = A + B (or A and B are null); RHS = C + D (or C and D are null).
32720b57cec5SDimitry Andric     bool NoLHSWrapProblem = false, NoRHSWrapProblem = false;
32730b57cec5SDimitry Andric     if (LBO && LBO->getOpcode() == Instruction::Add) {
32740b57cec5SDimitry Andric       A = LBO->getOperand(0);
32750b57cec5SDimitry Andric       B = LBO->getOperand(1);
32760b57cec5SDimitry Andric       NoLHSWrapProblem =
32770b57cec5SDimitry Andric           ICmpInst::isEquality(Pred) ||
32780b57cec5SDimitry Andric           (CmpInst::isUnsigned(Pred) &&
32790b57cec5SDimitry Andric            Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(LBO))) ||
32800b57cec5SDimitry Andric           (CmpInst::isSigned(Pred) &&
32810b57cec5SDimitry Andric            Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(LBO)));
32820b57cec5SDimitry Andric     }
32830b57cec5SDimitry Andric     if (RBO && RBO->getOpcode() == Instruction::Add) {
32840b57cec5SDimitry Andric       C = RBO->getOperand(0);
32850b57cec5SDimitry Andric       D = RBO->getOperand(1);
32860b57cec5SDimitry Andric       NoRHSWrapProblem =
32870b57cec5SDimitry Andric           ICmpInst::isEquality(Pred) ||
32880b57cec5SDimitry Andric           (CmpInst::isUnsigned(Pred) &&
32890b57cec5SDimitry Andric            Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(RBO))) ||
32900b57cec5SDimitry Andric           (CmpInst::isSigned(Pred) &&
32910b57cec5SDimitry Andric            Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(RBO)));
32920b57cec5SDimitry Andric     }
32930b57cec5SDimitry Andric 
32940b57cec5SDimitry Andric     // icmp (X+Y), X -> icmp Y, 0 for equalities or if there is no overflow.
32950b57cec5SDimitry Andric     if ((A == RHS || B == RHS) && NoLHSWrapProblem)
329681ad6265SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, A == RHS ? B : A,
32970b57cec5SDimitry Andric                                       Constant::getNullValue(RHS->getType()), Q,
32980b57cec5SDimitry Andric                                       MaxRecurse - 1))
32990b57cec5SDimitry Andric         return V;
33000b57cec5SDimitry Andric 
33010b57cec5SDimitry Andric     // icmp X, (X+Y) -> icmp 0, Y for equalities or if there is no overflow.
33020b57cec5SDimitry Andric     if ((C == LHS || D == LHS) && NoRHSWrapProblem)
33030b57cec5SDimitry Andric       if (Value *V =
330481ad6265SDimitry Andric               simplifyICmpInst(Pred, Constant::getNullValue(LHS->getType()),
33050b57cec5SDimitry Andric                                C == LHS ? D : C, Q, MaxRecurse - 1))
33060b57cec5SDimitry Andric         return V;
33070b57cec5SDimitry Andric 
33080b57cec5SDimitry Andric     // icmp (X+Y), (X+Z) -> icmp Y,Z for equalities or if there is no overflow.
3309e8d8bef9SDimitry Andric     bool CanSimplify = (NoLHSWrapProblem && NoRHSWrapProblem) ||
33105f757f3fSDimitry Andric                        trySimplifyICmpWithAdds(Pred, LHS, RHS, Q.IIQ);
3311e8d8bef9SDimitry Andric     if (A && C && (A == C || A == D || B == C || B == D) && CanSimplify) {
33120b57cec5SDimitry Andric       // Determine Y and Z in the form icmp (X+Y), (X+Z).
33130b57cec5SDimitry Andric       Value *Y, *Z;
33140b57cec5SDimitry Andric       if (A == C) {
33150b57cec5SDimitry Andric         // C + B == C + D  ->  B == D
33160b57cec5SDimitry Andric         Y = B;
33170b57cec5SDimitry Andric         Z = D;
33180b57cec5SDimitry Andric       } else if (A == D) {
33190b57cec5SDimitry Andric         // D + B == C + D  ->  B == C
33200b57cec5SDimitry Andric         Y = B;
33210b57cec5SDimitry Andric         Z = C;
33220b57cec5SDimitry Andric       } else if (B == C) {
33230b57cec5SDimitry Andric         // A + C == C + D  ->  A == D
33240b57cec5SDimitry Andric         Y = A;
33250b57cec5SDimitry Andric         Z = D;
33260b57cec5SDimitry Andric       } else {
33270b57cec5SDimitry Andric         assert(B == D);
33280b57cec5SDimitry Andric         // A + D == C + D  ->  A == C
33290b57cec5SDimitry Andric         Y = A;
33300b57cec5SDimitry Andric         Z = C;
33310b57cec5SDimitry Andric       }
333281ad6265SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, Y, Z, Q, MaxRecurse - 1))
33330b57cec5SDimitry Andric         return V;
33340b57cec5SDimitry Andric     }
33350b57cec5SDimitry Andric   }
33360b57cec5SDimitry Andric 
3337e8d8bef9SDimitry Andric   if (LBO)
3338e8d8bef9SDimitry Andric     if (Value *V = simplifyICmpWithBinOpOnLHS(Pred, LBO, RHS, Q, MaxRecurse))
3339e8d8bef9SDimitry Andric       return V;
33400b57cec5SDimitry Andric 
3341e8d8bef9SDimitry Andric   if (RBO)
3342e8d8bef9SDimitry Andric     if (Value *V = simplifyICmpWithBinOpOnLHS(
3343e8d8bef9SDimitry Andric             ICmpInst::getSwappedPredicate(Pred), RBO, LHS, Q, MaxRecurse))
3344e8d8bef9SDimitry Andric       return V;
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric   // 0 - (zext X) pred C
33470b57cec5SDimitry Andric   if (!CmpInst::isUnsigned(Pred) && match(LHS, m_Neg(m_ZExt(m_Value())))) {
3348e8d8bef9SDimitry Andric     const APInt *C;
3349e8d8bef9SDimitry Andric     if (match(RHS, m_APInt(C))) {
3350e8d8bef9SDimitry Andric       if (C->isStrictlyPositive()) {
3351e8d8bef9SDimitry Andric         if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_NE)
335281ad6265SDimitry Andric           return ConstantInt::getTrue(getCompareTy(RHS));
3353e8d8bef9SDimitry Andric         if (Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_EQ)
335481ad6265SDimitry Andric           return ConstantInt::getFalse(getCompareTy(RHS));
33550b57cec5SDimitry Andric       }
3356e8d8bef9SDimitry Andric       if (C->isNonNegative()) {
33570b57cec5SDimitry Andric         if (Pred == ICmpInst::ICMP_SLE)
335881ad6265SDimitry Andric           return ConstantInt::getTrue(getCompareTy(RHS));
33590b57cec5SDimitry Andric         if (Pred == ICmpInst::ICMP_SGT)
336081ad6265SDimitry Andric           return ConstantInt::getFalse(getCompareTy(RHS));
33610b57cec5SDimitry Andric       }
33620b57cec5SDimitry Andric     }
33630b57cec5SDimitry Andric   }
33640b57cec5SDimitry Andric 
3365e8d8bef9SDimitry Andric   //   If C2 is a power-of-2 and C is not:
3366e8d8bef9SDimitry Andric   //   (C2 << X) == C --> false
3367e8d8bef9SDimitry Andric   //   (C2 << X) != C --> true
3368e8d8bef9SDimitry Andric   const APInt *C;
3369e8d8bef9SDimitry Andric   if (match(LHS, m_Shl(m_Power2(), m_Value())) &&
3370*0fca6ea1SDimitry Andric       match(RHS, m_APIntAllowPoison(C)) && !C->isPowerOf2()) {
3371e8d8bef9SDimitry Andric     // C2 << X can equal zero in some circumstances.
3372e8d8bef9SDimitry Andric     // This simplification might be unsafe if C is zero.
33730b57cec5SDimitry Andric     //
33740b57cec5SDimitry Andric     // We know it is safe if:
3375e8d8bef9SDimitry Andric     // - The shift is nsw. We can't shift out the one bit.
3376e8d8bef9SDimitry Andric     // - The shift is nuw. We can't shift out the one bit.
3377e8d8bef9SDimitry Andric     // - C2 is one.
3378e8d8bef9SDimitry Andric     // - C isn't zero.
33790b57cec5SDimitry Andric     if (Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(LBO)) ||
33800b57cec5SDimitry Andric         Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(LBO)) ||
3381349cc55cSDimitry Andric         match(LHS, m_Shl(m_One(), m_Value())) || !C->isZero()) {
33820b57cec5SDimitry Andric       if (Pred == ICmpInst::ICMP_EQ)
338381ad6265SDimitry Andric         return ConstantInt::getFalse(getCompareTy(RHS));
33840b57cec5SDimitry Andric       if (Pred == ICmpInst::ICMP_NE)
338581ad6265SDimitry Andric         return ConstantInt::getTrue(getCompareTy(RHS));
33860b57cec5SDimitry Andric     }
33870b57cec5SDimitry Andric   }
3388e8d8bef9SDimitry Andric 
33895f757f3fSDimitry Andric   // If C is a power-of-2:
33905f757f3fSDimitry Andric   // (C << X)  >u 0x8000 --> false
33915f757f3fSDimitry Andric   // (C << X) <=u 0x8000 --> true
33925f757f3fSDimitry Andric   if (match(LHS, m_Shl(m_Power2(), m_Value())) && match(RHS, m_SignMask())) {
33930b57cec5SDimitry Andric     if (Pred == ICmpInst::ICMP_UGT)
339481ad6265SDimitry Andric       return ConstantInt::getFalse(getCompareTy(RHS));
33950b57cec5SDimitry Andric     if (Pred == ICmpInst::ICMP_ULE)
339681ad6265SDimitry Andric       return ConstantInt::getTrue(getCompareTy(RHS));
33970b57cec5SDimitry Andric   }
33980b57cec5SDimitry Andric 
339906c3fb27SDimitry Andric   if (!MaxRecurse || !LBO || !RBO || LBO->getOpcode() != RBO->getOpcode())
340006c3fb27SDimitry Andric     return nullptr;
340106c3fb27SDimitry Andric 
340206c3fb27SDimitry Andric   if (LBO->getOperand(0) == RBO->getOperand(0)) {
340306c3fb27SDimitry Andric     switch (LBO->getOpcode()) {
340406c3fb27SDimitry Andric     default:
340506c3fb27SDimitry Andric       break;
34065f757f3fSDimitry Andric     case Instruction::Shl: {
340706c3fb27SDimitry Andric       bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO);
340806c3fb27SDimitry Andric       bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO);
340906c3fb27SDimitry Andric       if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) ||
3410*0fca6ea1SDimitry Andric           !isKnownNonZero(LBO->getOperand(0), Q))
341106c3fb27SDimitry Andric         break;
341206c3fb27SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(1),
341306c3fb27SDimitry Andric                                       RBO->getOperand(1), Q, MaxRecurse - 1))
341406c3fb27SDimitry Andric         return V;
34155f757f3fSDimitry Andric       break;
34165f757f3fSDimitry Andric     }
34175f757f3fSDimitry Andric     // If C1 & C2 == C1, A = X and/or C1, B = X and/or C2:
34185f757f3fSDimitry Andric     // icmp ule A, B -> true
34195f757f3fSDimitry Andric     // icmp ugt A, B -> false
34205f757f3fSDimitry Andric     // icmp sle A, B -> true (C1 and C2 are the same sign)
34215f757f3fSDimitry Andric     // icmp sgt A, B -> false (C1 and C2 are the same sign)
34225f757f3fSDimitry Andric     case Instruction::And:
34235f757f3fSDimitry Andric     case Instruction::Or: {
34245f757f3fSDimitry Andric       const APInt *C1, *C2;
34255f757f3fSDimitry Andric       if (ICmpInst::isRelational(Pred) &&
34265f757f3fSDimitry Andric           match(LBO->getOperand(1), m_APInt(C1)) &&
34275f757f3fSDimitry Andric           match(RBO->getOperand(1), m_APInt(C2))) {
34285f757f3fSDimitry Andric         if (!C1->isSubsetOf(*C2)) {
34295f757f3fSDimitry Andric           std::swap(C1, C2);
34305f757f3fSDimitry Andric           Pred = ICmpInst::getSwappedPredicate(Pred);
34315f757f3fSDimitry Andric         }
34325f757f3fSDimitry Andric         if (C1->isSubsetOf(*C2)) {
34335f757f3fSDimitry Andric           if (Pred == ICmpInst::ICMP_ULE)
34345f757f3fSDimitry Andric             return ConstantInt::getTrue(getCompareTy(LHS));
34355f757f3fSDimitry Andric           if (Pred == ICmpInst::ICMP_UGT)
34365f757f3fSDimitry Andric             return ConstantInt::getFalse(getCompareTy(LHS));
34375f757f3fSDimitry Andric           if (C1->isNonNegative() == C2->isNonNegative()) {
34385f757f3fSDimitry Andric             if (Pred == ICmpInst::ICMP_SLE)
34395f757f3fSDimitry Andric               return ConstantInt::getTrue(getCompareTy(LHS));
34405f757f3fSDimitry Andric             if (Pred == ICmpInst::ICMP_SGT)
34415f757f3fSDimitry Andric               return ConstantInt::getFalse(getCompareTy(LHS));
34425f757f3fSDimitry Andric           }
34435f757f3fSDimitry Andric         }
34445f757f3fSDimitry Andric       }
34455f757f3fSDimitry Andric       break;
34465f757f3fSDimitry Andric     }
344706c3fb27SDimitry Andric     }
344806c3fb27SDimitry Andric   }
344906c3fb27SDimitry Andric 
345006c3fb27SDimitry Andric   if (LBO->getOperand(1) == RBO->getOperand(1)) {
34510b57cec5SDimitry Andric     switch (LBO->getOpcode()) {
34520b57cec5SDimitry Andric     default:
34530b57cec5SDimitry Andric       break;
34540b57cec5SDimitry Andric     case Instruction::UDiv:
34550b57cec5SDimitry Andric     case Instruction::LShr:
34560b57cec5SDimitry Andric       if (ICmpInst::isSigned(Pred) || !Q.IIQ.isExact(LBO) ||
34570b57cec5SDimitry Andric           !Q.IIQ.isExact(RBO))
34580b57cec5SDimitry Andric         break;
345981ad6265SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(0),
34600b57cec5SDimitry Andric                                       RBO->getOperand(0), Q, MaxRecurse - 1))
34610b57cec5SDimitry Andric         return V;
34620b57cec5SDimitry Andric       break;
34630b57cec5SDimitry Andric     case Instruction::SDiv:
34640b57cec5SDimitry Andric       if (!ICmpInst::isEquality(Pred) || !Q.IIQ.isExact(LBO) ||
34650b57cec5SDimitry Andric           !Q.IIQ.isExact(RBO))
34660b57cec5SDimitry Andric         break;
346781ad6265SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(0),
34680b57cec5SDimitry Andric                                       RBO->getOperand(0), Q, MaxRecurse - 1))
34690b57cec5SDimitry Andric         return V;
34700b57cec5SDimitry Andric       break;
34710b57cec5SDimitry Andric     case Instruction::AShr:
34720b57cec5SDimitry Andric       if (!Q.IIQ.isExact(LBO) || !Q.IIQ.isExact(RBO))
34730b57cec5SDimitry Andric         break;
347481ad6265SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(0),
34750b57cec5SDimitry Andric                                       RBO->getOperand(0), Q, MaxRecurse - 1))
34760b57cec5SDimitry Andric         return V;
34770b57cec5SDimitry Andric       break;
34780b57cec5SDimitry Andric     case Instruction::Shl: {
34790b57cec5SDimitry Andric       bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO);
34800b57cec5SDimitry Andric       bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO);
34810b57cec5SDimitry Andric       if (!NUW && !NSW)
34820b57cec5SDimitry Andric         break;
34830b57cec5SDimitry Andric       if (!NSW && ICmpInst::isSigned(Pred))
34840b57cec5SDimitry Andric         break;
348581ad6265SDimitry Andric       if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(0),
34860b57cec5SDimitry Andric                                       RBO->getOperand(0), Q, MaxRecurse - 1))
34870b57cec5SDimitry Andric         return V;
34880b57cec5SDimitry Andric       break;
34890b57cec5SDimitry Andric     }
34900b57cec5SDimitry Andric     }
34910b57cec5SDimitry Andric   }
34920b57cec5SDimitry Andric   return nullptr;
34930b57cec5SDimitry Andric }
34940b57cec5SDimitry Andric 
349581ad6265SDimitry Andric /// simplify integer comparisons where at least one operand of the compare
34960b57cec5SDimitry Andric /// matches an integer min/max idiom.
34970b57cec5SDimitry Andric static Value *simplifyICmpWithMinMax(CmpInst::Predicate Pred, Value *LHS,
34980b57cec5SDimitry Andric                                      Value *RHS, const SimplifyQuery &Q,
34990b57cec5SDimitry Andric                                      unsigned MaxRecurse) {
350081ad6265SDimitry Andric   Type *ITy = getCompareTy(LHS); // The return type.
35010b57cec5SDimitry Andric   Value *A, *B;
35020b57cec5SDimitry Andric   CmpInst::Predicate P = CmpInst::BAD_ICMP_PREDICATE;
35030b57cec5SDimitry Andric   CmpInst::Predicate EqP; // Chosen so that "A == max/min(A,B)" iff "A EqP B".
35040b57cec5SDimitry Andric 
35050b57cec5SDimitry Andric   // Signed variants on "max(a,b)>=a -> true".
35060b57cec5SDimitry Andric   if (match(LHS, m_SMax(m_Value(A), m_Value(B))) && (A == RHS || B == RHS)) {
35070b57cec5SDimitry Andric     if (A != RHS)
35080b57cec5SDimitry Andric       std::swap(A, B);       // smax(A, B) pred A.
35090b57cec5SDimitry Andric     EqP = CmpInst::ICMP_SGE; // "A == smax(A, B)" iff "A sge B".
35100b57cec5SDimitry Andric     // We analyze this as smax(A, B) pred A.
35110b57cec5SDimitry Andric     P = Pred;
35120b57cec5SDimitry Andric   } else if (match(RHS, m_SMax(m_Value(A), m_Value(B))) &&
35130b57cec5SDimitry Andric              (A == LHS || B == LHS)) {
35140b57cec5SDimitry Andric     if (A != LHS)
35150b57cec5SDimitry Andric       std::swap(A, B);       // A pred smax(A, B).
35160b57cec5SDimitry Andric     EqP = CmpInst::ICMP_SGE; // "A == smax(A, B)" iff "A sge B".
35170b57cec5SDimitry Andric     // We analyze this as smax(A, B) swapped-pred A.
35180b57cec5SDimitry Andric     P = CmpInst::getSwappedPredicate(Pred);
35190b57cec5SDimitry Andric   } else if (match(LHS, m_SMin(m_Value(A), m_Value(B))) &&
35200b57cec5SDimitry Andric              (A == RHS || B == RHS)) {
35210b57cec5SDimitry Andric     if (A != RHS)
35220b57cec5SDimitry Andric       std::swap(A, B);       // smin(A, B) pred A.
35230b57cec5SDimitry Andric     EqP = CmpInst::ICMP_SLE; // "A == smin(A, B)" iff "A sle B".
35240b57cec5SDimitry Andric     // We analyze this as smax(-A, -B) swapped-pred -A.
35250b57cec5SDimitry Andric     // Note that we do not need to actually form -A or -B thanks to EqP.
35260b57cec5SDimitry Andric     P = CmpInst::getSwappedPredicate(Pred);
35270b57cec5SDimitry Andric   } else if (match(RHS, m_SMin(m_Value(A), m_Value(B))) &&
35280b57cec5SDimitry Andric              (A == LHS || B == LHS)) {
35290b57cec5SDimitry Andric     if (A != LHS)
35300b57cec5SDimitry Andric       std::swap(A, B);       // A pred smin(A, B).
35310b57cec5SDimitry Andric     EqP = CmpInst::ICMP_SLE; // "A == smin(A, B)" iff "A sle B".
35320b57cec5SDimitry Andric     // We analyze this as smax(-A, -B) pred -A.
35330b57cec5SDimitry Andric     // Note that we do not need to actually form -A or -B thanks to EqP.
35340b57cec5SDimitry Andric     P = Pred;
35350b57cec5SDimitry Andric   }
35360b57cec5SDimitry Andric   if (P != CmpInst::BAD_ICMP_PREDICATE) {
35370b57cec5SDimitry Andric     // Cases correspond to "max(A, B) p A".
35380b57cec5SDimitry Andric     switch (P) {
35390b57cec5SDimitry Andric     default:
35400b57cec5SDimitry Andric       break;
35410b57cec5SDimitry Andric     case CmpInst::ICMP_EQ:
35420b57cec5SDimitry Andric     case CmpInst::ICMP_SLE:
35430b57cec5SDimitry Andric       // Equivalent to "A EqP B".  This may be the same as the condition tested
35440b57cec5SDimitry Andric       // in the max/min; if so, we can just return that.
354581ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(LHS, EqP, A, B))
35460b57cec5SDimitry Andric         return V;
354781ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(RHS, EqP, A, B))
35480b57cec5SDimitry Andric         return V;
35490b57cec5SDimitry Andric       // Otherwise, see if "A EqP B" simplifies.
35500b57cec5SDimitry Andric       if (MaxRecurse)
355181ad6265SDimitry Andric         if (Value *V = simplifyICmpInst(EqP, A, B, Q, MaxRecurse - 1))
35520b57cec5SDimitry Andric           return V;
35530b57cec5SDimitry Andric       break;
35540b57cec5SDimitry Andric     case CmpInst::ICMP_NE:
35550b57cec5SDimitry Andric     case CmpInst::ICMP_SGT: {
35560b57cec5SDimitry Andric       CmpInst::Predicate InvEqP = CmpInst::getInversePredicate(EqP);
35570b57cec5SDimitry Andric       // Equivalent to "A InvEqP B".  This may be the same as the condition
35580b57cec5SDimitry Andric       // tested in the max/min; if so, we can just return that.
355981ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(LHS, InvEqP, A, B))
35600b57cec5SDimitry Andric         return V;
356181ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(RHS, InvEqP, A, B))
35620b57cec5SDimitry Andric         return V;
35630b57cec5SDimitry Andric       // Otherwise, see if "A InvEqP B" simplifies.
35640b57cec5SDimitry Andric       if (MaxRecurse)
356581ad6265SDimitry Andric         if (Value *V = simplifyICmpInst(InvEqP, A, B, Q, MaxRecurse - 1))
35660b57cec5SDimitry Andric           return V;
35670b57cec5SDimitry Andric       break;
35680b57cec5SDimitry Andric     }
35690b57cec5SDimitry Andric     case CmpInst::ICMP_SGE:
35700b57cec5SDimitry Andric       // Always true.
35710b57cec5SDimitry Andric       return getTrue(ITy);
35720b57cec5SDimitry Andric     case CmpInst::ICMP_SLT:
35730b57cec5SDimitry Andric       // Always false.
35740b57cec5SDimitry Andric       return getFalse(ITy);
35750b57cec5SDimitry Andric     }
35760b57cec5SDimitry Andric   }
35770b57cec5SDimitry Andric 
35780b57cec5SDimitry Andric   // Unsigned variants on "max(a,b)>=a -> true".
35790b57cec5SDimitry Andric   P = CmpInst::BAD_ICMP_PREDICATE;
35800b57cec5SDimitry Andric   if (match(LHS, m_UMax(m_Value(A), m_Value(B))) && (A == RHS || B == RHS)) {
35810b57cec5SDimitry Andric     if (A != RHS)
35820b57cec5SDimitry Andric       std::swap(A, B);       // umax(A, B) pred A.
35830b57cec5SDimitry Andric     EqP = CmpInst::ICMP_UGE; // "A == umax(A, B)" iff "A uge B".
35840b57cec5SDimitry Andric     // We analyze this as umax(A, B) pred A.
35850b57cec5SDimitry Andric     P = Pred;
35860b57cec5SDimitry Andric   } else if (match(RHS, m_UMax(m_Value(A), m_Value(B))) &&
35870b57cec5SDimitry Andric              (A == LHS || B == LHS)) {
35880b57cec5SDimitry Andric     if (A != LHS)
35890b57cec5SDimitry Andric       std::swap(A, B);       // A pred umax(A, B).
35900b57cec5SDimitry Andric     EqP = CmpInst::ICMP_UGE; // "A == umax(A, B)" iff "A uge B".
35910b57cec5SDimitry Andric     // We analyze this as umax(A, B) swapped-pred A.
35920b57cec5SDimitry Andric     P = CmpInst::getSwappedPredicate(Pred);
35930b57cec5SDimitry Andric   } else if (match(LHS, m_UMin(m_Value(A), m_Value(B))) &&
35940b57cec5SDimitry Andric              (A == RHS || B == RHS)) {
35950b57cec5SDimitry Andric     if (A != RHS)
35960b57cec5SDimitry Andric       std::swap(A, B);       // umin(A, B) pred A.
35970b57cec5SDimitry Andric     EqP = CmpInst::ICMP_ULE; // "A == umin(A, B)" iff "A ule B".
35980b57cec5SDimitry Andric     // We analyze this as umax(-A, -B) swapped-pred -A.
35990b57cec5SDimitry Andric     // Note that we do not need to actually form -A or -B thanks to EqP.
36000b57cec5SDimitry Andric     P = CmpInst::getSwappedPredicate(Pred);
36010b57cec5SDimitry Andric   } else if (match(RHS, m_UMin(m_Value(A), m_Value(B))) &&
36020b57cec5SDimitry Andric              (A == LHS || B == LHS)) {
36030b57cec5SDimitry Andric     if (A != LHS)
36040b57cec5SDimitry Andric       std::swap(A, B);       // A pred umin(A, B).
36050b57cec5SDimitry Andric     EqP = CmpInst::ICMP_ULE; // "A == umin(A, B)" iff "A ule B".
36060b57cec5SDimitry Andric     // We analyze this as umax(-A, -B) pred -A.
36070b57cec5SDimitry Andric     // Note that we do not need to actually form -A or -B thanks to EqP.
36080b57cec5SDimitry Andric     P = Pred;
36090b57cec5SDimitry Andric   }
36100b57cec5SDimitry Andric   if (P != CmpInst::BAD_ICMP_PREDICATE) {
36110b57cec5SDimitry Andric     // Cases correspond to "max(A, B) p A".
36120b57cec5SDimitry Andric     switch (P) {
36130b57cec5SDimitry Andric     default:
36140b57cec5SDimitry Andric       break;
36150b57cec5SDimitry Andric     case CmpInst::ICMP_EQ:
36160b57cec5SDimitry Andric     case CmpInst::ICMP_ULE:
36170b57cec5SDimitry Andric       // Equivalent to "A EqP B".  This may be the same as the condition tested
36180b57cec5SDimitry Andric       // in the max/min; if so, we can just return that.
361981ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(LHS, EqP, A, B))
36200b57cec5SDimitry Andric         return V;
362181ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(RHS, EqP, A, B))
36220b57cec5SDimitry Andric         return V;
36230b57cec5SDimitry Andric       // Otherwise, see if "A EqP B" simplifies.
36240b57cec5SDimitry Andric       if (MaxRecurse)
362581ad6265SDimitry Andric         if (Value *V = simplifyICmpInst(EqP, A, B, Q, MaxRecurse - 1))
36260b57cec5SDimitry Andric           return V;
36270b57cec5SDimitry Andric       break;
36280b57cec5SDimitry Andric     case CmpInst::ICMP_NE:
36290b57cec5SDimitry Andric     case CmpInst::ICMP_UGT: {
36300b57cec5SDimitry Andric       CmpInst::Predicate InvEqP = CmpInst::getInversePredicate(EqP);
36310b57cec5SDimitry Andric       // Equivalent to "A InvEqP B".  This may be the same as the condition
36320b57cec5SDimitry Andric       // tested in the max/min; if so, we can just return that.
363381ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(LHS, InvEqP, A, B))
36340b57cec5SDimitry Andric         return V;
363581ad6265SDimitry Andric       if (Value *V = extractEquivalentCondition(RHS, InvEqP, A, B))
36360b57cec5SDimitry Andric         return V;
36370b57cec5SDimitry Andric       // Otherwise, see if "A InvEqP B" simplifies.
36380b57cec5SDimitry Andric       if (MaxRecurse)
363981ad6265SDimitry Andric         if (Value *V = simplifyICmpInst(InvEqP, A, B, Q, MaxRecurse - 1))
36400b57cec5SDimitry Andric           return V;
36410b57cec5SDimitry Andric       break;
36420b57cec5SDimitry Andric     }
36430b57cec5SDimitry Andric     case CmpInst::ICMP_UGE:
36440b57cec5SDimitry Andric       return getTrue(ITy);
36450b57cec5SDimitry Andric     case CmpInst::ICMP_ULT:
36460b57cec5SDimitry Andric       return getFalse(ITy);
36470b57cec5SDimitry Andric     }
36480b57cec5SDimitry Andric   }
36490b57cec5SDimitry Andric 
3650e8d8bef9SDimitry Andric   // Comparing 1 each of min/max with a common operand?
3651e8d8bef9SDimitry Andric   // Canonicalize min operand to RHS.
3652e8d8bef9SDimitry Andric   if (match(LHS, m_UMin(m_Value(), m_Value())) ||
3653e8d8bef9SDimitry Andric       match(LHS, m_SMin(m_Value(), m_Value()))) {
3654e8d8bef9SDimitry Andric     std::swap(LHS, RHS);
3655e8d8bef9SDimitry Andric     Pred = ICmpInst::getSwappedPredicate(Pred);
3656e8d8bef9SDimitry Andric   }
3657e8d8bef9SDimitry Andric 
36580b57cec5SDimitry Andric   Value *C, *D;
36590b57cec5SDimitry Andric   if (match(LHS, m_SMax(m_Value(A), m_Value(B))) &&
36600b57cec5SDimitry Andric       match(RHS, m_SMin(m_Value(C), m_Value(D))) &&
36610b57cec5SDimitry Andric       (A == C || A == D || B == C || B == D)) {
3662e8d8bef9SDimitry Andric     // smax(A, B) >=s smin(A, D) --> true
36630b57cec5SDimitry Andric     if (Pred == CmpInst::ICMP_SGE)
36640b57cec5SDimitry Andric       return getTrue(ITy);
3665e8d8bef9SDimitry Andric     // smax(A, B) <s smin(A, D) --> false
36660b57cec5SDimitry Andric     if (Pred == CmpInst::ICMP_SLT)
36670b57cec5SDimitry Andric       return getFalse(ITy);
36680b57cec5SDimitry Andric   } else if (match(LHS, m_UMax(m_Value(A), m_Value(B))) &&
36690b57cec5SDimitry Andric              match(RHS, m_UMin(m_Value(C), m_Value(D))) &&
36700b57cec5SDimitry Andric              (A == C || A == D || B == C || B == D)) {
3671e8d8bef9SDimitry Andric     // umax(A, B) >=u umin(A, D) --> true
36720b57cec5SDimitry Andric     if (Pred == CmpInst::ICMP_UGE)
36730b57cec5SDimitry Andric       return getTrue(ITy);
3674e8d8bef9SDimitry Andric     // umax(A, B) <u umin(A, D) --> false
36750b57cec5SDimitry Andric     if (Pred == CmpInst::ICMP_ULT)
36760b57cec5SDimitry Andric       return getFalse(ITy);
36770b57cec5SDimitry Andric   }
36780b57cec5SDimitry Andric 
36790b57cec5SDimitry Andric   return nullptr;
36800b57cec5SDimitry Andric }
36810b57cec5SDimitry Andric 
36825ffd83dbSDimitry Andric static Value *simplifyICmpWithDominatingAssume(CmpInst::Predicate Predicate,
36835ffd83dbSDimitry Andric                                                Value *LHS, Value *RHS,
36845ffd83dbSDimitry Andric                                                const SimplifyQuery &Q) {
36855ffd83dbSDimitry Andric   // Gracefully handle instructions that have not been inserted yet.
368606c3fb27SDimitry Andric   if (!Q.AC || !Q.CxtI)
36875ffd83dbSDimitry Andric     return nullptr;
36885ffd83dbSDimitry Andric 
36895ffd83dbSDimitry Andric   for (Value *AssumeBaseOp : {LHS, RHS}) {
36905ffd83dbSDimitry Andric     for (auto &AssumeVH : Q.AC->assumptionsFor(AssumeBaseOp)) {
36915ffd83dbSDimitry Andric       if (!AssumeVH)
36925ffd83dbSDimitry Andric         continue;
36935ffd83dbSDimitry Andric 
36945ffd83dbSDimitry Andric       CallInst *Assume = cast<CallInst>(AssumeVH);
3695bdd1243dSDimitry Andric       if (std::optional<bool> Imp = isImpliedCondition(
3696bdd1243dSDimitry Andric               Assume->getArgOperand(0), Predicate, LHS, RHS, Q.DL))
36975ffd83dbSDimitry Andric         if (isValidAssumeForContext(Assume, Q.CxtI, Q.DT))
369881ad6265SDimitry Andric           return ConstantInt::get(getCompareTy(LHS), *Imp);
36995ffd83dbSDimitry Andric     }
37005ffd83dbSDimitry Andric   }
37015ffd83dbSDimitry Andric 
37025ffd83dbSDimitry Andric   return nullptr;
37035ffd83dbSDimitry Andric }
37045ffd83dbSDimitry Andric 
370506c3fb27SDimitry Andric static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
370606c3fb27SDimitry Andric                                              Value *LHS, Value *RHS) {
370706c3fb27SDimitry Andric   auto *II = dyn_cast<IntrinsicInst>(LHS);
370806c3fb27SDimitry Andric   if (!II)
370906c3fb27SDimitry Andric     return nullptr;
371006c3fb27SDimitry Andric 
371106c3fb27SDimitry Andric   switch (II->getIntrinsicID()) {
371206c3fb27SDimitry Andric   case Intrinsic::uadd_sat:
371306c3fb27SDimitry Andric     // uadd.sat(X, Y) uge X, uadd.sat(X, Y) uge Y
371406c3fb27SDimitry Andric     if (II->getArgOperand(0) == RHS || II->getArgOperand(1) == RHS) {
371506c3fb27SDimitry Andric       if (Pred == ICmpInst::ICMP_UGE)
371606c3fb27SDimitry Andric         return ConstantInt::getTrue(getCompareTy(II));
371706c3fb27SDimitry Andric       if (Pred == ICmpInst::ICMP_ULT)
371806c3fb27SDimitry Andric         return ConstantInt::getFalse(getCompareTy(II));
371906c3fb27SDimitry Andric     }
372006c3fb27SDimitry Andric     return nullptr;
372106c3fb27SDimitry Andric   case Intrinsic::usub_sat:
372206c3fb27SDimitry Andric     // usub.sat(X, Y) ule X
372306c3fb27SDimitry Andric     if (II->getArgOperand(0) == RHS) {
372406c3fb27SDimitry Andric       if (Pred == ICmpInst::ICMP_ULE)
372506c3fb27SDimitry Andric         return ConstantInt::getTrue(getCompareTy(II));
372606c3fb27SDimitry Andric       if (Pred == ICmpInst::ICMP_UGT)
372706c3fb27SDimitry Andric         return ConstantInt::getFalse(getCompareTy(II));
372806c3fb27SDimitry Andric     }
372906c3fb27SDimitry Andric     return nullptr;
373006c3fb27SDimitry Andric   default:
373106c3fb27SDimitry Andric     return nullptr;
373206c3fb27SDimitry Andric   }
373306c3fb27SDimitry Andric }
373406c3fb27SDimitry Andric 
3735*0fca6ea1SDimitry Andric /// Helper method to get range from metadata or attribute.
3736*0fca6ea1SDimitry Andric static std::optional<ConstantRange> getRange(Value *V,
3737*0fca6ea1SDimitry Andric                                              const InstrInfoQuery &IIQ) {
3738*0fca6ea1SDimitry Andric   if (Instruction *I = dyn_cast<Instruction>(V))
3739*0fca6ea1SDimitry Andric     if (MDNode *MD = IIQ.getMetadata(I, LLVMContext::MD_range))
3740*0fca6ea1SDimitry Andric       return getConstantRangeFromMetadata(*MD);
3741*0fca6ea1SDimitry Andric 
3742*0fca6ea1SDimitry Andric   if (const Argument *A = dyn_cast<Argument>(V))
3743*0fca6ea1SDimitry Andric     return A->getRange();
3744*0fca6ea1SDimitry Andric   else if (const CallBase *CB = dyn_cast<CallBase>(V))
3745*0fca6ea1SDimitry Andric     return CB->getRange();
3746*0fca6ea1SDimitry Andric 
3747*0fca6ea1SDimitry Andric   return std::nullopt;
3748*0fca6ea1SDimitry Andric }
3749*0fca6ea1SDimitry Andric 
37500b57cec5SDimitry Andric /// Given operands for an ICmpInst, see if we can fold the result.
37510b57cec5SDimitry Andric /// If not, this returns null.
375281ad6265SDimitry Andric static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
37530b57cec5SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
37540b57cec5SDimitry Andric   CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
37550b57cec5SDimitry Andric   assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!");
37560b57cec5SDimitry Andric 
37570b57cec5SDimitry Andric   if (Constant *CLHS = dyn_cast<Constant>(LHS)) {
37580b57cec5SDimitry Andric     if (Constant *CRHS = dyn_cast<Constant>(RHS))
37590b57cec5SDimitry Andric       return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, Q.DL, Q.TLI);
37600b57cec5SDimitry Andric 
37610b57cec5SDimitry Andric     // If we have a constant, make sure it is on the RHS.
37620b57cec5SDimitry Andric     std::swap(LHS, RHS);
37630b57cec5SDimitry Andric     Pred = CmpInst::getSwappedPredicate(Pred);
37640b57cec5SDimitry Andric   }
37650b57cec5SDimitry Andric   assert(!isa<UndefValue>(LHS) && "Unexpected icmp undef,%X");
37660b57cec5SDimitry Andric 
376781ad6265SDimitry Andric   Type *ITy = getCompareTy(LHS); // The return type.
37680b57cec5SDimitry Andric 
3769fe6060f1SDimitry Andric   // icmp poison, X -> poison
3770fe6060f1SDimitry Andric   if (isa<PoisonValue>(RHS))
3771fe6060f1SDimitry Andric     return PoisonValue::get(ITy);
3772fe6060f1SDimitry Andric 
37730b57cec5SDimitry Andric   // For EQ and NE, we can always pick a value for the undef to make the
37740b57cec5SDimitry Andric   // predicate pass or fail, so we can return undef.
37750b57cec5SDimitry Andric   // Matches behavior in llvm::ConstantFoldCompareInstruction.
3776e8d8bef9SDimitry Andric   if (Q.isUndefValue(RHS) && ICmpInst::isEquality(Pred))
37770b57cec5SDimitry Andric     return UndefValue::get(ITy);
37780b57cec5SDimitry Andric 
37790b57cec5SDimitry Andric   // icmp X, X -> true/false
37800b57cec5SDimitry Andric   // icmp X, undef -> true/false because undef could be X.
3781e8d8bef9SDimitry Andric   if (LHS == RHS || Q.isUndefValue(RHS))
37820b57cec5SDimitry Andric     return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
37830b57cec5SDimitry Andric 
37840b57cec5SDimitry Andric   if (Value *V = simplifyICmpOfBools(Pred, LHS, RHS, Q))
37850b57cec5SDimitry Andric     return V;
37860b57cec5SDimitry Andric 
3787fe6060f1SDimitry Andric   // TODO: Sink/common this with other potentially expensive calls that use
3788fe6060f1SDimitry Andric   //       ValueTracking? See comment below for isKnownNonEqual().
37890b57cec5SDimitry Andric   if (Value *V = simplifyICmpWithZero(Pred, LHS, RHS, Q))
37900b57cec5SDimitry Andric     return V;
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric   if (Value *V = simplifyICmpWithConstant(Pred, LHS, RHS, Q.IIQ))
37930b57cec5SDimitry Andric     return V;
37940b57cec5SDimitry Andric 
37950b57cec5SDimitry Andric   // If both operands have range metadata, use the metadata
37960b57cec5SDimitry Andric   // to simplify the comparison.
3797*0fca6ea1SDimitry Andric   if (std::optional<ConstantRange> RhsCr = getRange(RHS, Q.IIQ))
3798*0fca6ea1SDimitry Andric     if (std::optional<ConstantRange> LhsCr = getRange(LHS, Q.IIQ)) {
3799*0fca6ea1SDimitry Andric       if (LhsCr->icmp(Pred, *RhsCr))
3800*0fca6ea1SDimitry Andric         return ConstantInt::getTrue(ITy);
38010b57cec5SDimitry Andric 
3802*0fca6ea1SDimitry Andric       if (LhsCr->icmp(CmpInst::getInversePredicate(Pred), *RhsCr))
3803*0fca6ea1SDimitry Andric         return ConstantInt::getFalse(ITy);
38040b57cec5SDimitry Andric     }
38050b57cec5SDimitry Andric 
38060b57cec5SDimitry Andric   // Compare of cast, for example (zext X) != 0 -> X != 0
38070b57cec5SDimitry Andric   if (isa<CastInst>(LHS) && (isa<Constant>(RHS) || isa<CastInst>(RHS))) {
38080b57cec5SDimitry Andric     Instruction *LI = cast<CastInst>(LHS);
38090b57cec5SDimitry Andric     Value *SrcOp = LI->getOperand(0);
38100b57cec5SDimitry Andric     Type *SrcTy = SrcOp->getType();
38110b57cec5SDimitry Andric     Type *DstTy = LI->getType();
38120b57cec5SDimitry Andric 
38130b57cec5SDimitry Andric     // Turn icmp (ptrtoint x), (ptrtoint/constant) into a compare of the input
38140b57cec5SDimitry Andric     // if the integer type is the same size as the pointer type.
38150b57cec5SDimitry Andric     if (MaxRecurse && isa<PtrToIntInst>(LI) &&
38160b57cec5SDimitry Andric         Q.DL.getTypeSizeInBits(SrcTy) == DstTy->getPrimitiveSizeInBits()) {
38170b57cec5SDimitry Andric       if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
38180b57cec5SDimitry Andric         // Transfer the cast to the constant.
381981ad6265SDimitry Andric         if (Value *V = simplifyICmpInst(Pred, SrcOp,
38200b57cec5SDimitry Andric                                         ConstantExpr::getIntToPtr(RHSC, SrcTy),
38210b57cec5SDimitry Andric                                         Q, MaxRecurse - 1))
38220b57cec5SDimitry Andric           return V;
38230b57cec5SDimitry Andric       } else if (PtrToIntInst *RI = dyn_cast<PtrToIntInst>(RHS)) {
38240b57cec5SDimitry Andric         if (RI->getOperand(0)->getType() == SrcTy)
38250b57cec5SDimitry Andric           // Compare without the cast.
382681ad6265SDimitry Andric           if (Value *V = simplifyICmpInst(Pred, SrcOp, RI->getOperand(0), Q,
382781ad6265SDimitry Andric                                           MaxRecurse - 1))
38280b57cec5SDimitry Andric             return V;
38290b57cec5SDimitry Andric       }
38300b57cec5SDimitry Andric     }
38310b57cec5SDimitry Andric 
38320b57cec5SDimitry Andric     if (isa<ZExtInst>(LHS)) {
38330b57cec5SDimitry Andric       // Turn icmp (zext X), (zext Y) into a compare of X and Y if they have the
38340b57cec5SDimitry Andric       // same type.
38350b57cec5SDimitry Andric       if (ZExtInst *RI = dyn_cast<ZExtInst>(RHS)) {
38360b57cec5SDimitry Andric         if (MaxRecurse && SrcTy == RI->getOperand(0)->getType())
38370b57cec5SDimitry Andric           // Compare X and Y.  Note that signed predicates become unsigned.
383881ad6265SDimitry Andric           if (Value *V =
383981ad6265SDimitry Andric                   simplifyICmpInst(ICmpInst::getUnsignedPredicate(Pred), SrcOp,
384081ad6265SDimitry Andric                                    RI->getOperand(0), Q, MaxRecurse - 1))
38410b57cec5SDimitry Andric             return V;
38420b57cec5SDimitry Andric       }
38435ffd83dbSDimitry Andric       // Fold (zext X) ule (sext X), (zext X) sge (sext X) to true.
38445ffd83dbSDimitry Andric       else if (SExtInst *RI = dyn_cast<SExtInst>(RHS)) {
38455ffd83dbSDimitry Andric         if (SrcOp == RI->getOperand(0)) {
38465ffd83dbSDimitry Andric           if (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_SGE)
38475ffd83dbSDimitry Andric             return ConstantInt::getTrue(ITy);
38485ffd83dbSDimitry Andric           if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SLT)
38495ffd83dbSDimitry Andric             return ConstantInt::getFalse(ITy);
38505ffd83dbSDimitry Andric         }
38515ffd83dbSDimitry Andric       }
38520b57cec5SDimitry Andric       // Turn icmp (zext X), Cst into a compare of X and Cst if Cst is extended
38530b57cec5SDimitry Andric       // too.  If not, then try to deduce the result of the comparison.
385406c3fb27SDimitry Andric       else if (match(RHS, m_ImmConstant())) {
385506c3fb27SDimitry Andric         Constant *C = dyn_cast<Constant>(RHS);
385606c3fb27SDimitry Andric         assert(C != nullptr);
385706c3fb27SDimitry Andric 
38580b57cec5SDimitry Andric         // Compute the constant that would happen if we truncated to SrcTy then
38590b57cec5SDimitry Andric         // reextended to DstTy.
38605f757f3fSDimitry Andric         Constant *Trunc =
38615f757f3fSDimitry Andric             ConstantFoldCastOperand(Instruction::Trunc, C, SrcTy, Q.DL);
38625f757f3fSDimitry Andric         assert(Trunc && "Constant-fold of ImmConstant should not fail");
38635f757f3fSDimitry Andric         Constant *RExt =
38645f757f3fSDimitry Andric             ConstantFoldCastOperand(CastInst::ZExt, Trunc, DstTy, Q.DL);
38655f757f3fSDimitry Andric         assert(RExt && "Constant-fold of ImmConstant should not fail");
38665f757f3fSDimitry Andric         Constant *AnyEq =
38675f757f3fSDimitry Andric             ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ, RExt, C, Q.DL);
38685f757f3fSDimitry Andric         assert(AnyEq && "Constant-fold of ImmConstant should not fail");
38690b57cec5SDimitry Andric 
387006c3fb27SDimitry Andric         // If the re-extended constant didn't change any of the elements then
387106c3fb27SDimitry Andric         // this is effectively also a case of comparing two zero-extended
387206c3fb27SDimitry Andric         // values.
387306c3fb27SDimitry Andric         if (AnyEq->isAllOnesValue() && MaxRecurse)
387481ad6265SDimitry Andric           if (Value *V = simplifyICmpInst(ICmpInst::getUnsignedPredicate(Pred),
38750b57cec5SDimitry Andric                                           SrcOp, Trunc, Q, MaxRecurse - 1))
38760b57cec5SDimitry Andric             return V;
38770b57cec5SDimitry Andric 
38780b57cec5SDimitry Andric         // Otherwise the upper bits of LHS are zero while RHS has a non-zero bit
38790b57cec5SDimitry Andric         // there.  Use this to work out the result of the comparison.
388006c3fb27SDimitry Andric         if (AnyEq->isNullValue()) {
38810b57cec5SDimitry Andric           switch (Pred) {
388281ad6265SDimitry Andric           default:
388381ad6265SDimitry Andric             llvm_unreachable("Unknown ICmp predicate!");
38840b57cec5SDimitry Andric           // LHS <u RHS.
38850b57cec5SDimitry Andric           case ICmpInst::ICMP_EQ:
38860b57cec5SDimitry Andric           case ICmpInst::ICMP_UGT:
38870b57cec5SDimitry Andric           case ICmpInst::ICMP_UGE:
388806c3fb27SDimitry Andric             return Constant::getNullValue(ITy);
38890b57cec5SDimitry Andric 
38900b57cec5SDimitry Andric           case ICmpInst::ICMP_NE:
38910b57cec5SDimitry Andric           case ICmpInst::ICMP_ULT:
38920b57cec5SDimitry Andric           case ICmpInst::ICMP_ULE:
389306c3fb27SDimitry Andric             return Constant::getAllOnesValue(ITy);
38940b57cec5SDimitry Andric 
38950b57cec5SDimitry Andric           // LHS is non-negative.  If RHS is negative then LHS >s LHS.  If RHS
38960b57cec5SDimitry Andric           // is non-negative then LHS <s RHS.
38970b57cec5SDimitry Andric           case ICmpInst::ICMP_SGT:
38980b57cec5SDimitry Andric           case ICmpInst::ICMP_SGE:
38995f757f3fSDimitry Andric             return ConstantFoldCompareInstOperands(
39005f757f3fSDimitry Andric                 ICmpInst::ICMP_SLT, C, Constant::getNullValue(C->getType()),
39015f757f3fSDimitry Andric                 Q.DL);
39020b57cec5SDimitry Andric           case ICmpInst::ICMP_SLT:
39030b57cec5SDimitry Andric           case ICmpInst::ICMP_SLE:
39045f757f3fSDimitry Andric             return ConstantFoldCompareInstOperands(
39055f757f3fSDimitry Andric                 ICmpInst::ICMP_SGE, C, Constant::getNullValue(C->getType()),
39065f757f3fSDimitry Andric                 Q.DL);
39070b57cec5SDimitry Andric           }
39080b57cec5SDimitry Andric         }
39090b57cec5SDimitry Andric       }
39100b57cec5SDimitry Andric     }
39110b57cec5SDimitry Andric 
39120b57cec5SDimitry Andric     if (isa<SExtInst>(LHS)) {
39130b57cec5SDimitry Andric       // Turn icmp (sext X), (sext Y) into a compare of X and Y if they have the
39140b57cec5SDimitry Andric       // same type.
39150b57cec5SDimitry Andric       if (SExtInst *RI = dyn_cast<SExtInst>(RHS)) {
39160b57cec5SDimitry Andric         if (MaxRecurse && SrcTy == RI->getOperand(0)->getType())
39170b57cec5SDimitry Andric           // Compare X and Y.  Note that the predicate does not change.
391881ad6265SDimitry Andric           if (Value *V = simplifyICmpInst(Pred, SrcOp, RI->getOperand(0), Q,
391981ad6265SDimitry Andric                                           MaxRecurse - 1))
39200b57cec5SDimitry Andric             return V;
39210b57cec5SDimitry Andric       }
39225ffd83dbSDimitry Andric       // Fold (sext X) uge (zext X), (sext X) sle (zext X) to true.
39235ffd83dbSDimitry Andric       else if (ZExtInst *RI = dyn_cast<ZExtInst>(RHS)) {
39245ffd83dbSDimitry Andric         if (SrcOp == RI->getOperand(0)) {
39255ffd83dbSDimitry Andric           if (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_SLE)
39265ffd83dbSDimitry Andric             return ConstantInt::getTrue(ITy);
39275ffd83dbSDimitry Andric           if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SGT)
39285ffd83dbSDimitry Andric             return ConstantInt::getFalse(ITy);
39295ffd83dbSDimitry Andric         }
39305ffd83dbSDimitry Andric       }
39310b57cec5SDimitry Andric       // Turn icmp (sext X), Cst into a compare of X and Cst if Cst is extended
39320b57cec5SDimitry Andric       // too.  If not, then try to deduce the result of the comparison.
393306c3fb27SDimitry Andric       else if (match(RHS, m_ImmConstant())) {
39345f757f3fSDimitry Andric         Constant *C = cast<Constant>(RHS);
393506c3fb27SDimitry Andric 
39360b57cec5SDimitry Andric         // Compute the constant that would happen if we truncated to SrcTy then
39370b57cec5SDimitry Andric         // reextended to DstTy.
39385f757f3fSDimitry Andric         Constant *Trunc =
39395f757f3fSDimitry Andric             ConstantFoldCastOperand(Instruction::Trunc, C, SrcTy, Q.DL);
39405f757f3fSDimitry Andric         assert(Trunc && "Constant-fold of ImmConstant should not fail");
39415f757f3fSDimitry Andric         Constant *RExt =
39425f757f3fSDimitry Andric             ConstantFoldCastOperand(CastInst::SExt, Trunc, DstTy, Q.DL);
39435f757f3fSDimitry Andric         assert(RExt && "Constant-fold of ImmConstant should not fail");
39445f757f3fSDimitry Andric         Constant *AnyEq =
39455f757f3fSDimitry Andric             ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ, RExt, C, Q.DL);
39465f757f3fSDimitry Andric         assert(AnyEq && "Constant-fold of ImmConstant should not fail");
39470b57cec5SDimitry Andric 
39480b57cec5SDimitry Andric         // If the re-extended constant didn't change then this is effectively
39490b57cec5SDimitry Andric         // also a case of comparing two sign-extended values.
395006c3fb27SDimitry Andric         if (AnyEq->isAllOnesValue() && MaxRecurse)
395181ad6265SDimitry Andric           if (Value *V =
395281ad6265SDimitry Andric                   simplifyICmpInst(Pred, SrcOp, Trunc, Q, MaxRecurse - 1))
39530b57cec5SDimitry Andric             return V;
39540b57cec5SDimitry Andric 
39550b57cec5SDimitry Andric         // Otherwise the upper bits of LHS are all equal, while RHS has varying
39560b57cec5SDimitry Andric         // bits there.  Use this to work out the result of the comparison.
395706c3fb27SDimitry Andric         if (AnyEq->isNullValue()) {
39580b57cec5SDimitry Andric           switch (Pred) {
395981ad6265SDimitry Andric           default:
396081ad6265SDimitry Andric             llvm_unreachable("Unknown ICmp predicate!");
39610b57cec5SDimitry Andric           case ICmpInst::ICMP_EQ:
396206c3fb27SDimitry Andric             return Constant::getNullValue(ITy);
39630b57cec5SDimitry Andric           case ICmpInst::ICMP_NE:
396406c3fb27SDimitry Andric             return Constant::getAllOnesValue(ITy);
39650b57cec5SDimitry Andric 
39660b57cec5SDimitry Andric           // If RHS is non-negative then LHS <s RHS.  If RHS is negative then
39670b57cec5SDimitry Andric           // LHS >s RHS.
39680b57cec5SDimitry Andric           case ICmpInst::ICMP_SGT:
39690b57cec5SDimitry Andric           case ICmpInst::ICMP_SGE:
3970*0fca6ea1SDimitry Andric             return ConstantFoldCompareInstOperands(
3971*0fca6ea1SDimitry Andric                 ICmpInst::ICMP_SLT, C, Constant::getNullValue(C->getType()),
3972*0fca6ea1SDimitry Andric                 Q.DL);
39730b57cec5SDimitry Andric           case ICmpInst::ICMP_SLT:
39740b57cec5SDimitry Andric           case ICmpInst::ICMP_SLE:
3975*0fca6ea1SDimitry Andric             return ConstantFoldCompareInstOperands(
3976*0fca6ea1SDimitry Andric                 ICmpInst::ICMP_SGE, C, Constant::getNullValue(C->getType()),
3977*0fca6ea1SDimitry Andric                 Q.DL);
39780b57cec5SDimitry Andric 
39790b57cec5SDimitry Andric           // If LHS is non-negative then LHS <u RHS.  If LHS is negative then
39800b57cec5SDimitry Andric           // LHS >u RHS.
39810b57cec5SDimitry Andric           case ICmpInst::ICMP_UGT:
39820b57cec5SDimitry Andric           case ICmpInst::ICMP_UGE:
39830b57cec5SDimitry Andric             // Comparison is true iff the LHS <s 0.
39840b57cec5SDimitry Andric             if (MaxRecurse)
398581ad6265SDimitry Andric               if (Value *V = simplifyICmpInst(ICmpInst::ICMP_SLT, SrcOp,
398681ad6265SDimitry Andric                                               Constant::getNullValue(SrcTy), Q,
398781ad6265SDimitry Andric                                               MaxRecurse - 1))
39880b57cec5SDimitry Andric                 return V;
39890b57cec5SDimitry Andric             break;
39900b57cec5SDimitry Andric           case ICmpInst::ICMP_ULT:
39910b57cec5SDimitry Andric           case ICmpInst::ICMP_ULE:
39920b57cec5SDimitry Andric             // Comparison is true iff the LHS >=s 0.
39930b57cec5SDimitry Andric             if (MaxRecurse)
399481ad6265SDimitry Andric               if (Value *V = simplifyICmpInst(ICmpInst::ICMP_SGE, SrcOp,
399581ad6265SDimitry Andric                                               Constant::getNullValue(SrcTy), Q,
399681ad6265SDimitry Andric                                               MaxRecurse - 1))
39970b57cec5SDimitry Andric                 return V;
39980b57cec5SDimitry Andric             break;
39990b57cec5SDimitry Andric           }
40000b57cec5SDimitry Andric         }
40010b57cec5SDimitry Andric       }
40020b57cec5SDimitry Andric     }
40030b57cec5SDimitry Andric   }
40040b57cec5SDimitry Andric 
40050b57cec5SDimitry Andric   // icmp eq|ne X, Y -> false|true if X != Y
4006fe6060f1SDimitry Andric   // This is potentially expensive, and we have already computedKnownBits for
4007fe6060f1SDimitry Andric   // compares with 0 above here, so only try this for a non-zero compare.
4008fe6060f1SDimitry Andric   if (ICmpInst::isEquality(Pred) && !match(RHS, m_Zero()) &&
40090b57cec5SDimitry Andric       isKnownNonEqual(LHS, RHS, Q.DL, Q.AC, Q.CxtI, Q.DT, Q.IIQ.UseInstrInfo)) {
40100b57cec5SDimitry Andric     return Pred == ICmpInst::ICMP_NE ? getTrue(ITy) : getFalse(ITy);
40110b57cec5SDimitry Andric   }
40120b57cec5SDimitry Andric 
40130b57cec5SDimitry Andric   if (Value *V = simplifyICmpWithBinOp(Pred, LHS, RHS, Q, MaxRecurse))
40140b57cec5SDimitry Andric     return V;
40150b57cec5SDimitry Andric 
40160b57cec5SDimitry Andric   if (Value *V = simplifyICmpWithMinMax(Pred, LHS, RHS, Q, MaxRecurse))
40170b57cec5SDimitry Andric     return V;
40180b57cec5SDimitry Andric 
401906c3fb27SDimitry Andric   if (Value *V = simplifyICmpWithIntrinsicOnLHS(Pred, LHS, RHS))
402006c3fb27SDimitry Andric     return V;
402106c3fb27SDimitry Andric   if (Value *V = simplifyICmpWithIntrinsicOnLHS(
402206c3fb27SDimitry Andric           ICmpInst::getSwappedPredicate(Pred), RHS, LHS))
402306c3fb27SDimitry Andric     return V;
402406c3fb27SDimitry Andric 
40255ffd83dbSDimitry Andric   if (Value *V = simplifyICmpWithDominatingAssume(Pred, LHS, RHS, Q))
40265ffd83dbSDimitry Andric     return V;
40275ffd83dbSDimitry Andric 
402806c3fb27SDimitry Andric   if (std::optional<bool> Res =
402906c3fb27SDimitry Andric           isImpliedByDomCondition(Pred, LHS, RHS, Q.CxtI, Q.DL))
403006c3fb27SDimitry Andric     return ConstantInt::getBool(ITy, *Res);
403106c3fb27SDimitry Andric 
40320b57cec5SDimitry Andric   // Simplify comparisons of related pointers using a powerful, recursive
40330b57cec5SDimitry Andric   // GEP-walk when we have target data available..
40340b57cec5SDimitry Andric   if (LHS->getType()->isPointerTy())
4035fe6060f1SDimitry Andric     if (auto *C = computePointerICmp(Pred, LHS, RHS, Q))
40360b57cec5SDimitry Andric       return C;
40370b57cec5SDimitry Andric   if (auto *CLHS = dyn_cast<PtrToIntOperator>(LHS))
40380b57cec5SDimitry Andric     if (auto *CRHS = dyn_cast<PtrToIntOperator>(RHS))
403906c3fb27SDimitry Andric       if (CLHS->getPointerOperandType() == CRHS->getPointerOperandType() &&
404006c3fb27SDimitry Andric           Q.DL.getTypeSizeInBits(CLHS->getPointerOperandType()) ==
404106c3fb27SDimitry Andric               Q.DL.getTypeSizeInBits(CLHS->getType()))
4042fe6060f1SDimitry Andric         if (auto *C = computePointerICmp(Pred, CLHS->getPointerOperand(),
4043fe6060f1SDimitry Andric                                          CRHS->getPointerOperand(), Q))
40440b57cec5SDimitry Andric           return C;
40450b57cec5SDimitry Andric 
40460b57cec5SDimitry Andric   // If the comparison is with the result of a select instruction, check whether
40470b57cec5SDimitry Andric   // comparing with either branch of the select always yields the same value.
40480b57cec5SDimitry Andric   if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))
404981ad6265SDimitry Andric     if (Value *V = threadCmpOverSelect(Pred, LHS, RHS, Q, MaxRecurse))
40500b57cec5SDimitry Andric       return V;
40510b57cec5SDimitry Andric 
40520b57cec5SDimitry Andric   // If the comparison is with the result of a phi instruction, check whether
40530b57cec5SDimitry Andric   // doing the compare with each incoming phi value yields a common result.
40540b57cec5SDimitry Andric   if (isa<PHINode>(LHS) || isa<PHINode>(RHS))
405581ad6265SDimitry Andric     if (Value *V = threadCmpOverPHI(Pred, LHS, RHS, Q, MaxRecurse))
40560b57cec5SDimitry Andric       return V;
40570b57cec5SDimitry Andric 
40580b57cec5SDimitry Andric   return nullptr;
40590b57cec5SDimitry Andric }
40600b57cec5SDimitry Andric 
406181ad6265SDimitry Andric Value *llvm::simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
40620b57cec5SDimitry Andric                               const SimplifyQuery &Q) {
406381ad6265SDimitry Andric   return ::simplifyICmpInst(Predicate, LHS, RHS, Q, RecursionLimit);
40640b57cec5SDimitry Andric }
40650b57cec5SDimitry Andric 
40660b57cec5SDimitry Andric /// Given operands for an FCmpInst, see if we can fold the result.
40670b57cec5SDimitry Andric /// If not, this returns null.
406881ad6265SDimitry Andric static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
40690b57cec5SDimitry Andric                                FastMathFlags FMF, const SimplifyQuery &Q,
40700b57cec5SDimitry Andric                                unsigned MaxRecurse) {
40710b57cec5SDimitry Andric   CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
40720b57cec5SDimitry Andric   assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
40730b57cec5SDimitry Andric 
40740b57cec5SDimitry Andric   if (Constant *CLHS = dyn_cast<Constant>(LHS)) {
40750b57cec5SDimitry Andric     if (Constant *CRHS = dyn_cast<Constant>(RHS))
407681ad6265SDimitry Andric       return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, Q.DL, Q.TLI,
407781ad6265SDimitry Andric                                              Q.CxtI);
40780b57cec5SDimitry Andric 
40790b57cec5SDimitry Andric     // If we have a constant, make sure it is on the RHS.
40800b57cec5SDimitry Andric     std::swap(LHS, RHS);
40810b57cec5SDimitry Andric     Pred = CmpInst::getSwappedPredicate(Pred);
40820b57cec5SDimitry Andric   }
40830b57cec5SDimitry Andric 
40840b57cec5SDimitry Andric   // Fold trivial predicates.
408581ad6265SDimitry Andric   Type *RetTy = getCompareTy(LHS);
40860b57cec5SDimitry Andric   if (Pred == FCmpInst::FCMP_FALSE)
40870b57cec5SDimitry Andric     return getFalse(RetTy);
40880b57cec5SDimitry Andric   if (Pred == FCmpInst::FCMP_TRUE)
40890b57cec5SDimitry Andric     return getTrue(RetTy);
40900b57cec5SDimitry Andric 
4091fe6060f1SDimitry Andric   // fcmp pred x, poison and  fcmp pred poison, x
4092fe6060f1SDimitry Andric   // fold to poison
4093fe6060f1SDimitry Andric   if (isa<PoisonValue>(LHS) || isa<PoisonValue>(RHS))
4094fe6060f1SDimitry Andric     return PoisonValue::get(RetTy);
4095fe6060f1SDimitry Andric 
40960b57cec5SDimitry Andric   // fcmp pred x, undef  and  fcmp pred undef, x
40970b57cec5SDimitry Andric   // fold to true if unordered, false if ordered
4098e8d8bef9SDimitry Andric   if (Q.isUndefValue(LHS) || Q.isUndefValue(RHS)) {
40990b57cec5SDimitry Andric     // Choosing NaN for the undef will always make unordered comparison succeed
41000b57cec5SDimitry Andric     // and ordered comparison fail.
41010b57cec5SDimitry Andric     return ConstantInt::get(RetTy, CmpInst::isUnordered(Pred));
41020b57cec5SDimitry Andric   }
41030b57cec5SDimitry Andric 
41040b57cec5SDimitry Andric   // fcmp x,x -> true/false.  Not all compares are foldable.
41050b57cec5SDimitry Andric   if (LHS == RHS) {
41060b57cec5SDimitry Andric     if (CmpInst::isTrueWhenEqual(Pred))
41070b57cec5SDimitry Andric       return getTrue(RetTy);
41080b57cec5SDimitry Andric     if (CmpInst::isFalseWhenEqual(Pred))
41090b57cec5SDimitry Andric       return getFalse(RetTy);
41100b57cec5SDimitry Andric   }
41110b57cec5SDimitry Andric 
41125f757f3fSDimitry Andric   // Fold (un)ordered comparison if we can determine there are no NaNs.
41135f757f3fSDimitry Andric   //
41145f757f3fSDimitry Andric   // This catches the 2 variable input case, constants are handled below as a
41155f757f3fSDimitry Andric   // class-like compare.
41165f757f3fSDimitry Andric   if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {
4117*0fca6ea1SDimitry Andric     KnownFPClass RHSClass =
4118*0fca6ea1SDimitry Andric         computeKnownFPClass(RHS, fcAllFlags, /*Depth=*/0, Q);
4119*0fca6ea1SDimitry Andric     KnownFPClass LHSClass =
4120*0fca6ea1SDimitry Andric         computeKnownFPClass(LHS, fcAllFlags, /*Depth=*/0, Q);
4121*0fca6ea1SDimitry Andric 
41225f757f3fSDimitry Andric     if (FMF.noNaNs() ||
4123*0fca6ea1SDimitry Andric         (RHSClass.isKnownNeverNaN() && LHSClass.isKnownNeverNaN()))
41245f757f3fSDimitry Andric       return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);
4125*0fca6ea1SDimitry Andric 
4126*0fca6ea1SDimitry Andric     if (RHSClass.isKnownAlwaysNaN() || LHSClass.isKnownAlwaysNaN())
4127*0fca6ea1SDimitry Andric       return ConstantInt::get(RetTy, Pred == CmpInst::FCMP_UNO);
41280b57cec5SDimitry Andric   }
41295f757f3fSDimitry Andric 
41305f757f3fSDimitry Andric   const APFloat *C = nullptr;
4131*0fca6ea1SDimitry Andric   match(RHS, m_APFloatAllowPoison(C));
41325f757f3fSDimitry Andric   std::optional<KnownFPClass> FullKnownClassLHS;
41335f757f3fSDimitry Andric 
41345f757f3fSDimitry Andric   // Lazily compute the possible classes for LHS. Avoid computing it twice if
41355f757f3fSDimitry Andric   // RHS is a 0.
41365f757f3fSDimitry Andric   auto computeLHSClass = [=, &FullKnownClassLHS](FPClassTest InterestedFlags =
41375f757f3fSDimitry Andric                                                      fcAllFlags) {
41385f757f3fSDimitry Andric     if (FullKnownClassLHS)
41395f757f3fSDimitry Andric       return *FullKnownClassLHS;
4140*0fca6ea1SDimitry Andric     return computeKnownFPClass(LHS, FMF, InterestedFlags, 0, Q);
41415f757f3fSDimitry Andric   };
41425f757f3fSDimitry Andric 
41435f757f3fSDimitry Andric   if (C && Q.CxtI) {
41445f757f3fSDimitry Andric     // Fold out compares that express a class test.
41455f757f3fSDimitry Andric     //
41465f757f3fSDimitry Andric     // FIXME: Should be able to perform folds without context
41475f757f3fSDimitry Andric     // instruction. Always pass in the context function?
41485f757f3fSDimitry Andric 
41495f757f3fSDimitry Andric     const Function *ParentF = Q.CxtI->getFunction();
41505f757f3fSDimitry Andric     auto [ClassVal, ClassTest] = fcmpToClassTest(Pred, *ParentF, LHS, C);
41515f757f3fSDimitry Andric     if (ClassVal) {
41525f757f3fSDimitry Andric       FullKnownClassLHS = computeLHSClass();
41535f757f3fSDimitry Andric       if ((FullKnownClassLHS->KnownFPClasses & ClassTest) == fcNone)
41540b57cec5SDimitry Andric         return getFalse(RetTy);
41555f757f3fSDimitry Andric       if ((FullKnownClassLHS->KnownFPClasses & ~ClassTest) == fcNone)
41560b57cec5SDimitry Andric         return getTrue(RetTy);
41570b57cec5SDimitry Andric     }
41580b57cec5SDimitry Andric   }
4159e8d8bef9SDimitry Andric 
41605f757f3fSDimitry Andric   // Handle fcmp with constant RHS.
41615f757f3fSDimitry Andric   if (C) {
41625f757f3fSDimitry Andric     // TODO: If we always required a context function, we wouldn't need to
41635f757f3fSDimitry Andric     // special case nans.
41645f757f3fSDimitry Andric     if (C->isNaN())
41655f757f3fSDimitry Andric       return ConstantInt::get(RetTy, CmpInst::isUnordered(Pred));
41665f757f3fSDimitry Andric 
41675f757f3fSDimitry Andric     // TODO: Need version fcmpToClassTest which returns implied class when the
41685f757f3fSDimitry Andric     // compare isn't a complete class test. e.g. > 1.0 implies fcPositive, but
41695f757f3fSDimitry Andric     // isn't implementable as a class call.
41700b57cec5SDimitry Andric     if (C->isNegative() && !C->isNegZero()) {
41715f757f3fSDimitry Andric       FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
41725f757f3fSDimitry Andric 
41730b57cec5SDimitry Andric       // TODO: We can catch more cases by using a range check rather than
41740b57cec5SDimitry Andric       //       relying on CannotBeOrderedLessThanZero.
41750b57cec5SDimitry Andric       switch (Pred) {
41760b57cec5SDimitry Andric       case FCmpInst::FCMP_UGE:
41770b57cec5SDimitry Andric       case FCmpInst::FCMP_UGT:
41785f757f3fSDimitry Andric       case FCmpInst::FCMP_UNE: {
41795f757f3fSDimitry Andric         KnownFPClass KnownClass = computeLHSClass(Interested);
41805f757f3fSDimitry Andric 
41810b57cec5SDimitry Andric         // (X >= 0) implies (X > C) when (C < 0)
41825f757f3fSDimitry Andric         if (KnownClass.cannotBeOrderedLessThanZero())
41830b57cec5SDimitry Andric           return getTrue(RetTy);
41840b57cec5SDimitry Andric         break;
41855f757f3fSDimitry Andric       }
41860b57cec5SDimitry Andric       case FCmpInst::FCMP_OEQ:
41870b57cec5SDimitry Andric       case FCmpInst::FCMP_OLE:
41885f757f3fSDimitry Andric       case FCmpInst::FCMP_OLT: {
41895f757f3fSDimitry Andric         KnownFPClass KnownClass = computeLHSClass(Interested);
41905f757f3fSDimitry Andric 
41910b57cec5SDimitry Andric         // (X >= 0) implies !(X < C) when (C < 0)
41925f757f3fSDimitry Andric         if (KnownClass.cannotBeOrderedLessThanZero())
41930b57cec5SDimitry Andric           return getFalse(RetTy);
41940b57cec5SDimitry Andric         break;
41955f757f3fSDimitry Andric       }
41960b57cec5SDimitry Andric       default:
41970b57cec5SDimitry Andric         break;
41980b57cec5SDimitry Andric       }
41990b57cec5SDimitry Andric     }
42000b57cec5SDimitry Andric     // Check comparison of [minnum/maxnum with constant] with other constant.
42010b57cec5SDimitry Andric     const APFloat *C2;
42020b57cec5SDimitry Andric     if ((match(LHS, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_APFloat(C2))) &&
42035ffd83dbSDimitry Andric          *C2 < *C) ||
42040b57cec5SDimitry Andric         (match(LHS, m_Intrinsic<Intrinsic::maxnum>(m_Value(), m_APFloat(C2))) &&
42055ffd83dbSDimitry Andric          *C2 > *C)) {
42060b57cec5SDimitry Andric       bool IsMaxNum =
42070b57cec5SDimitry Andric           cast<IntrinsicInst>(LHS)->getIntrinsicID() == Intrinsic::maxnum;
42080b57cec5SDimitry Andric       // The ordered relationship and minnum/maxnum guarantee that we do not
42090b57cec5SDimitry Andric       // have NaN constants, so ordered/unordered preds are handled the same.
42100b57cec5SDimitry Andric       switch (Pred) {
421181ad6265SDimitry Andric       case FCmpInst::FCMP_OEQ:
421281ad6265SDimitry Andric       case FCmpInst::FCMP_UEQ:
42130b57cec5SDimitry Andric         // minnum(X, LesserC)  == C --> false
42140b57cec5SDimitry Andric         // maxnum(X, GreaterC) == C --> false
42150b57cec5SDimitry Andric         return getFalse(RetTy);
421681ad6265SDimitry Andric       case FCmpInst::FCMP_ONE:
421781ad6265SDimitry Andric       case FCmpInst::FCMP_UNE:
42180b57cec5SDimitry Andric         // minnum(X, LesserC)  != C --> true
42190b57cec5SDimitry Andric         // maxnum(X, GreaterC) != C --> true
42200b57cec5SDimitry Andric         return getTrue(RetTy);
422181ad6265SDimitry Andric       case FCmpInst::FCMP_OGE:
422281ad6265SDimitry Andric       case FCmpInst::FCMP_UGE:
422381ad6265SDimitry Andric       case FCmpInst::FCMP_OGT:
422481ad6265SDimitry Andric       case FCmpInst::FCMP_UGT:
42250b57cec5SDimitry Andric         // minnum(X, LesserC)  >= C --> false
42260b57cec5SDimitry Andric         // minnum(X, LesserC)  >  C --> false
42270b57cec5SDimitry Andric         // maxnum(X, GreaterC) >= C --> true
42280b57cec5SDimitry Andric         // maxnum(X, GreaterC) >  C --> true
42290b57cec5SDimitry Andric         return ConstantInt::get(RetTy, IsMaxNum);
423081ad6265SDimitry Andric       case FCmpInst::FCMP_OLE:
423181ad6265SDimitry Andric       case FCmpInst::FCMP_ULE:
423281ad6265SDimitry Andric       case FCmpInst::FCMP_OLT:
423381ad6265SDimitry Andric       case FCmpInst::FCMP_ULT:
42340b57cec5SDimitry Andric         // minnum(X, LesserC)  <= C --> true
42350b57cec5SDimitry Andric         // minnum(X, LesserC)  <  C --> true
42360b57cec5SDimitry Andric         // maxnum(X, GreaterC) <= C --> false
42370b57cec5SDimitry Andric         // maxnum(X, GreaterC) <  C --> false
42380b57cec5SDimitry Andric         return ConstantInt::get(RetTy, !IsMaxNum);
42390b57cec5SDimitry Andric       default:
42400b57cec5SDimitry Andric         // TRUE/FALSE/ORD/UNO should be handled before this.
42410b57cec5SDimitry Andric         llvm_unreachable("Unexpected fcmp predicate");
42420b57cec5SDimitry Andric       }
42430b57cec5SDimitry Andric     }
42440b57cec5SDimitry Andric   }
42450b57cec5SDimitry Andric 
42465f757f3fSDimitry Andric   // TODO: Could fold this with above if there were a matcher which returned all
42475f757f3fSDimitry Andric   // classes in a non-splat vector.
42480b57cec5SDimitry Andric   if (match(RHS, m_AnyZeroFP())) {
42490b57cec5SDimitry Andric     switch (Pred) {
42500b57cec5SDimitry Andric     case FCmpInst::FCMP_OGE:
425106c3fb27SDimitry Andric     case FCmpInst::FCMP_ULT: {
42525f757f3fSDimitry Andric       FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
42535f757f3fSDimitry Andric       if (!FMF.noNaNs())
42545f757f3fSDimitry Andric         Interested |= fcNan;
42555f757f3fSDimitry Andric 
42565f757f3fSDimitry Andric       KnownFPClass Known = computeLHSClass(Interested);
425706c3fb27SDimitry Andric 
42580b57cec5SDimitry Andric       // Positive or zero X >= 0.0 --> true
42590b57cec5SDimitry Andric       // Positive or zero X <  0.0 --> false
426006c3fb27SDimitry Andric       if ((FMF.noNaNs() || Known.isKnownNeverNaN()) &&
426106c3fb27SDimitry Andric           Known.cannotBeOrderedLessThanZero())
42620b57cec5SDimitry Andric         return Pred == FCmpInst::FCMP_OGE ? getTrue(RetTy) : getFalse(RetTy);
42630b57cec5SDimitry Andric       break;
426406c3fb27SDimitry Andric     }
42650b57cec5SDimitry Andric     case FCmpInst::FCMP_UGE:
42665f757f3fSDimitry Andric     case FCmpInst::FCMP_OLT: {
42675f757f3fSDimitry Andric       FPClassTest Interested = KnownFPClass::OrderedLessThanZeroMask;
42685f757f3fSDimitry Andric       KnownFPClass Known = computeLHSClass(Interested);
42695f757f3fSDimitry Andric 
42700b57cec5SDimitry Andric       // Positive or zero or nan X >= 0.0 --> true
42710b57cec5SDimitry Andric       // Positive or zero or nan X <  0.0 --> false
42725f757f3fSDimitry Andric       if (Known.cannotBeOrderedLessThanZero())
42730b57cec5SDimitry Andric         return Pred == FCmpInst::FCMP_UGE ? getTrue(RetTy) : getFalse(RetTy);
42740b57cec5SDimitry Andric       break;
42755f757f3fSDimitry Andric     }
42760b57cec5SDimitry Andric     default:
42770b57cec5SDimitry Andric       break;
42780b57cec5SDimitry Andric     }
42790b57cec5SDimitry Andric   }
42800b57cec5SDimitry Andric 
42810b57cec5SDimitry Andric   // If the comparison is with the result of a select instruction, check whether
42820b57cec5SDimitry Andric   // comparing with either branch of the select always yields the same value.
42830b57cec5SDimitry Andric   if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))
428481ad6265SDimitry Andric     if (Value *V = threadCmpOverSelect(Pred, LHS, RHS, Q, MaxRecurse))
42850b57cec5SDimitry Andric       return V;
42860b57cec5SDimitry Andric 
42870b57cec5SDimitry Andric   // If the comparison is with the result of a phi instruction, check whether
42880b57cec5SDimitry Andric   // doing the compare with each incoming phi value yields a common result.
42890b57cec5SDimitry Andric   if (isa<PHINode>(LHS) || isa<PHINode>(RHS))
429081ad6265SDimitry Andric     if (Value *V = threadCmpOverPHI(Pred, LHS, RHS, Q, MaxRecurse))
42910b57cec5SDimitry Andric       return V;
42920b57cec5SDimitry Andric 
42930b57cec5SDimitry Andric   return nullptr;
42940b57cec5SDimitry Andric }
42950b57cec5SDimitry Andric 
429681ad6265SDimitry Andric Value *llvm::simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
42970b57cec5SDimitry Andric                               FastMathFlags FMF, const SimplifyQuery &Q) {
429881ad6265SDimitry Andric   return ::simplifyFCmpInst(Predicate, LHS, RHS, FMF, Q, RecursionLimit);
42990b57cec5SDimitry Andric }
43000b57cec5SDimitry Andric 
4301fe6060f1SDimitry Andric static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43020b57cec5SDimitry Andric                                      const SimplifyQuery &Q,
430316d6b3b3SDimitry Andric                                      bool AllowRefinement,
43045f757f3fSDimitry Andric                                      SmallVectorImpl<Instruction *> *DropFlags,
43050b57cec5SDimitry Andric                                      unsigned MaxRecurse) {
4306*0fca6ea1SDimitry Andric   assert((AllowRefinement || !Q.CanUseUndef) &&
4307*0fca6ea1SDimitry Andric          "If AllowRefinement=false then CanUseUndef=false");
4308*0fca6ea1SDimitry Andric 
43090b57cec5SDimitry Andric   // Trivial replacement.
43100b57cec5SDimitry Andric   if (V == Op)
43110b57cec5SDimitry Andric     return RepOp;
43120b57cec5SDimitry Andric 
431306c3fb27SDimitry Andric   if (!MaxRecurse--)
431406c3fb27SDimitry Andric     return nullptr;
431506c3fb27SDimitry Andric 
43160b57cec5SDimitry Andric   // We cannot replace a constant, and shouldn't even try.
43170b57cec5SDimitry Andric   if (isa<Constant>(Op))
43180b57cec5SDimitry Andric     return nullptr;
43190b57cec5SDimitry Andric 
43200b57cec5SDimitry Andric   auto *I = dyn_cast<Instruction>(V);
432106c3fb27SDimitry Andric   if (!I)
432206c3fb27SDimitry Andric     return nullptr;
432306c3fb27SDimitry Andric 
432406c3fb27SDimitry Andric   // The arguments of a phi node might refer to a value from a previous
432506c3fb27SDimitry Andric   // cycle iteration.
432606c3fb27SDimitry Andric   if (isa<PHINode>(I))
43270b57cec5SDimitry Andric     return nullptr;
43280b57cec5SDimitry Andric 
4329bdd1243dSDimitry Andric   if (Op->getType()->isVectorTy()) {
4330bdd1243dSDimitry Andric     // For vector types, the simplification must hold per-lane, so forbid
4331bdd1243dSDimitry Andric     // potentially cross-lane operations like shufflevector.
433206c3fb27SDimitry Andric     if (!I->getType()->isVectorTy() || isa<ShuffleVectorInst>(I) ||
43331db9f3b2SDimitry Andric         isa<CallBase>(I) || isa<BitCastInst>(I))
4334bdd1243dSDimitry Andric       return nullptr;
4335bdd1243dSDimitry Andric   }
4336bdd1243dSDimitry Andric 
43375f757f3fSDimitry Andric   // Don't fold away llvm.is.constant checks based on assumptions.
43385f757f3fSDimitry Andric   if (match(I, m_Intrinsic<Intrinsic::is_constant>()))
43395f757f3fSDimitry Andric     return nullptr;
43405f757f3fSDimitry Andric 
43413a079333SDimitry Andric   // Don't simplify freeze.
43423a079333SDimitry Andric   if (isa<FreezeInst>(I))
43433a079333SDimitry Andric     return nullptr;
43443a079333SDimitry Andric 
4345fe6060f1SDimitry Andric   // Replace Op with RepOp in instruction operands.
434606c3fb27SDimitry Andric   SmallVector<Value *, 8> NewOps;
434706c3fb27SDimitry Andric   bool AnyReplaced = false;
434806c3fb27SDimitry Andric   for (Value *InstOp : I->operands()) {
434906c3fb27SDimitry Andric     if (Value *NewInstOp = simplifyWithOpReplaced(
43505f757f3fSDimitry Andric             InstOp, Op, RepOp, Q, AllowRefinement, DropFlags, MaxRecurse)) {
435106c3fb27SDimitry Andric       NewOps.push_back(NewInstOp);
435206c3fb27SDimitry Andric       AnyReplaced = InstOp != NewInstOp;
435306c3fb27SDimitry Andric     } else {
435406c3fb27SDimitry Andric       NewOps.push_back(InstOp);
435506c3fb27SDimitry Andric     }
4356*0fca6ea1SDimitry Andric 
4357*0fca6ea1SDimitry Andric     // Bail out if any operand is undef and SimplifyQuery disables undef
4358*0fca6ea1SDimitry Andric     // simplification. Constant folding currently doesn't respect this option.
4359*0fca6ea1SDimitry Andric     if (isa<UndefValue>(NewOps.back()) && !Q.CanUseUndef)
4360*0fca6ea1SDimitry Andric       return nullptr;
436106c3fb27SDimitry Andric   }
436206c3fb27SDimitry Andric 
436306c3fb27SDimitry Andric   if (!AnyReplaced)
436406c3fb27SDimitry Andric     return nullptr;
43650b57cec5SDimitry Andric 
4366fe6060f1SDimitry Andric   if (!AllowRefinement) {
4367fe6060f1SDimitry Andric     // General InstSimplify functions may refine the result, e.g. by returning
4368fe6060f1SDimitry Andric     // a constant for a potentially poison value. To avoid this, implement only
4369fe6060f1SDimitry Andric     // a few non-refining but profitable transforms here.
4370fe6060f1SDimitry Andric 
4371fe6060f1SDimitry Andric     if (auto *BO = dyn_cast<BinaryOperator>(I)) {
4372fe6060f1SDimitry Andric       unsigned Opcode = BO->getOpcode();
4373fe6060f1SDimitry Andric       // id op x -> x, x op id -> x
4374fe6060f1SDimitry Andric       if (NewOps[0] == ConstantExpr::getBinOpIdentity(Opcode, I->getType()))
4375fe6060f1SDimitry Andric         return NewOps[1];
4376fe6060f1SDimitry Andric       if (NewOps[1] == ConstantExpr::getBinOpIdentity(Opcode, I->getType(),
4377fe6060f1SDimitry Andric                                                       /* RHS */ true))
4378fe6060f1SDimitry Andric         return NewOps[0];
4379fe6060f1SDimitry Andric 
4380fe6060f1SDimitry Andric       // x & x -> x, x | x -> x
4381fe6060f1SDimitry Andric       if ((Opcode == Instruction::And || Opcode == Instruction::Or) &&
43825f757f3fSDimitry Andric           NewOps[0] == NewOps[1]) {
43835f757f3fSDimitry Andric         // or disjoint x, x results in poison.
43845f757f3fSDimitry Andric         if (auto *PDI = dyn_cast<PossiblyDisjointInst>(BO)) {
43855f757f3fSDimitry Andric           if (PDI->isDisjoint()) {
43865f757f3fSDimitry Andric             if (!DropFlags)
43875f757f3fSDimitry Andric               return nullptr;
43885f757f3fSDimitry Andric             DropFlags->push_back(BO);
43895f757f3fSDimitry Andric           }
43905f757f3fSDimitry Andric         }
4391fe6060f1SDimitry Andric         return NewOps[0];
43925f757f3fSDimitry Andric       }
439306c3fb27SDimitry Andric 
439406c3fb27SDimitry Andric       // x - x -> 0, x ^ x -> 0. This is non-refining, because x is non-poison
439506c3fb27SDimitry Andric       // by assumption and this case never wraps, so nowrap flags can be
439606c3fb27SDimitry Andric       // ignored.
439706c3fb27SDimitry Andric       if ((Opcode == Instruction::Sub || Opcode == Instruction::Xor) &&
439806c3fb27SDimitry Andric           NewOps[0] == RepOp && NewOps[1] == RepOp)
439906c3fb27SDimitry Andric         return Constant::getNullValue(I->getType());
440006c3fb27SDimitry Andric 
440106c3fb27SDimitry Andric       // If we are substituting an absorber constant into a binop and extra
440206c3fb27SDimitry Andric       // poison can't leak if we remove the select -- because both operands of
440306c3fb27SDimitry Andric       // the binop are based on the same value -- then it may be safe to replace
440406c3fb27SDimitry Andric       // the value with the absorber constant. Examples:
440506c3fb27SDimitry Andric       // (Op == 0) ? 0 : (Op & -Op)            --> Op & -Op
440606c3fb27SDimitry Andric       // (Op == 0) ? 0 : (Op * (binop Op, C))  --> Op * (binop Op, C)
440706c3fb27SDimitry Andric       // (Op == -1) ? -1 : (Op | (binop C, Op) --> Op | (binop C, Op)
440806c3fb27SDimitry Andric       Constant *Absorber =
440906c3fb27SDimitry Andric           ConstantExpr::getBinOpAbsorber(Opcode, I->getType());
441006c3fb27SDimitry Andric       if ((NewOps[0] == Absorber || NewOps[1] == Absorber) &&
441106c3fb27SDimitry Andric           impliesPoison(BO, Op))
441206c3fb27SDimitry Andric         return Absorber;
4413fe6060f1SDimitry Andric     }
4414fe6060f1SDimitry Andric 
441506c3fb27SDimitry Andric     if (isa<GetElementPtrInst>(I)) {
441606c3fb27SDimitry Andric       // getelementptr x, 0 -> x.
441706c3fb27SDimitry Andric       // This never returns poison, even if inbounds is set.
441806c3fb27SDimitry Andric       if (NewOps.size() == 2 && match(NewOps[1], m_Zero()))
4419fe6060f1SDimitry Andric         return NewOps[0];
4420fe6060f1SDimitry Andric     }
442106c3fb27SDimitry Andric   } else {
4422e8d8bef9SDimitry Andric     // The simplification queries below may return the original value. Consider:
4423e8d8bef9SDimitry Andric     //   %div = udiv i32 %arg, %arg2
4424e8d8bef9SDimitry Andric     //   %mul = mul nsw i32 %div, %arg2
4425e8d8bef9SDimitry Andric     //   %cmp = icmp eq i32 %mul, %arg
4426e8d8bef9SDimitry Andric     //   %sel = select i1 %cmp, i32 %div, i32 undef
4427e8d8bef9SDimitry Andric     // Replacing %arg by %mul, %div becomes "udiv i32 %mul, %arg2", which
4428e8d8bef9SDimitry Andric     // simplifies back to %arg. This can only happen because %mul does not
4429e8d8bef9SDimitry Andric     // dominate %div. To ensure a consistent return value contract, we make sure
4430e8d8bef9SDimitry Andric     // that this case returns nullptr as well.
4431e8d8bef9SDimitry Andric     auto PreventSelfSimplify = [V](Value *Simplified) {
4432e8d8bef9SDimitry Andric       return Simplified != V ? Simplified : nullptr;
4433e8d8bef9SDimitry Andric     };
4434e8d8bef9SDimitry Andric 
443506c3fb27SDimitry Andric     return PreventSelfSimplify(
443606c3fb27SDimitry Andric         ::simplifyInstructionWithOperands(I, NewOps, Q, MaxRecurse));
4437fe6060f1SDimitry Andric   }
44380b57cec5SDimitry Andric 
44390b57cec5SDimitry Andric   // If all operands are constant after substituting Op for RepOp then we can
44400b57cec5SDimitry Andric   // constant fold the instruction.
44410b57cec5SDimitry Andric   SmallVector<Constant *, 8> ConstOps;
4442fe6060f1SDimitry Andric   for (Value *NewOp : NewOps) {
4443fe6060f1SDimitry Andric     if (Constant *ConstOp = dyn_cast<Constant>(NewOp))
4444fe6060f1SDimitry Andric       ConstOps.push_back(ConstOp);
44450b57cec5SDimitry Andric     else
4446fe6060f1SDimitry Andric       return nullptr;
44470b57cec5SDimitry Andric   }
44480b57cec5SDimitry Andric 
4449fe6060f1SDimitry Andric   // Consider:
4450fe6060f1SDimitry Andric   //   %cmp = icmp eq i32 %x, 2147483647
4451fe6060f1SDimitry Andric   //   %add = add nsw i32 %x, 1
4452fe6060f1SDimitry Andric   //   %sel = select i1 %cmp, i32 -2147483648, i32 %add
4453fe6060f1SDimitry Andric   //
4454fe6060f1SDimitry Andric   // We can't replace %sel with %add unless we strip away the flags (which
4455fe6060f1SDimitry Andric   // will be done in InstCombine).
4456fe6060f1SDimitry Andric   // TODO: This may be unsound, because it only catches some forms of
4457fe6060f1SDimitry Andric   // refinement.
44585f757f3fSDimitry Andric   if (!AllowRefinement) {
44595f757f3fSDimitry Andric     if (canCreatePoison(cast<Operator>(I), !DropFlags)) {
44605f757f3fSDimitry Andric       // abs cannot create poison if the value is known to never be int_min.
44615f757f3fSDimitry Andric       if (auto *II = dyn_cast<IntrinsicInst>(I);
44625f757f3fSDimitry Andric           II && II->getIntrinsicID() == Intrinsic::abs) {
44635f757f3fSDimitry Andric         if (!ConstOps[0]->isNotMinSignedValue())
4464fe6060f1SDimitry Andric           return nullptr;
44655f757f3fSDimitry Andric       } else
44665f757f3fSDimitry Andric         return nullptr;
44675f757f3fSDimitry Andric     }
44685f757f3fSDimitry Andric     Constant *Res = ConstantFoldInstOperands(I, ConstOps, Q.DL, Q.TLI);
4469*0fca6ea1SDimitry Andric     if (DropFlags && Res && I->hasPoisonGeneratingAnnotations())
44705f757f3fSDimitry Andric       DropFlags->push_back(I);
44715f757f3fSDimitry Andric     return Res;
44725f757f3fSDimitry Andric   }
4473fe6060f1SDimitry Andric 
44740b57cec5SDimitry Andric   return ConstantFoldInstOperands(I, ConstOps, Q.DL, Q.TLI);
44750b57cec5SDimitry Andric }
44760b57cec5SDimitry Andric 
4477fe6060f1SDimitry Andric Value *llvm::simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
447816d6b3b3SDimitry Andric                                     const SimplifyQuery &Q,
44795f757f3fSDimitry Andric                                     bool AllowRefinement,
44805f757f3fSDimitry Andric                                     SmallVectorImpl<Instruction *> *DropFlags) {
4481*0fca6ea1SDimitry Andric   // If refinement is disabled, also disable undef simplifications (which are
4482*0fca6ea1SDimitry Andric   // always refinements) in SimplifyQuery.
4483*0fca6ea1SDimitry Andric   if (!AllowRefinement)
4484*0fca6ea1SDimitry Andric     return ::simplifyWithOpReplaced(V, Op, RepOp, Q.getWithoutUndef(),
4485*0fca6ea1SDimitry Andric                                     AllowRefinement, DropFlags, RecursionLimit);
44865f757f3fSDimitry Andric   return ::simplifyWithOpReplaced(V, Op, RepOp, Q, AllowRefinement, DropFlags,
448716d6b3b3SDimitry Andric                                   RecursionLimit);
448816d6b3b3SDimitry Andric }
448916d6b3b3SDimitry Andric 
44900b57cec5SDimitry Andric /// Try to simplify a select instruction when its condition operand is an
44910b57cec5SDimitry Andric /// integer comparison where one operand of the compare is a constant.
44920b57cec5SDimitry Andric static Value *simplifySelectBitTest(Value *TrueVal, Value *FalseVal, Value *X,
44930b57cec5SDimitry Andric                                     const APInt *Y, bool TrueWhenUnset) {
44940b57cec5SDimitry Andric   const APInt *C;
44950b57cec5SDimitry Andric 
44960b57cec5SDimitry Andric   // (X & Y) == 0 ? X & ~Y : X  --> X
44970b57cec5SDimitry Andric   // (X & Y) != 0 ? X & ~Y : X  --> X & ~Y
44980b57cec5SDimitry Andric   if (FalseVal == X && match(TrueVal, m_And(m_Specific(X), m_APInt(C))) &&
44990b57cec5SDimitry Andric       *Y == ~*C)
45000b57cec5SDimitry Andric     return TrueWhenUnset ? FalseVal : TrueVal;
45010b57cec5SDimitry Andric 
45020b57cec5SDimitry Andric   // (X & Y) == 0 ? X : X & ~Y  --> X & ~Y
45030b57cec5SDimitry Andric   // (X & Y) != 0 ? X : X & ~Y  --> X
45040b57cec5SDimitry Andric   if (TrueVal == X && match(FalseVal, m_And(m_Specific(X), m_APInt(C))) &&
45050b57cec5SDimitry Andric       *Y == ~*C)
45060b57cec5SDimitry Andric     return TrueWhenUnset ? FalseVal : TrueVal;
45070b57cec5SDimitry Andric 
45080b57cec5SDimitry Andric   if (Y->isPowerOf2()) {
45090b57cec5SDimitry Andric     // (X & Y) == 0 ? X | Y : X  --> X | Y
45100b57cec5SDimitry Andric     // (X & Y) != 0 ? X | Y : X  --> X
45110b57cec5SDimitry Andric     if (FalseVal == X && match(TrueVal, m_Or(m_Specific(X), m_APInt(C))) &&
45125f757f3fSDimitry Andric         *Y == *C) {
45135f757f3fSDimitry Andric       // We can't return the or if it has the disjoint flag.
45145f757f3fSDimitry Andric       if (TrueWhenUnset && cast<PossiblyDisjointInst>(TrueVal)->isDisjoint())
45155f757f3fSDimitry Andric         return nullptr;
45160b57cec5SDimitry Andric       return TrueWhenUnset ? TrueVal : FalseVal;
45175f757f3fSDimitry Andric     }
45180b57cec5SDimitry Andric 
45190b57cec5SDimitry Andric     // (X & Y) == 0 ? X : X | Y  --> X
45200b57cec5SDimitry Andric     // (X & Y) != 0 ? X : X | Y  --> X | Y
45210b57cec5SDimitry Andric     if (TrueVal == X && match(FalseVal, m_Or(m_Specific(X), m_APInt(C))) &&
45225f757f3fSDimitry Andric         *Y == *C) {
45235f757f3fSDimitry Andric       // We can't return the or if it has the disjoint flag.
45245f757f3fSDimitry Andric       if (!TrueWhenUnset && cast<PossiblyDisjointInst>(FalseVal)->isDisjoint())
45255f757f3fSDimitry Andric         return nullptr;
45260b57cec5SDimitry Andric       return TrueWhenUnset ? TrueVal : FalseVal;
45270b57cec5SDimitry Andric     }
45285f757f3fSDimitry Andric   }
45290b57cec5SDimitry Andric 
45300b57cec5SDimitry Andric   return nullptr;
45310b57cec5SDimitry Andric }
45320b57cec5SDimitry Andric 
4533bdd1243dSDimitry Andric static Value *simplifyCmpSelOfMaxMin(Value *CmpLHS, Value *CmpRHS,
4534bdd1243dSDimitry Andric                                      ICmpInst::Predicate Pred, Value *TVal,
4535bdd1243dSDimitry Andric                                      Value *FVal) {
4536bdd1243dSDimitry Andric   // Canonicalize common cmp+sel operand as CmpLHS.
4537bdd1243dSDimitry Andric   if (CmpRHS == TVal || CmpRHS == FVal) {
4538bdd1243dSDimitry Andric     std::swap(CmpLHS, CmpRHS);
4539bdd1243dSDimitry Andric     Pred = ICmpInst::getSwappedPredicate(Pred);
4540bdd1243dSDimitry Andric   }
4541bdd1243dSDimitry Andric 
4542bdd1243dSDimitry Andric   // Canonicalize common cmp+sel operand as TVal.
4543bdd1243dSDimitry Andric   if (CmpLHS == FVal) {
4544bdd1243dSDimitry Andric     std::swap(TVal, FVal);
4545bdd1243dSDimitry Andric     Pred = ICmpInst::getInversePredicate(Pred);
4546bdd1243dSDimitry Andric   }
4547bdd1243dSDimitry Andric 
4548bdd1243dSDimitry Andric   // A vector select may be shuffling together elements that are equivalent
4549bdd1243dSDimitry Andric   // based on the max/min/select relationship.
4550bdd1243dSDimitry Andric   Value *X = CmpLHS, *Y = CmpRHS;
4551bdd1243dSDimitry Andric   bool PeekedThroughSelectShuffle = false;
4552bdd1243dSDimitry Andric   auto *Shuf = dyn_cast<ShuffleVectorInst>(FVal);
4553bdd1243dSDimitry Andric   if (Shuf && Shuf->isSelect()) {
4554bdd1243dSDimitry Andric     if (Shuf->getOperand(0) == Y)
4555bdd1243dSDimitry Andric       FVal = Shuf->getOperand(1);
4556bdd1243dSDimitry Andric     else if (Shuf->getOperand(1) == Y)
4557bdd1243dSDimitry Andric       FVal = Shuf->getOperand(0);
4558bdd1243dSDimitry Andric     else
4559bdd1243dSDimitry Andric       return nullptr;
4560bdd1243dSDimitry Andric     PeekedThroughSelectShuffle = true;
4561bdd1243dSDimitry Andric   }
4562bdd1243dSDimitry Andric 
4563bdd1243dSDimitry Andric   // (X pred Y) ? X : max/min(X, Y)
4564bdd1243dSDimitry Andric   auto *MMI = dyn_cast<MinMaxIntrinsic>(FVal);
4565bdd1243dSDimitry Andric   if (!MMI || TVal != X ||
4566bdd1243dSDimitry Andric       !match(FVal, m_c_MaxOrMin(m_Specific(X), m_Specific(Y))))
4567bdd1243dSDimitry Andric     return nullptr;
4568bdd1243dSDimitry Andric 
4569bdd1243dSDimitry Andric   // (X >  Y) ? X : max(X, Y) --> max(X, Y)
4570bdd1243dSDimitry Andric   // (X >= Y) ? X : max(X, Y) --> max(X, Y)
4571bdd1243dSDimitry Andric   // (X <  Y) ? X : min(X, Y) --> min(X, Y)
4572bdd1243dSDimitry Andric   // (X <= Y) ? X : min(X, Y) --> min(X, Y)
4573bdd1243dSDimitry Andric   //
4574bdd1243dSDimitry Andric   // The equivalence allows a vector select (shuffle) of max/min and Y. Ex:
4575bdd1243dSDimitry Andric   // (X > Y) ? X : (Z ? max(X, Y) : Y)
4576bdd1243dSDimitry Andric   // If Z is true, this reduces as above, and if Z is false:
4577bdd1243dSDimitry Andric   // (X > Y) ? X : Y --> max(X, Y)
4578bdd1243dSDimitry Andric   ICmpInst::Predicate MMPred = MMI->getPredicate();
4579bdd1243dSDimitry Andric   if (MMPred == CmpInst::getStrictPredicate(Pred))
4580bdd1243dSDimitry Andric     return MMI;
4581bdd1243dSDimitry Andric 
4582bdd1243dSDimitry Andric   // Other transforms are not valid with a shuffle.
4583bdd1243dSDimitry Andric   if (PeekedThroughSelectShuffle)
4584bdd1243dSDimitry Andric     return nullptr;
4585bdd1243dSDimitry Andric 
4586bdd1243dSDimitry Andric   // (X == Y) ? X : max/min(X, Y) --> max/min(X, Y)
4587bdd1243dSDimitry Andric   if (Pred == CmpInst::ICMP_EQ)
4588bdd1243dSDimitry Andric     return MMI;
4589bdd1243dSDimitry Andric 
4590bdd1243dSDimitry Andric   // (X != Y) ? X : max/min(X, Y) --> X
4591bdd1243dSDimitry Andric   if (Pred == CmpInst::ICMP_NE)
4592bdd1243dSDimitry Andric     return X;
4593bdd1243dSDimitry Andric 
4594bdd1243dSDimitry Andric   // (X <  Y) ? X : max(X, Y) --> X
4595bdd1243dSDimitry Andric   // (X <= Y) ? X : max(X, Y) --> X
4596bdd1243dSDimitry Andric   // (X >  Y) ? X : min(X, Y) --> X
4597bdd1243dSDimitry Andric   // (X >= Y) ? X : min(X, Y) --> X
4598bdd1243dSDimitry Andric   ICmpInst::Predicate InvPred = CmpInst::getInversePredicate(Pred);
4599bdd1243dSDimitry Andric   if (MMPred == CmpInst::getStrictPredicate(InvPred))
4600bdd1243dSDimitry Andric     return X;
4601bdd1243dSDimitry Andric 
4602bdd1243dSDimitry Andric   return nullptr;
4603bdd1243dSDimitry Andric }
4604bdd1243dSDimitry Andric 
46050b57cec5SDimitry Andric /// An alternative way to test if a bit is set or not uses sgt/slt instead of
46060b57cec5SDimitry Andric /// eq/ne.
46070b57cec5SDimitry Andric static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS,
46080b57cec5SDimitry Andric                                            ICmpInst::Predicate Pred,
46090b57cec5SDimitry Andric                                            Value *TrueVal, Value *FalseVal) {
46100b57cec5SDimitry Andric   Value *X;
46110b57cec5SDimitry Andric   APInt Mask;
46120b57cec5SDimitry Andric   if (!decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, X, Mask))
46130b57cec5SDimitry Andric     return nullptr;
46140b57cec5SDimitry Andric 
46150b57cec5SDimitry Andric   return simplifySelectBitTest(TrueVal, FalseVal, X, &Mask,
46160b57cec5SDimitry Andric                                Pred == ICmpInst::ICMP_EQ);
46170b57cec5SDimitry Andric }
46180b57cec5SDimitry Andric 
46190b57cec5SDimitry Andric /// Try to simplify a select instruction when its condition operand is an
462006c3fb27SDimitry Andric /// integer equality comparison.
462106c3fb27SDimitry Andric static Value *simplifySelectWithICmpEq(Value *CmpLHS, Value *CmpRHS,
462206c3fb27SDimitry Andric                                        Value *TrueVal, Value *FalseVal,
462306c3fb27SDimitry Andric                                        const SimplifyQuery &Q,
462406c3fb27SDimitry Andric                                        unsigned MaxRecurse) {
4625*0fca6ea1SDimitry Andric   if (simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q.getWithoutUndef(),
462606c3fb27SDimitry Andric                              /* AllowRefinement */ false,
46275f757f3fSDimitry Andric                              /* DropFlags */ nullptr, MaxRecurse) == TrueVal)
462806c3fb27SDimitry Andric     return FalseVal;
462906c3fb27SDimitry Andric   if (simplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q,
463006c3fb27SDimitry Andric                              /* AllowRefinement */ true,
46315f757f3fSDimitry Andric                              /* DropFlags */ nullptr, MaxRecurse) == FalseVal)
463206c3fb27SDimitry Andric     return FalseVal;
463306c3fb27SDimitry Andric 
463406c3fb27SDimitry Andric   return nullptr;
463506c3fb27SDimitry Andric }
463606c3fb27SDimitry Andric 
463706c3fb27SDimitry Andric /// Try to simplify a select instruction when its condition operand is an
46380b57cec5SDimitry Andric /// integer comparison.
46390b57cec5SDimitry Andric static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
464081ad6265SDimitry Andric                                          Value *FalseVal,
464181ad6265SDimitry Andric                                          const SimplifyQuery &Q,
46420b57cec5SDimitry Andric                                          unsigned MaxRecurse) {
46430b57cec5SDimitry Andric   ICmpInst::Predicate Pred;
46440b57cec5SDimitry Andric   Value *CmpLHS, *CmpRHS;
46450b57cec5SDimitry Andric   if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
46460b57cec5SDimitry Andric     return nullptr;
46470b57cec5SDimitry Andric 
4648bdd1243dSDimitry Andric   if (Value *V = simplifyCmpSelOfMaxMin(CmpLHS, CmpRHS, Pred, TrueVal, FalseVal))
4649bdd1243dSDimitry Andric     return V;
4650bdd1243dSDimitry Andric 
465116d6b3b3SDimitry Andric   // Canonicalize ne to eq predicate.
465216d6b3b3SDimitry Andric   if (Pred == ICmpInst::ICMP_NE) {
465316d6b3b3SDimitry Andric     Pred = ICmpInst::ICMP_EQ;
465416d6b3b3SDimitry Andric     std::swap(TrueVal, FalseVal);
465516d6b3b3SDimitry Andric   }
465616d6b3b3SDimitry Andric 
46576e75b2fbSDimitry Andric   // Check for integer min/max with a limit constant:
46586e75b2fbSDimitry Andric   // X > MIN_INT ? X : MIN_INT --> X
46596e75b2fbSDimitry Andric   // X < MAX_INT ? X : MAX_INT --> X
46606e75b2fbSDimitry Andric   if (TrueVal->getType()->isIntOrIntVectorTy()) {
46616e75b2fbSDimitry Andric     Value *X, *Y;
46626e75b2fbSDimitry Andric     SelectPatternFlavor SPF =
46636e75b2fbSDimitry Andric         matchDecomposedSelectPattern(cast<ICmpInst>(CondVal), TrueVal, FalseVal,
466481ad6265SDimitry Andric                                      X, Y)
466581ad6265SDimitry Andric             .Flavor;
46666e75b2fbSDimitry Andric     if (SelectPatternResult::isMinOrMax(SPF) && Pred == getMinMaxPred(SPF)) {
46676e75b2fbSDimitry Andric       APInt LimitC = getMinMaxLimit(getInverseMinMaxFlavor(SPF),
46686e75b2fbSDimitry Andric                                     X->getType()->getScalarSizeInBits());
46696e75b2fbSDimitry Andric       if (match(Y, m_SpecificInt(LimitC)))
46706e75b2fbSDimitry Andric         return X;
46716e75b2fbSDimitry Andric     }
46726e75b2fbSDimitry Andric   }
46736e75b2fbSDimitry Andric 
467416d6b3b3SDimitry Andric   if (Pred == ICmpInst::ICMP_EQ && match(CmpRHS, m_Zero())) {
46750b57cec5SDimitry Andric     Value *X;
46760b57cec5SDimitry Andric     const APInt *Y;
46770b57cec5SDimitry Andric     if (match(CmpLHS, m_And(m_Value(X), m_APInt(Y))))
46780b57cec5SDimitry Andric       if (Value *V = simplifySelectBitTest(TrueVal, FalseVal, X, Y,
467916d6b3b3SDimitry Andric                                            /*TrueWhenUnset=*/true))
46800b57cec5SDimitry Andric         return V;
46810b57cec5SDimitry Andric 
46820b57cec5SDimitry Andric     // Test for a bogus zero-shift-guard-op around funnel-shift or rotate.
46830b57cec5SDimitry Andric     Value *ShAmt;
4684e8d8bef9SDimitry Andric     auto isFsh = m_CombineOr(m_FShl(m_Value(X), m_Value(), m_Value(ShAmt)),
4685e8d8bef9SDimitry Andric                              m_FShr(m_Value(), m_Value(X), m_Value(ShAmt)));
46860b57cec5SDimitry Andric     // (ShAmt == 0) ? fshl(X, *, ShAmt) : X --> X
46870b57cec5SDimitry Andric     // (ShAmt == 0) ? fshr(*, X, ShAmt) : X --> X
468816d6b3b3SDimitry Andric     if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt)
46890b57cec5SDimitry Andric       return X;
46900b57cec5SDimitry Andric 
46910b57cec5SDimitry Andric     // Test for a zero-shift-guard-op around rotates. These are used to
46920b57cec5SDimitry Andric     // avoid UB from oversized shifts in raw IR rotate patterns, but the
46930b57cec5SDimitry Andric     // intrinsics do not have that problem.
46940b57cec5SDimitry Andric     // We do not allow this transform for the general funnel shift case because
46950b57cec5SDimitry Andric     // that would not preserve the poison safety of the original code.
4696e8d8bef9SDimitry Andric     auto isRotate =
4697e8d8bef9SDimitry Andric         m_CombineOr(m_FShl(m_Value(X), m_Deferred(X), m_Value(ShAmt)),
4698e8d8bef9SDimitry Andric                     m_FShr(m_Value(X), m_Deferred(X), m_Value(ShAmt)));
46990b57cec5SDimitry Andric     // (ShAmt == 0) ? X : fshl(X, X, ShAmt) --> fshl(X, X, ShAmt)
47000b57cec5SDimitry Andric     // (ShAmt == 0) ? X : fshr(X, X, ShAmt) --> fshr(X, X, ShAmt)
47010b57cec5SDimitry Andric     if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&
47020b57cec5SDimitry Andric         Pred == ICmpInst::ICMP_EQ)
47030b57cec5SDimitry Andric       return FalseVal;
4704e8d8bef9SDimitry Andric 
4705e8d8bef9SDimitry Andric     // X == 0 ? abs(X) : -abs(X) --> -abs(X)
4706e8d8bef9SDimitry Andric     // X == 0 ? -abs(X) : abs(X) --> abs(X)
4707e8d8bef9SDimitry Andric     if (match(TrueVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))) &&
4708e8d8bef9SDimitry Andric         match(FalseVal, m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))))
4709e8d8bef9SDimitry Andric       return FalseVal;
4710e8d8bef9SDimitry Andric     if (match(TrueVal,
4711e8d8bef9SDimitry Andric               m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))) &&
4712e8d8bef9SDimitry Andric         match(FalseVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))))
4713e8d8bef9SDimitry Andric       return FalseVal;
47140b57cec5SDimitry Andric   }
47150b57cec5SDimitry Andric 
47160b57cec5SDimitry Andric   // Check for other compares that behave like bit test.
471781ad6265SDimitry Andric   if (Value *V =
471881ad6265SDimitry Andric           simplifySelectWithFakeICmpEq(CmpLHS, CmpRHS, Pred, TrueVal, FalseVal))
47190b57cec5SDimitry Andric     return V;
47200b57cec5SDimitry Andric 
472123408297SDimitry Andric   // If we have a scalar equality comparison, then we know the value in one of
472223408297SDimitry Andric   // the arms of the select. See if substituting this value into the arm and
47230b57cec5SDimitry Andric   // simplifying the result yields the same value as the other arm.
4724bdd1243dSDimitry Andric   if (Pred == ICmpInst::ICMP_EQ) {
472506c3fb27SDimitry Andric     if (Value *V = simplifySelectWithICmpEq(CmpLHS, CmpRHS, TrueVal, FalseVal,
472606c3fb27SDimitry Andric                                             Q, MaxRecurse))
472706c3fb27SDimitry Andric       return V;
472806c3fb27SDimitry Andric     if (Value *V = simplifySelectWithICmpEq(CmpRHS, CmpLHS, TrueVal, FalseVal,
472906c3fb27SDimitry Andric                                             Q, MaxRecurse))
473006c3fb27SDimitry Andric       return V;
473106c3fb27SDimitry Andric 
473206c3fb27SDimitry Andric     Value *X;
473306c3fb27SDimitry Andric     Value *Y;
473406c3fb27SDimitry Andric     // select((X | Y) == 0 ?  X : 0) --> 0 (commuted 2 ways)
473506c3fb27SDimitry Andric     if (match(CmpLHS, m_Or(m_Value(X), m_Value(Y))) &&
473606c3fb27SDimitry Andric         match(CmpRHS, m_Zero())) {
473706c3fb27SDimitry Andric       // (X | Y) == 0 implies X == 0 and Y == 0.
473806c3fb27SDimitry Andric       if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q,
473906c3fb27SDimitry Andric                                               MaxRecurse))
474006c3fb27SDimitry Andric         return V;
474106c3fb27SDimitry Andric       if (Value *V = simplifySelectWithICmpEq(Y, CmpRHS, TrueVal, FalseVal, Q,
474206c3fb27SDimitry Andric                                               MaxRecurse))
474306c3fb27SDimitry Andric         return V;
474406c3fb27SDimitry Andric     }
474506c3fb27SDimitry Andric 
474606c3fb27SDimitry Andric     // select((X & Y) == -1 ?  X : -1) --> -1 (commuted 2 ways)
474706c3fb27SDimitry Andric     if (match(CmpLHS, m_And(m_Value(X), m_Value(Y))) &&
474806c3fb27SDimitry Andric         match(CmpRHS, m_AllOnes())) {
474906c3fb27SDimitry Andric       // (X & Y) == -1 implies X == -1 and Y == -1.
475006c3fb27SDimitry Andric       if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q,
475106c3fb27SDimitry Andric                                               MaxRecurse))
475206c3fb27SDimitry Andric         return V;
475306c3fb27SDimitry Andric       if (Value *V = simplifySelectWithICmpEq(Y, CmpRHS, TrueVal, FalseVal, Q,
475406c3fb27SDimitry Andric                                               MaxRecurse))
475506c3fb27SDimitry Andric         return V;
475606c3fb27SDimitry Andric     }
47570b57cec5SDimitry Andric   }
47580b57cec5SDimitry Andric 
47590b57cec5SDimitry Andric   return nullptr;
47600b57cec5SDimitry Andric }
47610b57cec5SDimitry Andric 
47620b57cec5SDimitry Andric /// Try to simplify a select instruction when its condition operand is a
47630b57cec5SDimitry Andric /// floating-point comparison.
4764480093f4SDimitry Andric static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F,
4765480093f4SDimitry Andric                                      const SimplifyQuery &Q) {
47660b57cec5SDimitry Andric   FCmpInst::Predicate Pred;
47670b57cec5SDimitry Andric   if (!match(Cond, m_FCmp(Pred, m_Specific(T), m_Specific(F))) &&
47680b57cec5SDimitry Andric       !match(Cond, m_FCmp(Pred, m_Specific(F), m_Specific(T))))
47690b57cec5SDimitry Andric     return nullptr;
47700b57cec5SDimitry Andric 
4771480093f4SDimitry Andric   // This transform is safe if we do not have (do not care about) -0.0 or if
4772480093f4SDimitry Andric   // at least one operand is known to not be -0.0. Otherwise, the select can
4773480093f4SDimitry Andric   // change the sign of a zero operand.
477481ad6265SDimitry Andric   bool HasNoSignedZeros =
477581ad6265SDimitry Andric       Q.CxtI && isa<FPMathOperator>(Q.CxtI) && Q.CxtI->hasNoSignedZeros();
47760b57cec5SDimitry Andric   const APFloat *C;
4777480093f4SDimitry Andric   if (HasNoSignedZeros || (match(T, m_APFloat(C)) && C->isNonZero()) ||
47780b57cec5SDimitry Andric       (match(F, m_APFloat(C)) && C->isNonZero())) {
47790b57cec5SDimitry Andric     // (T == F) ? T : F --> F
47800b57cec5SDimitry Andric     // (F == T) ? T : F --> F
47810b57cec5SDimitry Andric     if (Pred == FCmpInst::FCMP_OEQ)
47820b57cec5SDimitry Andric       return F;
47830b57cec5SDimitry Andric 
47840b57cec5SDimitry Andric     // (T != F) ? T : F --> T
47850b57cec5SDimitry Andric     // (F != T) ? T : F --> T
47860b57cec5SDimitry Andric     if (Pred == FCmpInst::FCMP_UNE)
47870b57cec5SDimitry Andric       return T;
47880b57cec5SDimitry Andric   }
47890b57cec5SDimitry Andric 
47900b57cec5SDimitry Andric   return nullptr;
47910b57cec5SDimitry Andric }
47920b57cec5SDimitry Andric 
47930b57cec5SDimitry Andric /// Given operands for a SelectInst, see if we can fold the result.
47940b57cec5SDimitry Andric /// If not, this returns null.
479581ad6265SDimitry Andric static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
47960b57cec5SDimitry Andric                                  const SimplifyQuery &Q, unsigned MaxRecurse) {
47970b57cec5SDimitry Andric   if (auto *CondC = dyn_cast<Constant>(Cond)) {
47980b57cec5SDimitry Andric     if (auto *TrueC = dyn_cast<Constant>(TrueVal))
47990b57cec5SDimitry Andric       if (auto *FalseC = dyn_cast<Constant>(FalseVal))
480006c3fb27SDimitry Andric         if (Constant *C = ConstantFoldSelectInstruction(CondC, TrueC, FalseC))
480106c3fb27SDimitry Andric           return C;
48020b57cec5SDimitry Andric 
4803fe6060f1SDimitry Andric     // select poison, X, Y -> poison
4804fe6060f1SDimitry Andric     if (isa<PoisonValue>(CondC))
4805fe6060f1SDimitry Andric       return PoisonValue::get(TrueVal->getType());
4806fe6060f1SDimitry Andric 
48070b57cec5SDimitry Andric     // select undef, X, Y -> X or Y
4808e8d8bef9SDimitry Andric     if (Q.isUndefValue(CondC))
48090b57cec5SDimitry Andric       return isa<Constant>(FalseVal) ? FalseVal : TrueVal;
48100b57cec5SDimitry Andric 
4811fe6060f1SDimitry Andric     // select true,  X, Y --> X
4812fe6060f1SDimitry Andric     // select false, X, Y --> Y
4813fe6060f1SDimitry Andric     // For vectors, allow undef/poison elements in the condition to match the
4814fe6060f1SDimitry Andric     // defined elements, so we can eliminate the select.
4815fe6060f1SDimitry Andric     if (match(CondC, m_One()))
48160b57cec5SDimitry Andric       return TrueVal;
4817fe6060f1SDimitry Andric     if (match(CondC, m_Zero()))
48180b57cec5SDimitry Andric       return FalseVal;
48190b57cec5SDimitry Andric   }
48200b57cec5SDimitry Andric 
4821480093f4SDimitry Andric   assert(Cond->getType()->isIntOrIntVectorTy(1) &&
4822480093f4SDimitry Andric          "Select must have bool or bool vector condition");
4823480093f4SDimitry Andric   assert(TrueVal->getType() == FalseVal->getType() &&
4824480093f4SDimitry Andric          "Select must have same types for true/false ops");
4825349cc55cSDimitry Andric 
4826349cc55cSDimitry Andric   if (Cond->getType() == TrueVal->getType()) {
4827349cc55cSDimitry Andric     // select i1 Cond, i1 true, i1 false --> i1 Cond
4828349cc55cSDimitry Andric     if (match(TrueVal, m_One()) && match(FalseVal, m_ZeroInt()))
4829480093f4SDimitry Andric       return Cond;
4830480093f4SDimitry Andric 
4831bdd1243dSDimitry Andric     // (X && Y) ? X : Y --> Y (commuted 2 ways)
4832bdd1243dSDimitry Andric     if (match(Cond, m_c_LogicalAnd(m_Specific(TrueVal), m_Specific(FalseVal))))
4833bdd1243dSDimitry Andric       return FalseVal;
4834bdd1243dSDimitry Andric 
4835bdd1243dSDimitry Andric     // (X || Y) ? X : Y --> X (commuted 2 ways)
4836bdd1243dSDimitry Andric     if (match(Cond, m_c_LogicalOr(m_Specific(TrueVal), m_Specific(FalseVal))))
4837bdd1243dSDimitry Andric       return TrueVal;
4838bdd1243dSDimitry Andric 
4839bdd1243dSDimitry Andric     // (X || Y) ? false : X --> false (commuted 2 ways)
4840bdd1243dSDimitry Andric     if (match(Cond, m_c_LogicalOr(m_Specific(FalseVal), m_Value())) &&
4841bdd1243dSDimitry Andric         match(TrueVal, m_ZeroInt()))
4842bdd1243dSDimitry Andric       return ConstantInt::getFalse(Cond->getType());
4843bdd1243dSDimitry Andric 
4844bdd1243dSDimitry Andric     // Match patterns that end in logical-and.
4845bdd1243dSDimitry Andric     if (match(FalseVal, m_ZeroInt())) {
4846bdd1243dSDimitry Andric       // !(X || Y) && X --> false (commuted 2 ways)
4847bdd1243dSDimitry Andric       if (match(Cond, m_Not(m_c_LogicalOr(m_Specific(TrueVal), m_Value()))))
4848bdd1243dSDimitry Andric         return ConstantInt::getFalse(Cond->getType());
484906c3fb27SDimitry Andric       // X && !(X || Y) --> false (commuted 2 ways)
485006c3fb27SDimitry Andric       if (match(TrueVal, m_Not(m_c_LogicalOr(m_Specific(Cond), m_Value()))))
485106c3fb27SDimitry Andric         return ConstantInt::getFalse(Cond->getType());
4852bdd1243dSDimitry Andric 
4853bdd1243dSDimitry Andric       // (X || Y) && Y --> Y (commuted 2 ways)
4854bdd1243dSDimitry Andric       if (match(Cond, m_c_LogicalOr(m_Specific(TrueVal), m_Value())))
4855bdd1243dSDimitry Andric         return TrueVal;
4856bdd1243dSDimitry Andric       // Y && (X || Y) --> Y (commuted 2 ways)
4857bdd1243dSDimitry Andric       if (match(TrueVal, m_c_LogicalOr(m_Specific(Cond), m_Value())))
4858bdd1243dSDimitry Andric         return Cond;
4859bdd1243dSDimitry Andric 
4860349cc55cSDimitry Andric       // (X || Y) && (X || !Y) --> X (commuted 8 ways)
4861349cc55cSDimitry Andric       Value *X, *Y;
4862349cc55cSDimitry Andric       if (match(Cond, m_c_LogicalOr(m_Value(X), m_Not(m_Value(Y)))) &&
4863349cc55cSDimitry Andric           match(TrueVal, m_c_LogicalOr(m_Specific(X), m_Specific(Y))))
4864349cc55cSDimitry Andric         return X;
4865349cc55cSDimitry Andric       if (match(TrueVal, m_c_LogicalOr(m_Value(X), m_Not(m_Value(Y)))) &&
4866349cc55cSDimitry Andric           match(Cond, m_c_LogicalOr(m_Specific(X), m_Specific(Y))))
4867349cc55cSDimitry Andric         return X;
4868349cc55cSDimitry Andric     }
4869bdd1243dSDimitry Andric 
4870bdd1243dSDimitry Andric     // Match patterns that end in logical-or.
4871bdd1243dSDimitry Andric     if (match(TrueVal, m_One())) {
487206c3fb27SDimitry Andric       // !(X && Y) || X --> true (commuted 2 ways)
487306c3fb27SDimitry Andric       if (match(Cond, m_Not(m_c_LogicalAnd(m_Specific(FalseVal), m_Value()))))
487406c3fb27SDimitry Andric         return ConstantInt::getTrue(Cond->getType());
487506c3fb27SDimitry Andric       // X || !(X && Y) --> true (commuted 2 ways)
487606c3fb27SDimitry Andric       if (match(FalseVal, m_Not(m_c_LogicalAnd(m_Specific(Cond), m_Value()))))
487706c3fb27SDimitry Andric         return ConstantInt::getTrue(Cond->getType());
487806c3fb27SDimitry Andric 
4879bdd1243dSDimitry Andric       // (X && Y) || Y --> Y (commuted 2 ways)
4880bdd1243dSDimitry Andric       if (match(Cond, m_c_LogicalAnd(m_Specific(FalseVal), m_Value())))
4881bdd1243dSDimitry Andric         return FalseVal;
4882bdd1243dSDimitry Andric       // Y || (X && Y) --> Y (commuted 2 ways)
4883bdd1243dSDimitry Andric       if (match(FalseVal, m_c_LogicalAnd(m_Specific(Cond), m_Value())))
4884bdd1243dSDimitry Andric         return Cond;
4885bdd1243dSDimitry Andric     }
4886349cc55cSDimitry Andric   }
4887349cc55cSDimitry Andric 
48880b57cec5SDimitry Andric   // select ?, X, X -> X
48890b57cec5SDimitry Andric   if (TrueVal == FalseVal)
48900b57cec5SDimitry Andric     return TrueVal;
48910b57cec5SDimitry Andric 
4892bdd1243dSDimitry Andric   if (Cond == TrueVal) {
4893bdd1243dSDimitry Andric     // select i1 X, i1 X, i1 false --> X (logical-and)
4894bdd1243dSDimitry Andric     if (match(FalseVal, m_ZeroInt()))
4895bdd1243dSDimitry Andric       return Cond;
4896bdd1243dSDimitry Andric     // select i1 X, i1 X, i1 true --> true
4897bdd1243dSDimitry Andric     if (match(FalseVal, m_One()))
4898bdd1243dSDimitry Andric       return ConstantInt::getTrue(Cond->getType());
4899bdd1243dSDimitry Andric   }
4900bdd1243dSDimitry Andric   if (Cond == FalseVal) {
4901bdd1243dSDimitry Andric     // select i1 X, i1 true, i1 X --> X (logical-or)
4902bdd1243dSDimitry Andric     if (match(TrueVal, m_One()))
4903bdd1243dSDimitry Andric       return Cond;
4904bdd1243dSDimitry Andric     // select i1 X, i1 false, i1 X --> false
4905bdd1243dSDimitry Andric     if (match(TrueVal, m_ZeroInt()))
4906bdd1243dSDimitry Andric       return ConstantInt::getFalse(Cond->getType());
4907bdd1243dSDimitry Andric   }
4908bdd1243dSDimitry Andric 
4909fe6060f1SDimitry Andric   // If the true or false value is poison, we can fold to the other value.
4910e8d8bef9SDimitry Andric   // If the true or false value is undef, we can fold to the other value as
4911e8d8bef9SDimitry Andric   // long as the other value isn't poison.
4912fe6060f1SDimitry Andric   // select ?, poison, X -> X
4913e8d8bef9SDimitry Andric   // select ?, undef,  X -> X
4914fe6060f1SDimitry Andric   if (isa<PoisonValue>(TrueVal) ||
4915647cbc5dSDimitry Andric       (Q.isUndefValue(TrueVal) && impliesPoison(FalseVal, Cond)))
49160b57cec5SDimitry Andric     return FalseVal;
4917fe6060f1SDimitry Andric   // select ?, X, poison -> X
4918e8d8bef9SDimitry Andric   // select ?, X, undef  -> X
4919fe6060f1SDimitry Andric   if (isa<PoisonValue>(FalseVal) ||
4920647cbc5dSDimitry Andric       (Q.isUndefValue(FalseVal) && impliesPoison(TrueVal, Cond)))
49210b57cec5SDimitry Andric     return TrueVal;
49220b57cec5SDimitry Andric 
49235ffd83dbSDimitry Andric   // Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC''
49245ffd83dbSDimitry Andric   Constant *TrueC, *FalseC;
4925e8d8bef9SDimitry Andric   if (isa<FixedVectorType>(TrueVal->getType()) &&
4926e8d8bef9SDimitry Andric       match(TrueVal, m_Constant(TrueC)) &&
49275ffd83dbSDimitry Andric       match(FalseVal, m_Constant(FalseC))) {
4928e8d8bef9SDimitry Andric     unsigned NumElts =
4929e8d8bef9SDimitry Andric         cast<FixedVectorType>(TrueC->getType())->getNumElements();
49305ffd83dbSDimitry Andric     SmallVector<Constant *, 16> NewC;
49315ffd83dbSDimitry Andric     for (unsigned i = 0; i != NumElts; ++i) {
49325ffd83dbSDimitry Andric       // Bail out on incomplete vector constants.
49335ffd83dbSDimitry Andric       Constant *TEltC = TrueC->getAggregateElement(i);
49345ffd83dbSDimitry Andric       Constant *FEltC = FalseC->getAggregateElement(i);
49355ffd83dbSDimitry Andric       if (!TEltC || !FEltC)
49365ffd83dbSDimitry Andric         break;
49375ffd83dbSDimitry Andric 
49385ffd83dbSDimitry Andric       // If the elements match (undef or not), that value is the result. If only
49395ffd83dbSDimitry Andric       // one element is undef, choose the defined element as the safe result.
49405ffd83dbSDimitry Andric       if (TEltC == FEltC)
49415ffd83dbSDimitry Andric         NewC.push_back(TEltC);
4942fe6060f1SDimitry Andric       else if (isa<PoisonValue>(TEltC) ||
4943fe6060f1SDimitry Andric                (Q.isUndefValue(TEltC) && isGuaranteedNotToBePoison(FEltC)))
49445ffd83dbSDimitry Andric         NewC.push_back(FEltC);
4945fe6060f1SDimitry Andric       else if (isa<PoisonValue>(FEltC) ||
4946fe6060f1SDimitry Andric                (Q.isUndefValue(FEltC) && isGuaranteedNotToBePoison(TEltC)))
49475ffd83dbSDimitry Andric         NewC.push_back(TEltC);
49485ffd83dbSDimitry Andric       else
49495ffd83dbSDimitry Andric         break;
49505ffd83dbSDimitry Andric     }
49515ffd83dbSDimitry Andric     if (NewC.size() == NumElts)
49525ffd83dbSDimitry Andric       return ConstantVector::get(NewC);
49535ffd83dbSDimitry Andric   }
49545ffd83dbSDimitry Andric 
49550b57cec5SDimitry Andric   if (Value *V =
49560b57cec5SDimitry Andric           simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse))
49570b57cec5SDimitry Andric     return V;
49580b57cec5SDimitry Andric 
4959480093f4SDimitry Andric   if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal, Q))
49600b57cec5SDimitry Andric     return V;
49610b57cec5SDimitry Andric 
49620b57cec5SDimitry Andric   if (Value *V = foldSelectWithBinaryOp(Cond, TrueVal, FalseVal))
49630b57cec5SDimitry Andric     return V;
49640b57cec5SDimitry Andric 
4965bdd1243dSDimitry Andric   std::optional<bool> Imp = isImpliedByDomCondition(Cond, Q.CxtI, Q.DL);
49660b57cec5SDimitry Andric   if (Imp)
49670b57cec5SDimitry Andric     return *Imp ? TrueVal : FalseVal;
49680b57cec5SDimitry Andric 
49690b57cec5SDimitry Andric   return nullptr;
49700b57cec5SDimitry Andric }
49710b57cec5SDimitry Andric 
497281ad6265SDimitry Andric Value *llvm::simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
49730b57cec5SDimitry Andric                                 const SimplifyQuery &Q) {
497481ad6265SDimitry Andric   return ::simplifySelectInst(Cond, TrueVal, FalseVal, Q, RecursionLimit);
49750b57cec5SDimitry Andric }
49760b57cec5SDimitry Andric 
49770b57cec5SDimitry Andric /// Given operands for an GetElementPtrInst, see if we can fold the result.
49780b57cec5SDimitry Andric /// If not, this returns null.
497981ad6265SDimitry Andric static Value *simplifyGEPInst(Type *SrcTy, Value *Ptr,
4980*0fca6ea1SDimitry Andric                               ArrayRef<Value *> Indices, GEPNoWrapFlags NW,
49810b57cec5SDimitry Andric                               const SimplifyQuery &Q, unsigned) {
49820b57cec5SDimitry Andric   // The type of the GEP pointer operand.
49830b57cec5SDimitry Andric   unsigned AS =
498404eeddc0SDimitry Andric       cast<PointerType>(Ptr->getType()->getScalarType())->getAddressSpace();
49850b57cec5SDimitry Andric 
49860b57cec5SDimitry Andric   // getelementptr P -> P.
498704eeddc0SDimitry Andric   if (Indices.empty())
498804eeddc0SDimitry Andric     return Ptr;
49890b57cec5SDimitry Andric 
49900b57cec5SDimitry Andric   // Compute the (pointer) type returned by the GEP instruction.
499104eeddc0SDimitry Andric   Type *LastType = GetElementPtrInst::getIndexedType(SrcTy, Indices);
49925f757f3fSDimitry Andric   Type *GEPTy = Ptr->getType();
49935f757f3fSDimitry Andric   if (!GEPTy->isVectorTy()) {
499404eeddc0SDimitry Andric     for (Value *Op : Indices) {
4995fe6060f1SDimitry Andric       // If one of the operands is a vector, the result type is a vector of
4996fe6060f1SDimitry Andric       // pointers. All vector operands must have the same number of elements.
4997fe6060f1SDimitry Andric       if (VectorType *VT = dyn_cast<VectorType>(Op->getType())) {
49985ffd83dbSDimitry Andric         GEPTy = VectorType::get(GEPTy, VT->getElementCount());
4999fe6060f1SDimitry Andric         break;
5000fe6060f1SDimitry Andric       }
5001fe6060f1SDimitry Andric     }
500204eeddc0SDimitry Andric   }
50030b57cec5SDimitry Andric 
500406c3fb27SDimitry Andric   // All-zero GEP is a no-op, unless it performs a vector splat.
500506c3fb27SDimitry Andric   if (Ptr->getType() == GEPTy &&
500681ad6265SDimitry Andric       all_of(Indices, [](const auto *V) { return match(V, m_Zero()); }))
500781ad6265SDimitry Andric     return Ptr;
500881ad6265SDimitry Andric 
5009e8d8bef9SDimitry Andric   // getelementptr poison, idx -> poison
5010e8d8bef9SDimitry Andric   // getelementptr baseptr, poison -> poison
501104eeddc0SDimitry Andric   if (isa<PoisonValue>(Ptr) ||
501204eeddc0SDimitry Andric       any_of(Indices, [](const auto *V) { return isa<PoisonValue>(V); }))
5013e8d8bef9SDimitry Andric     return PoisonValue::get(GEPTy);
5014e8d8bef9SDimitry Andric 
501506c3fb27SDimitry Andric   // getelementptr undef, idx -> undef
501604eeddc0SDimitry Andric   if (Q.isUndefValue(Ptr))
501706c3fb27SDimitry Andric     return UndefValue::get(GEPTy);
50180b57cec5SDimitry Andric 
5019fe6060f1SDimitry Andric   bool IsScalableVec =
50205f757f3fSDimitry Andric       SrcTy->isScalableTy() || any_of(Indices, [](const Value *V) {
5021fe6060f1SDimitry Andric         return isa<ScalableVectorType>(V->getType());
5022fe6060f1SDimitry Andric       });
50235ffd83dbSDimitry Andric 
502404eeddc0SDimitry Andric   if (Indices.size() == 1) {
50250b57cec5SDimitry Andric     Type *Ty = SrcTy;
50265ffd83dbSDimitry Andric     if (!IsScalableVec && Ty->isSized()) {
50270b57cec5SDimitry Andric       Value *P;
50280b57cec5SDimitry Andric       uint64_t C;
50290b57cec5SDimitry Andric       uint64_t TyAllocSize = Q.DL.getTypeAllocSize(Ty);
50300b57cec5SDimitry Andric       // getelementptr P, N -> P if P points to a type of zero size.
503104eeddc0SDimitry Andric       if (TyAllocSize == 0 && Ptr->getType() == GEPTy)
503204eeddc0SDimitry Andric         return Ptr;
50330b57cec5SDimitry Andric 
50340b57cec5SDimitry Andric       // The following transforms are only safe if the ptrtoint cast
50350b57cec5SDimitry Andric       // doesn't truncate the pointers.
503604eeddc0SDimitry Andric       if (Indices[0]->getType()->getScalarSizeInBits() ==
5037480093f4SDimitry Andric           Q.DL.getPointerSizeInBits(AS)) {
503804eeddc0SDimitry Andric         auto CanSimplify = [GEPTy, &P, Ptr]() -> bool {
5039fe6060f1SDimitry Andric           return P->getType() == GEPTy &&
504004eeddc0SDimitry Andric                  getUnderlyingObject(P) == getUnderlyingObject(Ptr);
50410b57cec5SDimitry Andric         };
50420b57cec5SDimitry Andric         // getelementptr V, (sub P, V) -> P if P points to a type of size 1.
50430b57cec5SDimitry Andric         if (TyAllocSize == 1 &&
504404eeddc0SDimitry Andric             match(Indices[0],
504504eeddc0SDimitry Andric                   m_Sub(m_PtrToInt(m_Value(P)), m_PtrToInt(m_Specific(Ptr)))) &&
5046fe6060f1SDimitry Andric             CanSimplify())
5047fe6060f1SDimitry Andric           return P;
50480b57cec5SDimitry Andric 
5049fe6060f1SDimitry Andric         // getelementptr V, (ashr (sub P, V), C) -> P if P points to a type of
5050fe6060f1SDimitry Andric         // size 1 << C.
505104eeddc0SDimitry Andric         if (match(Indices[0], m_AShr(m_Sub(m_PtrToInt(m_Value(P)),
505204eeddc0SDimitry Andric                                            m_PtrToInt(m_Specific(Ptr))),
50530b57cec5SDimitry Andric                                      m_ConstantInt(C))) &&
5054fe6060f1SDimitry Andric             TyAllocSize == 1ULL << C && CanSimplify())
5055fe6060f1SDimitry Andric           return P;
50560b57cec5SDimitry Andric 
5057fe6060f1SDimitry Andric         // getelementptr V, (sdiv (sub P, V), C) -> P if P points to a type of
5058fe6060f1SDimitry Andric         // size C.
505904eeddc0SDimitry Andric         if (match(Indices[0], m_SDiv(m_Sub(m_PtrToInt(m_Value(P)),
506004eeddc0SDimitry Andric                                            m_PtrToInt(m_Specific(Ptr))),
5061fe6060f1SDimitry Andric                                      m_SpecificInt(TyAllocSize))) &&
5062fe6060f1SDimitry Andric             CanSimplify())
5063fe6060f1SDimitry Andric           return P;
50640b57cec5SDimitry Andric       }
50650b57cec5SDimitry Andric     }
50660b57cec5SDimitry Andric   }
50670b57cec5SDimitry Andric 
50685ffd83dbSDimitry Andric   if (!IsScalableVec && Q.DL.getTypeAllocSize(LastType) == 1 &&
506904eeddc0SDimitry Andric       all_of(Indices.drop_back(1),
50700b57cec5SDimitry Andric              [](Value *Idx) { return match(Idx, m_Zero()); })) {
50710b57cec5SDimitry Andric     unsigned IdxWidth =
507204eeddc0SDimitry Andric         Q.DL.getIndexSizeInBits(Ptr->getType()->getPointerAddressSpace());
507304eeddc0SDimitry Andric     if (Q.DL.getTypeSizeInBits(Indices.back()->getType()) == IdxWidth) {
50740b57cec5SDimitry Andric       APInt BasePtrOffset(IdxWidth, 0);
50750b57cec5SDimitry Andric       Value *StrippedBasePtr =
507604eeddc0SDimitry Andric           Ptr->stripAndAccumulateInBoundsConstantOffsets(Q.DL, BasePtrOffset);
50770b57cec5SDimitry Andric 
5078e8d8bef9SDimitry Andric       // Avoid creating inttoptr of zero here: While LLVMs treatment of
5079e8d8bef9SDimitry Andric       // inttoptr is generally conservative, this particular case is folded to
5080e8d8bef9SDimitry Andric       // a null pointer, which will have incorrect provenance.
5081e8d8bef9SDimitry Andric 
50820b57cec5SDimitry Andric       // gep (gep V, C), (sub 0, V) -> C
508304eeddc0SDimitry Andric       if (match(Indices.back(),
5084*0fca6ea1SDimitry Andric                 m_Neg(m_PtrToInt(m_Specific(StrippedBasePtr)))) &&
5085349cc55cSDimitry Andric           !BasePtrOffset.isZero()) {
50860b57cec5SDimitry Andric         auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset);
50870b57cec5SDimitry Andric         return ConstantExpr::getIntToPtr(CI, GEPTy);
50880b57cec5SDimitry Andric       }
50890b57cec5SDimitry Andric       // gep (gep V, C), (xor V, -1) -> C-1
509004eeddc0SDimitry Andric       if (match(Indices.back(),
5091e8d8bef9SDimitry Andric                 m_Xor(m_PtrToInt(m_Specific(StrippedBasePtr)), m_AllOnes())) &&
5092349cc55cSDimitry Andric           !BasePtrOffset.isOne()) {
50930b57cec5SDimitry Andric         auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset - 1);
50940b57cec5SDimitry Andric         return ConstantExpr::getIntToPtr(CI, GEPTy);
50950b57cec5SDimitry Andric       }
50960b57cec5SDimitry Andric     }
50970b57cec5SDimitry Andric   }
50980b57cec5SDimitry Andric 
50990b57cec5SDimitry Andric   // Check to see if this is constant foldable.
510004eeddc0SDimitry Andric   if (!isa<Constant>(Ptr) ||
510104eeddc0SDimitry Andric       !all_of(Indices, [](Value *V) { return isa<Constant>(V); }))
51020b57cec5SDimitry Andric     return nullptr;
51030b57cec5SDimitry Andric 
510406c3fb27SDimitry Andric   if (!ConstantExpr::isSupportedGetElementPtr(SrcTy))
5105*0fca6ea1SDimitry Andric     return ConstantFoldGetElementPtr(SrcTy, cast<Constant>(Ptr), std::nullopt,
5106*0fca6ea1SDimitry Andric                                      Indices);
510706c3fb27SDimitry Andric 
5108*0fca6ea1SDimitry Andric   auto *CE =
5109*0fca6ea1SDimitry Andric       ConstantExpr::getGetElementPtr(SrcTy, cast<Constant>(Ptr), Indices, NW);
51105ffd83dbSDimitry Andric   return ConstantFoldConstant(CE, Q.DL);
51110b57cec5SDimitry Andric }
51120b57cec5SDimitry Andric 
511381ad6265SDimitry Andric Value *llvm::simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef<Value *> Indices,
5114*0fca6ea1SDimitry Andric                              GEPNoWrapFlags NW, const SimplifyQuery &Q) {
5115*0fca6ea1SDimitry Andric   return ::simplifyGEPInst(SrcTy, Ptr, Indices, NW, Q, RecursionLimit);
51160b57cec5SDimitry Andric }
51170b57cec5SDimitry Andric 
51180b57cec5SDimitry Andric /// Given operands for an InsertValueInst, see if we can fold the result.
51190b57cec5SDimitry Andric /// If not, this returns null.
512081ad6265SDimitry Andric static Value *simplifyInsertValueInst(Value *Agg, Value *Val,
512181ad6265SDimitry Andric                                       ArrayRef<unsigned> Idxs,
512281ad6265SDimitry Andric                                       const SimplifyQuery &Q, unsigned) {
51230b57cec5SDimitry Andric   if (Constant *CAgg = dyn_cast<Constant>(Agg))
51240b57cec5SDimitry Andric     if (Constant *CVal = dyn_cast<Constant>(Val))
51250b57cec5SDimitry Andric       return ConstantFoldInsertValueInstruction(CAgg, CVal, Idxs);
51260b57cec5SDimitry Andric 
5127bdd1243dSDimitry Andric   // insertvalue x, poison, n -> x
5128bdd1243dSDimitry Andric   // insertvalue x, undef, n -> x if x cannot be poison
5129bdd1243dSDimitry Andric   if (isa<PoisonValue>(Val) ||
5130bdd1243dSDimitry Andric       (Q.isUndefValue(Val) && isGuaranteedNotToBePoison(Agg)))
51310b57cec5SDimitry Andric     return Agg;
51320b57cec5SDimitry Andric 
51330b57cec5SDimitry Andric   // insertvalue x, (extractvalue y, n), n
51340b57cec5SDimitry Andric   if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Val))
51350b57cec5SDimitry Andric     if (EV->getAggregateOperand()->getType() == Agg->getType() &&
51360b57cec5SDimitry Andric         EV->getIndices() == Idxs) {
513706c3fb27SDimitry Andric       // insertvalue poison, (extractvalue y, n), n -> y
513806c3fb27SDimitry Andric       // insertvalue undef, (extractvalue y, n), n -> y if y cannot be poison
513906c3fb27SDimitry Andric       if (isa<PoisonValue>(Agg) ||
514006c3fb27SDimitry Andric           (Q.isUndefValue(Agg) &&
514106c3fb27SDimitry Andric            isGuaranteedNotToBePoison(EV->getAggregateOperand())))
51420b57cec5SDimitry Andric         return EV->getAggregateOperand();
51430b57cec5SDimitry Andric 
51440b57cec5SDimitry Andric       // insertvalue y, (extractvalue y, n), n -> y
51450b57cec5SDimitry Andric       if (Agg == EV->getAggregateOperand())
51460b57cec5SDimitry Andric         return Agg;
51470b57cec5SDimitry Andric     }
51480b57cec5SDimitry Andric 
51490b57cec5SDimitry Andric   return nullptr;
51500b57cec5SDimitry Andric }
51510b57cec5SDimitry Andric 
515281ad6265SDimitry Andric Value *llvm::simplifyInsertValueInst(Value *Agg, Value *Val,
51530b57cec5SDimitry Andric                                      ArrayRef<unsigned> Idxs,
51540b57cec5SDimitry Andric                                      const SimplifyQuery &Q) {
515581ad6265SDimitry Andric   return ::simplifyInsertValueInst(Agg, Val, Idxs, Q, RecursionLimit);
51560b57cec5SDimitry Andric }
51570b57cec5SDimitry Andric 
515881ad6265SDimitry Andric Value *llvm::simplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx,
51590b57cec5SDimitry Andric                                        const SimplifyQuery &Q) {
51600b57cec5SDimitry Andric   // Try to constant fold.
51610b57cec5SDimitry Andric   auto *VecC = dyn_cast<Constant>(Vec);
51620b57cec5SDimitry Andric   auto *ValC = dyn_cast<Constant>(Val);
51630b57cec5SDimitry Andric   auto *IdxC = dyn_cast<Constant>(Idx);
51640b57cec5SDimitry Andric   if (VecC && ValC && IdxC)
5165e8d8bef9SDimitry Andric     return ConstantExpr::getInsertElement(VecC, ValC, IdxC);
51660b57cec5SDimitry Andric 
5167e8d8bef9SDimitry Andric   // For fixed-length vector, fold into poison if index is out of bounds.
51680b57cec5SDimitry Andric   if (auto *CI = dyn_cast<ConstantInt>(Idx)) {
51695ffd83dbSDimitry Andric     if (isa<FixedVectorType>(Vec->getType()) &&
51705ffd83dbSDimitry Andric         CI->uge(cast<FixedVectorType>(Vec->getType())->getNumElements()))
5171e8d8bef9SDimitry Andric       return PoisonValue::get(Vec->getType());
51720b57cec5SDimitry Andric   }
51730b57cec5SDimitry Andric 
51740b57cec5SDimitry Andric   // If index is undef, it might be out of bounds (see above case)
5175e8d8bef9SDimitry Andric   if (Q.isUndefValue(Idx))
5176e8d8bef9SDimitry Andric     return PoisonValue::get(Vec->getType());
51770b57cec5SDimitry Andric 
5178e8d8bef9SDimitry Andric   // If the scalar is poison, or it is undef and there is no risk of
5179e8d8bef9SDimitry Andric   // propagating poison from the vector value, simplify to the vector value.
5180e8d8bef9SDimitry Andric   if (isa<PoisonValue>(Val) ||
5181e8d8bef9SDimitry Andric       (Q.isUndefValue(Val) && isGuaranteedNotToBePoison(Vec)))
51820b57cec5SDimitry Andric     return Vec;
51830b57cec5SDimitry Andric 
51840b57cec5SDimitry Andric   // If we are extracting a value from a vector, then inserting it into the same
51850b57cec5SDimitry Andric   // place, that's the input vector:
51860b57cec5SDimitry Andric   // insertelt Vec, (extractelt Vec, Idx), Idx --> Vec
51875ffd83dbSDimitry Andric   if (match(Val, m_ExtractElt(m_Specific(Vec), m_Specific(Idx))))
51880b57cec5SDimitry Andric     return Vec;
51890b57cec5SDimitry Andric 
51900b57cec5SDimitry Andric   return nullptr;
51910b57cec5SDimitry Andric }
51920b57cec5SDimitry Andric 
51930b57cec5SDimitry Andric /// Given operands for an ExtractValueInst, see if we can fold the result.
51940b57cec5SDimitry Andric /// If not, this returns null.
519581ad6265SDimitry Andric static Value *simplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
51960b57cec5SDimitry Andric                                        const SimplifyQuery &, unsigned) {
51970b57cec5SDimitry Andric   if (auto *CAgg = dyn_cast<Constant>(Agg))
51980b57cec5SDimitry Andric     return ConstantFoldExtractValueInstruction(CAgg, Idxs);
51990b57cec5SDimitry Andric 
52000b57cec5SDimitry Andric   // extractvalue x, (insertvalue y, elt, n), n -> elt
52010b57cec5SDimitry Andric   unsigned NumIdxs = Idxs.size();
52020b57cec5SDimitry Andric   for (auto *IVI = dyn_cast<InsertValueInst>(Agg); IVI != nullptr;
52030b57cec5SDimitry Andric        IVI = dyn_cast<InsertValueInst>(IVI->getAggregateOperand())) {
52040b57cec5SDimitry Andric     ArrayRef<unsigned> InsertValueIdxs = IVI->getIndices();
52050b57cec5SDimitry Andric     unsigned NumInsertValueIdxs = InsertValueIdxs.size();
52060b57cec5SDimitry Andric     unsigned NumCommonIdxs = std::min(NumInsertValueIdxs, NumIdxs);
52070b57cec5SDimitry Andric     if (InsertValueIdxs.slice(0, NumCommonIdxs) ==
52080b57cec5SDimitry Andric         Idxs.slice(0, NumCommonIdxs)) {
52090b57cec5SDimitry Andric       if (NumIdxs == NumInsertValueIdxs)
52100b57cec5SDimitry Andric         return IVI->getInsertedValueOperand();
52110b57cec5SDimitry Andric       break;
52120b57cec5SDimitry Andric     }
52130b57cec5SDimitry Andric   }
52140b57cec5SDimitry Andric 
52150b57cec5SDimitry Andric   return nullptr;
52160b57cec5SDimitry Andric }
52170b57cec5SDimitry Andric 
521881ad6265SDimitry Andric Value *llvm::simplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
52190b57cec5SDimitry Andric                                       const SimplifyQuery &Q) {
522081ad6265SDimitry Andric   return ::simplifyExtractValueInst(Agg, Idxs, Q, RecursionLimit);
52210b57cec5SDimitry Andric }
52220b57cec5SDimitry Andric 
52230b57cec5SDimitry Andric /// Given operands for an ExtractElementInst, see if we can fold the result.
52240b57cec5SDimitry Andric /// If not, this returns null.
522581ad6265SDimitry Andric static Value *simplifyExtractElementInst(Value *Vec, Value *Idx,
5226e8d8bef9SDimitry Andric                                          const SimplifyQuery &Q, unsigned) {
52275ffd83dbSDimitry Andric   auto *VecVTy = cast<VectorType>(Vec->getType());
52280b57cec5SDimitry Andric   if (auto *CVec = dyn_cast<Constant>(Vec)) {
52290b57cec5SDimitry Andric     if (auto *CIdx = dyn_cast<Constant>(Idx))
5230e8d8bef9SDimitry Andric       return ConstantExpr::getExtractElement(CVec, CIdx);
52310b57cec5SDimitry Andric 
5232e8d8bef9SDimitry Andric     if (Q.isUndefValue(Vec))
52335ffd83dbSDimitry Andric       return UndefValue::get(VecVTy->getElementType());
52340b57cec5SDimitry Andric   }
52350b57cec5SDimitry Andric 
52360b57cec5SDimitry Andric   // An undef extract index can be arbitrarily chosen to be an out-of-range
5237e8d8bef9SDimitry Andric   // index value, which would result in the instruction being poison.
5238e8d8bef9SDimitry Andric   if (Q.isUndefValue(Idx))
5239e8d8bef9SDimitry Andric     return PoisonValue::get(VecVTy->getElementType());
52400b57cec5SDimitry Andric 
5241fe6060f1SDimitry Andric   // If extracting a specified index from the vector, see if we can recursively
5242fe6060f1SDimitry Andric   // find a previously computed scalar that was inserted into the vector.
5243fe6060f1SDimitry Andric   if (auto *IdxC = dyn_cast<ConstantInt>(Idx)) {
5244fe6060f1SDimitry Andric     // For fixed-length vector, fold into undef if index is out of bounds.
5245fe6060f1SDimitry Andric     unsigned MinNumElts = VecVTy->getElementCount().getKnownMinValue();
5246fe6060f1SDimitry Andric     if (isa<FixedVectorType>(VecVTy) && IdxC->getValue().uge(MinNumElts))
5247fe6060f1SDimitry Andric       return PoisonValue::get(VecVTy->getElementType());
5248fe6060f1SDimitry Andric     // Handle case where an element is extracted from a splat.
5249fe6060f1SDimitry Andric     if (IdxC->getValue().ult(MinNumElts))
5250fe6060f1SDimitry Andric       if (auto *Splat = getSplatValue(Vec))
5251fe6060f1SDimitry Andric         return Splat;
5252fe6060f1SDimitry Andric     if (Value *Elt = findScalarElement(Vec, IdxC->getZExtValue()))
5253fe6060f1SDimitry Andric       return Elt;
5254fe6060f1SDimitry Andric   } else {
5255bdd1243dSDimitry Andric     // extractelt x, (insertelt y, elt, n), n -> elt
5256bdd1243dSDimitry Andric     // If the possibly-variable indices are trivially known to be equal
5257bdd1243dSDimitry Andric     // (because they are the same operand) then use the value that was
5258bdd1243dSDimitry Andric     // inserted directly.
5259bdd1243dSDimitry Andric     auto *IE = dyn_cast<InsertElementInst>(Vec);
5260bdd1243dSDimitry Andric     if (IE && IE->getOperand(2) == Idx)
5261bdd1243dSDimitry Andric       return IE->getOperand(1);
5262bdd1243dSDimitry Andric 
5263fe6060f1SDimitry Andric     // The index is not relevant if our vector is a splat.
5264fe6060f1SDimitry Andric     if (Value *Splat = getSplatValue(Vec))
5265fe6060f1SDimitry Andric       return Splat;
5266fe6060f1SDimitry Andric   }
52670b57cec5SDimitry Andric   return nullptr;
52680b57cec5SDimitry Andric }
52690b57cec5SDimitry Andric 
527081ad6265SDimitry Andric Value *llvm::simplifyExtractElementInst(Value *Vec, Value *Idx,
52710b57cec5SDimitry Andric                                         const SimplifyQuery &Q) {
527281ad6265SDimitry Andric   return ::simplifyExtractElementInst(Vec, Idx, Q, RecursionLimit);
52730b57cec5SDimitry Andric }
52740b57cec5SDimitry Andric 
52750b57cec5SDimitry Andric /// See if we can fold the given phi. If not, returns null.
527681ad6265SDimitry Andric static Value *simplifyPHINode(PHINode *PN, ArrayRef<Value *> IncomingValues,
5277fe6060f1SDimitry Andric                               const SimplifyQuery &Q) {
5278e8d8bef9SDimitry Andric   // WARNING: no matter how worthwhile it may seem, we can not perform PHI CSE
5279e8d8bef9SDimitry Andric   //          here, because the PHI we may succeed simplifying to was not
5280e8d8bef9SDimitry Andric   //          def-reachable from the original PHI!
5281e8d8bef9SDimitry Andric 
52820b57cec5SDimitry Andric   // If all of the PHI's incoming values are the same then replace the PHI node
52830b57cec5SDimitry Andric   // with the common value.
52840b57cec5SDimitry Andric   Value *CommonValue = nullptr;
5285*0fca6ea1SDimitry Andric   bool HasPoisonInput = false;
52860b57cec5SDimitry Andric   bool HasUndefInput = false;
5287fe6060f1SDimitry Andric   for (Value *Incoming : IncomingValues) {
52880b57cec5SDimitry Andric     // If the incoming value is the phi node itself, it can safely be skipped.
528981ad6265SDimitry Andric     if (Incoming == PN)
529081ad6265SDimitry Andric       continue;
5291*0fca6ea1SDimitry Andric     if (isa<PoisonValue>(Incoming)) {
5292*0fca6ea1SDimitry Andric       HasPoisonInput = true;
5293*0fca6ea1SDimitry Andric       continue;
5294*0fca6ea1SDimitry Andric     }
5295e8d8bef9SDimitry Andric     if (Q.isUndefValue(Incoming)) {
52960b57cec5SDimitry Andric       // Remember that we saw an undef value, but otherwise ignore them.
52970b57cec5SDimitry Andric       HasUndefInput = true;
52980b57cec5SDimitry Andric       continue;
52990b57cec5SDimitry Andric     }
53000b57cec5SDimitry Andric     if (CommonValue && Incoming != CommonValue)
53010b57cec5SDimitry Andric       return nullptr; // Not the same, bail out.
53020b57cec5SDimitry Andric     CommonValue = Incoming;
53030b57cec5SDimitry Andric   }
53040b57cec5SDimitry Andric 
5305*0fca6ea1SDimitry Andric   // If CommonValue is null then all of the incoming values were either undef,
5306*0fca6ea1SDimitry Andric   // poison or equal to the phi node itself.
53070b57cec5SDimitry Andric   if (!CommonValue)
5308*0fca6ea1SDimitry Andric     return HasUndefInput ? UndefValue::get(PN->getType())
5309*0fca6ea1SDimitry Andric                          : PoisonValue::get(PN->getType());
53100b57cec5SDimitry Andric 
5311*0fca6ea1SDimitry Andric   if (HasPoisonInput || HasUndefInput) {
53120b57cec5SDimitry Andric     // If we have a PHI node like phi(X, undef, X), where X is defined by some
53130b57cec5SDimitry Andric     // instruction, we cannot return X as the result of the PHI node unless it
53140b57cec5SDimitry Andric     // dominates the PHI block.
53150b57cec5SDimitry Andric     return valueDominatesPHI(CommonValue, PN, Q.DT) ? CommonValue : nullptr;
531681ad6265SDimitry Andric   }
53170b57cec5SDimitry Andric 
53180b57cec5SDimitry Andric   return CommonValue;
53190b57cec5SDimitry Andric }
53200b57cec5SDimitry Andric 
532181ad6265SDimitry Andric static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
532281ad6265SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
53230b57cec5SDimitry Andric   if (auto *C = dyn_cast<Constant>(Op))
53240b57cec5SDimitry Andric     return ConstantFoldCastOperand(CastOpc, C, Ty, Q.DL);
53250b57cec5SDimitry Andric 
53260b57cec5SDimitry Andric   if (auto *CI = dyn_cast<CastInst>(Op)) {
53270b57cec5SDimitry Andric     auto *Src = CI->getOperand(0);
53280b57cec5SDimitry Andric     Type *SrcTy = Src->getType();
53290b57cec5SDimitry Andric     Type *MidTy = CI->getType();
53300b57cec5SDimitry Andric     Type *DstTy = Ty;
53310b57cec5SDimitry Andric     if (Src->getType() == Ty) {
53320b57cec5SDimitry Andric       auto FirstOp = static_cast<Instruction::CastOps>(CI->getOpcode());
53330b57cec5SDimitry Andric       auto SecondOp = static_cast<Instruction::CastOps>(CastOpc);
53340b57cec5SDimitry Andric       Type *SrcIntPtrTy =
53350b57cec5SDimitry Andric           SrcTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(SrcTy) : nullptr;
53360b57cec5SDimitry Andric       Type *MidIntPtrTy =
53370b57cec5SDimitry Andric           MidTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(MidTy) : nullptr;
53380b57cec5SDimitry Andric       Type *DstIntPtrTy =
53390b57cec5SDimitry Andric           DstTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(DstTy) : nullptr;
53400b57cec5SDimitry Andric       if (CastInst::isEliminableCastPair(FirstOp, SecondOp, SrcTy, MidTy, DstTy,
53410b57cec5SDimitry Andric                                          SrcIntPtrTy, MidIntPtrTy,
53420b57cec5SDimitry Andric                                          DstIntPtrTy) == Instruction::BitCast)
53430b57cec5SDimitry Andric         return Src;
53440b57cec5SDimitry Andric     }
53450b57cec5SDimitry Andric   }
53460b57cec5SDimitry Andric 
53470b57cec5SDimitry Andric   // bitcast x -> x
53480b57cec5SDimitry Andric   if (CastOpc == Instruction::BitCast)
53490b57cec5SDimitry Andric     if (Op->getType() == Ty)
53500b57cec5SDimitry Andric       return Op;
53510b57cec5SDimitry Andric 
5352*0fca6ea1SDimitry Andric   // ptrtoint (ptradd (Ptr, X - ptrtoint(Ptr))) -> X
5353*0fca6ea1SDimitry Andric   Value *Ptr, *X;
5354*0fca6ea1SDimitry Andric   if (CastOpc == Instruction::PtrToInt &&
5355*0fca6ea1SDimitry Andric       match(Op, m_PtrAdd(m_Value(Ptr),
5356*0fca6ea1SDimitry Andric                          m_Sub(m_Value(X), m_PtrToInt(m_Deferred(Ptr))))) &&
5357*0fca6ea1SDimitry Andric       X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType()))
5358*0fca6ea1SDimitry Andric     return X;
5359*0fca6ea1SDimitry Andric 
53600b57cec5SDimitry Andric   return nullptr;
53610b57cec5SDimitry Andric }
53620b57cec5SDimitry Andric 
536381ad6265SDimitry Andric Value *llvm::simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
53640b57cec5SDimitry Andric                               const SimplifyQuery &Q) {
536581ad6265SDimitry Andric   return ::simplifyCastInst(CastOpc, Op, Ty, Q, RecursionLimit);
53660b57cec5SDimitry Andric }
53670b57cec5SDimitry Andric 
53680b57cec5SDimitry Andric /// For the given destination element of a shuffle, peek through shuffles to
53690b57cec5SDimitry Andric /// match a root vector source operand that contains that element in the same
53700b57cec5SDimitry Andric /// vector lane (ie, the same mask index), so we can eliminate the shuffle(s).
53710b57cec5SDimitry Andric static Value *foldIdentityShuffles(int DestElt, Value *Op0, Value *Op1,
53720b57cec5SDimitry Andric                                    int MaskVal, Value *RootVec,
53730b57cec5SDimitry Andric                                    unsigned MaxRecurse) {
53740b57cec5SDimitry Andric   if (!MaxRecurse--)
53750b57cec5SDimitry Andric     return nullptr;
53760b57cec5SDimitry Andric 
53770b57cec5SDimitry Andric   // Bail out if any mask value is undefined. That kind of shuffle may be
53780b57cec5SDimitry Andric   // simplified further based on demanded bits or other folds.
53790b57cec5SDimitry Andric   if (MaskVal == -1)
53800b57cec5SDimitry Andric     return nullptr;
53810b57cec5SDimitry Andric 
53820b57cec5SDimitry Andric   // The mask value chooses which source operand we need to look at next.
5383e8d8bef9SDimitry Andric   int InVecNumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
53840b57cec5SDimitry Andric   int RootElt = MaskVal;
53850b57cec5SDimitry Andric   Value *SourceOp = Op0;
53860b57cec5SDimitry Andric   if (MaskVal >= InVecNumElts) {
53870b57cec5SDimitry Andric     RootElt = MaskVal - InVecNumElts;
53880b57cec5SDimitry Andric     SourceOp = Op1;
53890b57cec5SDimitry Andric   }
53900b57cec5SDimitry Andric 
53910b57cec5SDimitry Andric   // If the source operand is a shuffle itself, look through it to find the
53920b57cec5SDimitry Andric   // matching root vector.
53930b57cec5SDimitry Andric   if (auto *SourceShuf = dyn_cast<ShuffleVectorInst>(SourceOp)) {
53940b57cec5SDimitry Andric     return foldIdentityShuffles(
53950b57cec5SDimitry Andric         DestElt, SourceShuf->getOperand(0), SourceShuf->getOperand(1),
53960b57cec5SDimitry Andric         SourceShuf->getMaskValue(RootElt), RootVec, MaxRecurse);
53970b57cec5SDimitry Andric   }
53980b57cec5SDimitry Andric 
53990b57cec5SDimitry Andric   // The source operand is not a shuffle. Initialize the root vector value for
54000b57cec5SDimitry Andric   // this shuffle if that has not been done yet.
54010b57cec5SDimitry Andric   if (!RootVec)
54020b57cec5SDimitry Andric     RootVec = SourceOp;
54030b57cec5SDimitry Andric 
54040b57cec5SDimitry Andric   // Give up as soon as a source operand does not match the existing root value.
54050b57cec5SDimitry Andric   if (RootVec != SourceOp)
54060b57cec5SDimitry Andric     return nullptr;
54070b57cec5SDimitry Andric 
54080b57cec5SDimitry Andric   // The element must be coming from the same lane in the source vector
54090b57cec5SDimitry Andric   // (although it may have crossed lanes in intermediate shuffles).
54100b57cec5SDimitry Andric   if (RootElt != DestElt)
54110b57cec5SDimitry Andric     return nullptr;
54120b57cec5SDimitry Andric 
54130b57cec5SDimitry Andric   return RootVec;
54140b57cec5SDimitry Andric }
54150b57cec5SDimitry Andric 
541681ad6265SDimitry Andric static Value *simplifyShuffleVectorInst(Value *Op0, Value *Op1,
54175ffd83dbSDimitry Andric                                         ArrayRef<int> Mask, Type *RetTy,
54185ffd83dbSDimitry Andric                                         const SimplifyQuery &Q,
54190b57cec5SDimitry Andric                                         unsigned MaxRecurse) {
542006c3fb27SDimitry Andric   if (all_of(Mask, [](int Elem) { return Elem == PoisonMaskElem; }))
542106c3fb27SDimitry Andric     return PoisonValue::get(RetTy);
54220b57cec5SDimitry Andric 
54235ffd83dbSDimitry Andric   auto *InVecTy = cast<VectorType>(Op0->getType());
54245ffd83dbSDimitry Andric   unsigned MaskNumElts = Mask.size();
54255ffd83dbSDimitry Andric   ElementCount InVecEltCount = InVecTy->getElementCount();
54265ffd83dbSDimitry Andric 
5427e8d8bef9SDimitry Andric   bool Scalable = InVecEltCount.isScalable();
54280b57cec5SDimitry Andric 
54290b57cec5SDimitry Andric   SmallVector<int, 32> Indices;
54305ffd83dbSDimitry Andric   Indices.assign(Mask.begin(), Mask.end());
54310b57cec5SDimitry Andric 
54320b57cec5SDimitry Andric   // Canonicalization: If mask does not select elements from an input vector,
5433e8d8bef9SDimitry Andric   // replace that input vector with poison.
54345ffd83dbSDimitry Andric   if (!Scalable) {
54350b57cec5SDimitry Andric     bool MaskSelects0 = false, MaskSelects1 = false;
5436e8d8bef9SDimitry Andric     unsigned InVecNumElts = InVecEltCount.getKnownMinValue();
54370b57cec5SDimitry Andric     for (unsigned i = 0; i != MaskNumElts; ++i) {
54380b57cec5SDimitry Andric       if (Indices[i] == -1)
54390b57cec5SDimitry Andric         continue;
54400b57cec5SDimitry Andric       if ((unsigned)Indices[i] < InVecNumElts)
54410b57cec5SDimitry Andric         MaskSelects0 = true;
54420b57cec5SDimitry Andric       else
54430b57cec5SDimitry Andric         MaskSelects1 = true;
54440b57cec5SDimitry Andric     }
54450b57cec5SDimitry Andric     if (!MaskSelects0)
5446e8d8bef9SDimitry Andric       Op0 = PoisonValue::get(InVecTy);
54470b57cec5SDimitry Andric     if (!MaskSelects1)
5448e8d8bef9SDimitry Andric       Op1 = PoisonValue::get(InVecTy);
54495ffd83dbSDimitry Andric   }
54500b57cec5SDimitry Andric 
54510b57cec5SDimitry Andric   auto *Op0Const = dyn_cast<Constant>(Op0);
54520b57cec5SDimitry Andric   auto *Op1Const = dyn_cast<Constant>(Op1);
54530b57cec5SDimitry Andric 
54545ffd83dbSDimitry Andric   // If all operands are constant, constant fold the shuffle. This
54555ffd83dbSDimitry Andric   // transformation depends on the value of the mask which is not known at
54565ffd83dbSDimitry Andric   // compile time for scalable vectors
5457e8d8bef9SDimitry Andric   if (Op0Const && Op1Const)
5458e8d8bef9SDimitry Andric     return ConstantExpr::getShuffleVector(Op0Const, Op1Const, Mask);
54590b57cec5SDimitry Andric 
54600b57cec5SDimitry Andric   // Canonicalization: if only one input vector is constant, it shall be the
54615ffd83dbSDimitry Andric   // second one. This transformation depends on the value of the mask which
54625ffd83dbSDimitry Andric   // is not known at compile time for scalable vectors
54635ffd83dbSDimitry Andric   if (!Scalable && Op0Const && !Op1Const) {
54640b57cec5SDimitry Andric     std::swap(Op0, Op1);
5465e8d8bef9SDimitry Andric     ShuffleVectorInst::commuteShuffleMask(Indices,
5466e8d8bef9SDimitry Andric                                           InVecEltCount.getKnownMinValue());
54670b57cec5SDimitry Andric   }
54680b57cec5SDimitry Andric 
5469480093f4SDimitry Andric   // A splat of an inserted scalar constant becomes a vector constant:
5470480093f4SDimitry Andric   // shuf (inselt ?, C, IndexC), undef, <IndexC, IndexC...> --> <C, C...>
5471480093f4SDimitry Andric   // NOTE: We may have commuted above, so analyze the updated Indices, not the
5472480093f4SDimitry Andric   //       original mask constant.
54735ffd83dbSDimitry Andric   // NOTE: This transformation depends on the value of the mask which is not
54745ffd83dbSDimitry Andric   // known at compile time for scalable vectors
5475480093f4SDimitry Andric   Constant *C;
5476480093f4SDimitry Andric   ConstantInt *IndexC;
54775ffd83dbSDimitry Andric   if (!Scalable && match(Op0, m_InsertElt(m_Value(), m_Constant(C),
5478480093f4SDimitry Andric                                           m_ConstantInt(IndexC)))) {
5479480093f4SDimitry Andric     // Match a splat shuffle mask of the insert index allowing undef elements.
5480480093f4SDimitry Andric     int InsertIndex = IndexC->getZExtValue();
5481480093f4SDimitry Andric     if (all_of(Indices, [InsertIndex](int MaskElt) {
5482480093f4SDimitry Andric           return MaskElt == InsertIndex || MaskElt == -1;
5483480093f4SDimitry Andric         })) {
5484480093f4SDimitry Andric       assert(isa<UndefValue>(Op1) && "Expected undef operand 1 for splat");
5485480093f4SDimitry Andric 
548606c3fb27SDimitry Andric       // Shuffle mask poisons become poison constant result elements.
5487480093f4SDimitry Andric       SmallVector<Constant *, 16> VecC(MaskNumElts, C);
5488480093f4SDimitry Andric       for (unsigned i = 0; i != MaskNumElts; ++i)
5489480093f4SDimitry Andric         if (Indices[i] == -1)
549006c3fb27SDimitry Andric           VecC[i] = PoisonValue::get(C->getType());
5491480093f4SDimitry Andric       return ConstantVector::get(VecC);
5492480093f4SDimitry Andric     }
5493480093f4SDimitry Andric   }
5494480093f4SDimitry Andric 
54950b57cec5SDimitry Andric   // A shuffle of a splat is always the splat itself. Legal if the shuffle's
54960b57cec5SDimitry Andric   // value type is same as the input vectors' type.
54970b57cec5SDimitry Andric   if (auto *OpShuf = dyn_cast<ShuffleVectorInst>(Op0))
5498e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op1) && RetTy == InVecTy &&
5499bdd1243dSDimitry Andric         all_equal(OpShuf->getShuffleMask()))
55000b57cec5SDimitry Andric       return Op0;
55010b57cec5SDimitry Andric 
55025ffd83dbSDimitry Andric   // All remaining transformation depend on the value of the mask, which is
55035ffd83dbSDimitry Andric   // not known at compile time for scalable vectors.
55045ffd83dbSDimitry Andric   if (Scalable)
55055ffd83dbSDimitry Andric     return nullptr;
55065ffd83dbSDimitry Andric 
55070b57cec5SDimitry Andric   // Don't fold a shuffle with undef mask elements. This may get folded in a
55080b57cec5SDimitry Andric   // better way using demanded bits or other analysis.
55090b57cec5SDimitry Andric   // TODO: Should we allow this?
5510e8d8bef9SDimitry Andric   if (is_contained(Indices, -1))
55110b57cec5SDimitry Andric     return nullptr;
55120b57cec5SDimitry Andric 
55130b57cec5SDimitry Andric   // Check if every element of this shuffle can be mapped back to the
55140b57cec5SDimitry Andric   // corresponding element of a single root vector. If so, we don't need this
55150b57cec5SDimitry Andric   // shuffle. This handles simple identity shuffles as well as chains of
55160b57cec5SDimitry Andric   // shuffles that may widen/narrow and/or move elements across lanes and back.
55170b57cec5SDimitry Andric   Value *RootVec = nullptr;
55180b57cec5SDimitry Andric   for (unsigned i = 0; i != MaskNumElts; ++i) {
55190b57cec5SDimitry Andric     // Note that recursion is limited for each vector element, so if any element
55200b57cec5SDimitry Andric     // exceeds the limit, this will fail to simplify.
55210b57cec5SDimitry Andric     RootVec =
55220b57cec5SDimitry Andric         foldIdentityShuffles(i, Op0, Op1, Indices[i], RootVec, MaxRecurse);
55230b57cec5SDimitry Andric 
55240b57cec5SDimitry Andric     // We can't replace a widening/narrowing shuffle with one of its operands.
55250b57cec5SDimitry Andric     if (!RootVec || RootVec->getType() != RetTy)
55260b57cec5SDimitry Andric       return nullptr;
55270b57cec5SDimitry Andric   }
55280b57cec5SDimitry Andric   return RootVec;
55290b57cec5SDimitry Andric }
55300b57cec5SDimitry Andric 
55310b57cec5SDimitry Andric /// Given operands for a ShuffleVectorInst, fold the result or return null.
553281ad6265SDimitry Andric Value *llvm::simplifyShuffleVectorInst(Value *Op0, Value *Op1,
55335ffd83dbSDimitry Andric                                        ArrayRef<int> Mask, Type *RetTy,
55345ffd83dbSDimitry Andric                                        const SimplifyQuery &Q) {
553581ad6265SDimitry Andric   return ::simplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
55360b57cec5SDimitry Andric }
55370b57cec5SDimitry Andric 
553881ad6265SDimitry Andric static Constant *foldConstant(Instruction::UnaryOps Opcode, Value *&Op,
553981ad6265SDimitry Andric                               const SimplifyQuery &Q) {
55400b57cec5SDimitry Andric   if (auto *C = dyn_cast<Constant>(Op))
55410b57cec5SDimitry Andric     return ConstantFoldUnaryOpOperand(Opcode, C, Q.DL);
55420b57cec5SDimitry Andric   return nullptr;
55430b57cec5SDimitry Andric }
55440b57cec5SDimitry Andric 
55450b57cec5SDimitry Andric /// Given the operand for an FNeg, see if we can fold the result.  If not, this
55460b57cec5SDimitry Andric /// returns null.
55470b57cec5SDimitry Andric static Value *simplifyFNegInst(Value *Op, FastMathFlags FMF,
55480b57cec5SDimitry Andric                                const SimplifyQuery &Q, unsigned MaxRecurse) {
55490b57cec5SDimitry Andric   if (Constant *C = foldConstant(Instruction::FNeg, Op, Q))
55500b57cec5SDimitry Andric     return C;
55510b57cec5SDimitry Andric 
55520b57cec5SDimitry Andric   Value *X;
55530b57cec5SDimitry Andric   // fneg (fneg X) ==> X
55540b57cec5SDimitry Andric   if (match(Op, m_FNeg(m_Value(X))))
55550b57cec5SDimitry Andric     return X;
55560b57cec5SDimitry Andric 
55570b57cec5SDimitry Andric   return nullptr;
55580b57cec5SDimitry Andric }
55590b57cec5SDimitry Andric 
556081ad6265SDimitry Andric Value *llvm::simplifyFNegInst(Value *Op, FastMathFlags FMF,
55610b57cec5SDimitry Andric                               const SimplifyQuery &Q) {
55620b57cec5SDimitry Andric   return ::simplifyFNegInst(Op, FMF, Q, RecursionLimit);
55630b57cec5SDimitry Andric }
55640b57cec5SDimitry Andric 
5565bdd1243dSDimitry Andric /// Try to propagate existing NaN values when possible. If not, replace the
5566bdd1243dSDimitry Andric /// constant or elements in the constant with a canonical NaN.
55670b57cec5SDimitry Andric static Constant *propagateNaN(Constant *In) {
556806c3fb27SDimitry Andric   Type *Ty = In->getType();
556906c3fb27SDimitry Andric   if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) {
5570bdd1243dSDimitry Andric     unsigned NumElts = VecTy->getNumElements();
5571bdd1243dSDimitry Andric     SmallVector<Constant *, 32> NewC(NumElts);
5572bdd1243dSDimitry Andric     for (unsigned i = 0; i != NumElts; ++i) {
5573bdd1243dSDimitry Andric       Constant *EltC = In->getAggregateElement(i);
557406c3fb27SDimitry Andric       // Poison elements propagate. NaN propagates except signaling is quieted.
5575bdd1243dSDimitry Andric       // Replace unknown or undef elements with canonical NaN.
557606c3fb27SDimitry Andric       if (EltC && isa<PoisonValue>(EltC))
5577bdd1243dSDimitry Andric         NewC[i] = EltC;
557806c3fb27SDimitry Andric       else if (EltC && EltC->isNaN())
557906c3fb27SDimitry Andric         NewC[i] = ConstantFP::get(
558006c3fb27SDimitry Andric             EltC->getType(), cast<ConstantFP>(EltC)->getValue().makeQuiet());
5581bdd1243dSDimitry Andric       else
558206c3fb27SDimitry Andric         NewC[i] = ConstantFP::getNaN(VecTy->getElementType());
5583bdd1243dSDimitry Andric     }
5584bdd1243dSDimitry Andric     return ConstantVector::get(NewC);
5585bdd1243dSDimitry Andric   }
5586bdd1243dSDimitry Andric 
558706c3fb27SDimitry Andric   // If it is not a fixed vector, but not a simple NaN either, return a
558806c3fb27SDimitry Andric   // canonical NaN.
55890b57cec5SDimitry Andric   if (!In->isNaN())
559006c3fb27SDimitry Andric     return ConstantFP::getNaN(Ty);
55910b57cec5SDimitry Andric 
559206c3fb27SDimitry Andric   // If we known this is a NaN, and it's scalable vector, we must have a splat
559306c3fb27SDimitry Andric   // on our hands. Grab that before splatting a QNaN constant.
559406c3fb27SDimitry Andric   if (isa<ScalableVectorType>(Ty)) {
559506c3fb27SDimitry Andric     auto *Splat = In->getSplatValue();
559606c3fb27SDimitry Andric     assert(Splat && Splat->isNaN() &&
559706c3fb27SDimitry Andric            "Found a scalable-vector NaN but not a splat");
559806c3fb27SDimitry Andric     In = Splat;
559906c3fb27SDimitry Andric   }
560006c3fb27SDimitry Andric 
560106c3fb27SDimitry Andric   // Propagate an existing QNaN constant. If it is an SNaN, make it quiet, but
560206c3fb27SDimitry Andric   // preserve the sign/payload.
560306c3fb27SDimitry Andric   return ConstantFP::get(Ty, cast<ConstantFP>(In)->getValue().makeQuiet());
56040b57cec5SDimitry Andric }
56050b57cec5SDimitry Andric 
56068bcb0991SDimitry Andric /// Perform folds that are common to any floating-point operation. This implies
5607fe6060f1SDimitry Andric /// transforms based on poison/undef/NaN because the operation itself makes no
56088bcb0991SDimitry Andric /// difference to the result.
5609fe6060f1SDimitry Andric static Constant *simplifyFPOp(ArrayRef<Value *> Ops, FastMathFlags FMF,
5610fe6060f1SDimitry Andric                               const SimplifyQuery &Q,
5611fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5612fe6060f1SDimitry Andric                               RoundingMode Rounding) {
5613fe6060f1SDimitry Andric   // Poison is independent of anything else. It always propagates from an
5614fe6060f1SDimitry Andric   // operand to a math result.
5615fe6060f1SDimitry Andric   if (any_of(Ops, [](Value *V) { return match(V, m_Poison()); }))
5616fe6060f1SDimitry Andric     return PoisonValue::get(Ops[0]->getType());
5617fe6060f1SDimitry Andric 
56185ffd83dbSDimitry Andric   for (Value *V : Ops) {
56195ffd83dbSDimitry Andric     bool IsNan = match(V, m_NaN());
56205ffd83dbSDimitry Andric     bool IsInf = match(V, m_Inf());
5621e8d8bef9SDimitry Andric     bool IsUndef = Q.isUndefValue(V);
56220b57cec5SDimitry Andric 
56235ffd83dbSDimitry Andric     // If this operation has 'nnan' or 'ninf' and at least 1 disallowed operand
56245ffd83dbSDimitry Andric     // (an undef operand can be chosen to be Nan/Inf), then the result of
5625e8d8bef9SDimitry Andric     // this operation is poison.
56265ffd83dbSDimitry Andric     if (FMF.noNaNs() && (IsNan || IsUndef))
5627e8d8bef9SDimitry Andric       return PoisonValue::get(V->getType());
56285ffd83dbSDimitry Andric     if (FMF.noInfs() && (IsInf || IsUndef))
5629e8d8bef9SDimitry Andric       return PoisonValue::get(V->getType());
56305ffd83dbSDimitry Andric 
5631fe6060f1SDimitry Andric     if (isDefaultFPEnvironment(ExBehavior, Rounding)) {
5632bdd1243dSDimitry Andric       // Undef does not propagate because undef means that all bits can take on
5633bdd1243dSDimitry Andric       // any value. If this is undef * NaN for example, then the result values
5634bdd1243dSDimitry Andric       // (at least the exponent bits) are limited. Assume the undef is a
5635bdd1243dSDimitry Andric       // canonical NaN and propagate that.
5636bdd1243dSDimitry Andric       if (IsUndef)
5637bdd1243dSDimitry Andric         return ConstantFP::getNaN(V->getType());
5638bdd1243dSDimitry Andric       if (IsNan)
56398bcb0991SDimitry Andric         return propagateNaN(cast<Constant>(V));
5640fe6060f1SDimitry Andric     } else if (ExBehavior != fp::ebStrict) {
5641fe6060f1SDimitry Andric       if (IsNan)
5642fe6060f1SDimitry Andric         return propagateNaN(cast<Constant>(V));
5643fe6060f1SDimitry Andric     }
56445ffd83dbSDimitry Andric   }
56450b57cec5SDimitry Andric   return nullptr;
56460b57cec5SDimitry Andric }
56470b57cec5SDimitry Andric 
56480b57cec5SDimitry Andric /// Given operands for an FAdd, see if we can fold the result.  If not, this
56490b57cec5SDimitry Andric /// returns null.
5650fe6060f1SDimitry Andric static Value *
565181ad6265SDimitry Andric simplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5652fe6060f1SDimitry Andric                  const SimplifyQuery &Q, unsigned MaxRecurse,
5653fe6060f1SDimitry Andric                  fp::ExceptionBehavior ExBehavior = fp::ebIgnore,
5654fe6060f1SDimitry Andric                  RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5655fe6060f1SDimitry Andric   if (isDefaultFPEnvironment(ExBehavior, Rounding))
56560b57cec5SDimitry Andric     if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
56570b57cec5SDimitry Andric       return C;
56580b57cec5SDimitry Andric 
5659fe6060f1SDimitry Andric   if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q, ExBehavior, Rounding))
56600b57cec5SDimitry Andric     return C;
56610b57cec5SDimitry Andric 
56620b57cec5SDimitry Andric   // fadd X, -0 ==> X
5663349cc55cSDimitry Andric   // With strict/constrained FP, we have these possible edge cases that do
5664349cc55cSDimitry Andric   // not simplify to Op0:
5665349cc55cSDimitry Andric   // fadd SNaN, -0.0 --> QNaN
5666349cc55cSDimitry Andric   // fadd +0.0, -0.0 --> -0.0 (but only with round toward negative)
5667349cc55cSDimitry Andric   if (canIgnoreSNaN(ExBehavior, FMF) &&
5668349cc55cSDimitry Andric       (!canRoundingModeBe(Rounding, RoundingMode::TowardNegative) ||
5669349cc55cSDimitry Andric        FMF.noSignedZeros()))
56700b57cec5SDimitry Andric     if (match(Op1, m_NegZeroFP()))
56710b57cec5SDimitry Andric       return Op0;
56720b57cec5SDimitry Andric 
56730b57cec5SDimitry Andric   // fadd X, 0 ==> X, when we know X is not -0
5674349cc55cSDimitry Andric   if (canIgnoreSNaN(ExBehavior, FMF))
56750b57cec5SDimitry Andric     if (match(Op1, m_PosZeroFP()) &&
5676*0fca6ea1SDimitry Andric         (FMF.noSignedZeros() || cannotBeNegativeZero(Op0, /*Depth=*/0, Q)))
56770b57cec5SDimitry Andric       return Op0;
56780b57cec5SDimitry Andric 
5679349cc55cSDimitry Andric   if (!isDefaultFPEnvironment(ExBehavior, Rounding))
5680349cc55cSDimitry Andric     return nullptr;
5681349cc55cSDimitry Andric 
5682bdd1243dSDimitry Andric   if (FMF.noNaNs()) {
5683bdd1243dSDimitry Andric     // With nnan: X + {+/-}Inf --> {+/-}Inf
5684bdd1243dSDimitry Andric     if (match(Op1, m_Inf()))
5685bdd1243dSDimitry Andric       return Op1;
5686bdd1243dSDimitry Andric 
56870b57cec5SDimitry Andric     // With nnan: -X + X --> 0.0 (and commuted variant)
56880b57cec5SDimitry Andric     // We don't have to explicitly exclude infinities (ninf): INF + -INF == NaN.
56890b57cec5SDimitry Andric     // Negative zeros are allowed because we always end up with positive zero:
56900b57cec5SDimitry Andric     // X = -0.0: (-0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0
56910b57cec5SDimitry Andric     // X = -0.0: ( 0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0
56920b57cec5SDimitry Andric     // X =  0.0: (-0.0 - ( 0.0)) + ( 0.0) == (-0.0) + ( 0.0) == 0.0
56930b57cec5SDimitry Andric     // X =  0.0: ( 0.0 - ( 0.0)) + ( 0.0) == ( 0.0) + ( 0.0) == 0.0
56940b57cec5SDimitry Andric     if (match(Op0, m_FSub(m_AnyZeroFP(), m_Specific(Op1))) ||
56950b57cec5SDimitry Andric         match(Op1, m_FSub(m_AnyZeroFP(), m_Specific(Op0))))
569606c3fb27SDimitry Andric       return ConstantFP::getZero(Op0->getType());
56970b57cec5SDimitry Andric 
56980b57cec5SDimitry Andric     if (match(Op0, m_FNeg(m_Specific(Op1))) ||
56990b57cec5SDimitry Andric         match(Op1, m_FNeg(m_Specific(Op0))))
570006c3fb27SDimitry Andric       return ConstantFP::getZero(Op0->getType());
57010b57cec5SDimitry Andric   }
57020b57cec5SDimitry Andric 
57030b57cec5SDimitry Andric   // (X - Y) + Y --> X
57040b57cec5SDimitry Andric   // Y + (X - Y) --> X
57050b57cec5SDimitry Andric   Value *X;
57060b57cec5SDimitry Andric   if (FMF.noSignedZeros() && FMF.allowReassoc() &&
57070b57cec5SDimitry Andric       (match(Op0, m_FSub(m_Value(X), m_Specific(Op1))) ||
57080b57cec5SDimitry Andric        match(Op1, m_FSub(m_Value(X), m_Specific(Op0)))))
57090b57cec5SDimitry Andric     return X;
57100b57cec5SDimitry Andric 
57110b57cec5SDimitry Andric   return nullptr;
57120b57cec5SDimitry Andric }
57130b57cec5SDimitry Andric 
57140b57cec5SDimitry Andric /// Given operands for an FSub, see if we can fold the result.  If not, this
57150b57cec5SDimitry Andric /// returns null.
5716fe6060f1SDimitry Andric static Value *
571781ad6265SDimitry Andric simplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5718fe6060f1SDimitry Andric                  const SimplifyQuery &Q, unsigned MaxRecurse,
5719fe6060f1SDimitry Andric                  fp::ExceptionBehavior ExBehavior = fp::ebIgnore,
5720fe6060f1SDimitry Andric                  RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5721fe6060f1SDimitry Andric   if (isDefaultFPEnvironment(ExBehavior, Rounding))
57220b57cec5SDimitry Andric     if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
57230b57cec5SDimitry Andric       return C;
57240b57cec5SDimitry Andric 
5725fe6060f1SDimitry Andric   if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q, ExBehavior, Rounding))
57260b57cec5SDimitry Andric     return C;
57270b57cec5SDimitry Andric 
57280b57cec5SDimitry Andric   // fsub X, +0 ==> X
572981ad6265SDimitry Andric   if (canIgnoreSNaN(ExBehavior, FMF) &&
573081ad6265SDimitry Andric       (!canRoundingModeBe(Rounding, RoundingMode::TowardNegative) ||
573181ad6265SDimitry Andric        FMF.noSignedZeros()))
57320b57cec5SDimitry Andric     if (match(Op1, m_PosZeroFP()))
57330b57cec5SDimitry Andric       return Op0;
57340b57cec5SDimitry Andric 
57350b57cec5SDimitry Andric   // fsub X, -0 ==> X, when we know X is not -0
573681ad6265SDimitry Andric   if (canIgnoreSNaN(ExBehavior, FMF))
57370b57cec5SDimitry Andric     if (match(Op1, m_NegZeroFP()) &&
5738*0fca6ea1SDimitry Andric         (FMF.noSignedZeros() || cannotBeNegativeZero(Op0, /*Depth=*/0, Q)))
57390b57cec5SDimitry Andric       return Op0;
57400b57cec5SDimitry Andric 
57410b57cec5SDimitry Andric   // fsub -0.0, (fsub -0.0, X) ==> X
57420b57cec5SDimitry Andric   // fsub -0.0, (fneg X) ==> X
57430b57cec5SDimitry Andric   Value *X;
574481ad6265SDimitry Andric   if (canIgnoreSNaN(ExBehavior, FMF))
574581ad6265SDimitry Andric     if (match(Op0, m_NegZeroFP()) && match(Op1, m_FNeg(m_Value(X))))
57460b57cec5SDimitry Andric       return X;
57470b57cec5SDimitry Andric 
57480b57cec5SDimitry Andric   // fsub 0.0, (fsub 0.0, X) ==> X if signed zeros are ignored.
57490b57cec5SDimitry Andric   // fsub 0.0, (fneg X) ==> X if signed zeros are ignored.
5750bdd1243dSDimitry Andric   if (canIgnoreSNaN(ExBehavior, FMF))
57510b57cec5SDimitry Andric     if (FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()) &&
57520b57cec5SDimitry Andric         (match(Op1, m_FSub(m_AnyZeroFP(), m_Value(X))) ||
57530b57cec5SDimitry Andric          match(Op1, m_FNeg(m_Value(X)))))
57540b57cec5SDimitry Andric       return X;
57550b57cec5SDimitry Andric 
5756bdd1243dSDimitry Andric   if (!isDefaultFPEnvironment(ExBehavior, Rounding))
5757bdd1243dSDimitry Andric     return nullptr;
5758bdd1243dSDimitry Andric 
5759bdd1243dSDimitry Andric   if (FMF.noNaNs()) {
57600b57cec5SDimitry Andric     // fsub nnan x, x ==> 0.0
5761bdd1243dSDimitry Andric     if (Op0 == Op1)
57620b57cec5SDimitry Andric       return Constant::getNullValue(Op0->getType());
57630b57cec5SDimitry Andric 
5764bdd1243dSDimitry Andric     // With nnan: {+/-}Inf - X --> {+/-}Inf
5765bdd1243dSDimitry Andric     if (match(Op0, m_Inf()))
5766bdd1243dSDimitry Andric       return Op0;
5767bdd1243dSDimitry Andric 
5768bdd1243dSDimitry Andric     // With nnan: X - {+/-}Inf --> {-/+}Inf
5769bdd1243dSDimitry Andric     if (match(Op1, m_Inf()))
5770bdd1243dSDimitry Andric       return foldConstant(Instruction::FNeg, Op1, Q);
5771bdd1243dSDimitry Andric   }
5772bdd1243dSDimitry Andric 
57730b57cec5SDimitry Andric   // Y - (Y - X) --> X
57740b57cec5SDimitry Andric   // (X + Y) - Y --> X
57750b57cec5SDimitry Andric   if (FMF.noSignedZeros() && FMF.allowReassoc() &&
57760b57cec5SDimitry Andric       (match(Op1, m_FSub(m_Specific(Op0), m_Value(X))) ||
57770b57cec5SDimitry Andric        match(Op0, m_c_FAdd(m_Specific(Op1), m_Value(X)))))
57780b57cec5SDimitry Andric     return X;
57790b57cec5SDimitry Andric 
57800b57cec5SDimitry Andric   return nullptr;
57810b57cec5SDimitry Andric }
57820b57cec5SDimitry Andric 
578381ad6265SDimitry Andric static Value *simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
5784fe6060f1SDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse,
5785fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5786fe6060f1SDimitry Andric                               RoundingMode Rounding) {
5787fe6060f1SDimitry Andric   if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q, ExBehavior, Rounding))
57880b57cec5SDimitry Andric     return C;
57890b57cec5SDimitry Andric 
5790fe6060f1SDimitry Andric   if (!isDefaultFPEnvironment(ExBehavior, Rounding))
5791fe6060f1SDimitry Andric     return nullptr;
5792fe6060f1SDimitry Andric 
5793bdd1243dSDimitry Andric   // Canonicalize special constants as operand 1.
5794bdd1243dSDimitry Andric   if (match(Op0, m_FPOne()) || match(Op0, m_AnyZeroFP()))
5795bdd1243dSDimitry Andric     std::swap(Op0, Op1);
5796bdd1243dSDimitry Andric 
5797bdd1243dSDimitry Andric   // X * 1.0 --> X
57980b57cec5SDimitry Andric   if (match(Op1, m_FPOne()))
57990b57cec5SDimitry Andric     return Op0;
58000b57cec5SDimitry Andric 
5801bdd1243dSDimitry Andric   if (match(Op1, m_AnyZeroFP())) {
5802bdd1243dSDimitry Andric     // X * 0.0 --> 0.0 (with nnan and nsz)
5803bdd1243dSDimitry Andric     if (FMF.noNaNs() && FMF.noSignedZeros())
580406c3fb27SDimitry Andric       return ConstantFP::getZero(Op0->getType());
58050b57cec5SDimitry Andric 
5806*0fca6ea1SDimitry Andric     KnownFPClass Known =
5807*0fca6ea1SDimitry Andric         computeKnownFPClass(Op0, FMF, fcInf | fcNan, /*Depth=*/0, Q);
5808*0fca6ea1SDimitry Andric     if (Known.isKnownNever(fcInf | fcNan)) {
5809bdd1243dSDimitry Andric       // +normal number * (-)0.0 --> (-)0.0
5810*0fca6ea1SDimitry Andric       if (Known.SignBit == false)
5811bdd1243dSDimitry Andric         return Op1;
5812*0fca6ea1SDimitry Andric       // -normal number * (-)0.0 --> -(-)0.0
5813*0fca6ea1SDimitry Andric       if (Known.SignBit == true)
5814*0fca6ea1SDimitry Andric         return foldConstant(Instruction::FNeg, Op1, Q);
5815*0fca6ea1SDimitry Andric     }
5816bdd1243dSDimitry Andric   }
58178bcb0991SDimitry Andric 
58180b57cec5SDimitry Andric   // sqrt(X) * sqrt(X) --> X, if we can:
58190b57cec5SDimitry Andric   // 1. Remove the intermediate rounding (reassociate).
58200b57cec5SDimitry Andric   // 2. Ignore non-zero negative numbers because sqrt would produce NAN.
58210b57cec5SDimitry Andric   // 3. Ignore -0.0 because sqrt(-0.0) == -0.0, but -0.0 * -0.0 == 0.0.
58220b57cec5SDimitry Andric   Value *X;
582381ad6265SDimitry Andric   if (Op0 == Op1 && match(Op0, m_Sqrt(m_Value(X))) && FMF.allowReassoc() &&
582481ad6265SDimitry Andric       FMF.noNaNs() && FMF.noSignedZeros())
58250b57cec5SDimitry Andric     return X;
58260b57cec5SDimitry Andric 
58270b57cec5SDimitry Andric   return nullptr;
58280b57cec5SDimitry Andric }
58290b57cec5SDimitry Andric 
58308bcb0991SDimitry Andric /// Given the operands for an FMul, see if we can fold the result
5831fe6060f1SDimitry Andric static Value *
583281ad6265SDimitry Andric simplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5833fe6060f1SDimitry Andric                  const SimplifyQuery &Q, unsigned MaxRecurse,
5834fe6060f1SDimitry Andric                  fp::ExceptionBehavior ExBehavior = fp::ebIgnore,
5835fe6060f1SDimitry Andric                  RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5836fe6060f1SDimitry Andric   if (isDefaultFPEnvironment(ExBehavior, Rounding))
58378bcb0991SDimitry Andric     if (Constant *C = foldOrCommuteConstant(Instruction::FMul, Op0, Op1, Q))
58388bcb0991SDimitry Andric       return C;
58398bcb0991SDimitry Andric 
58408bcb0991SDimitry Andric   // Now apply simplifications that do not require rounding.
584181ad6265SDimitry Andric   return simplifyFMAFMul(Op0, Op1, FMF, Q, MaxRecurse, ExBehavior, Rounding);
58428bcb0991SDimitry Andric }
58438bcb0991SDimitry Andric 
584481ad6265SDimitry Andric Value *llvm::simplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5845fe6060f1SDimitry Andric                               const SimplifyQuery &Q,
5846fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5847fe6060f1SDimitry Andric                               RoundingMode Rounding) {
584881ad6265SDimitry Andric   return ::simplifyFAddInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5849fe6060f1SDimitry Andric                             Rounding);
58500b57cec5SDimitry Andric }
58510b57cec5SDimitry Andric 
585281ad6265SDimitry Andric Value *llvm::simplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5853fe6060f1SDimitry Andric                               const SimplifyQuery &Q,
5854fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5855fe6060f1SDimitry Andric                               RoundingMode Rounding) {
585681ad6265SDimitry Andric   return ::simplifyFSubInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5857fe6060f1SDimitry Andric                             Rounding);
58580b57cec5SDimitry Andric }
58590b57cec5SDimitry Andric 
586081ad6265SDimitry Andric Value *llvm::simplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5861fe6060f1SDimitry Andric                               const SimplifyQuery &Q,
5862fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5863fe6060f1SDimitry Andric                               RoundingMode Rounding) {
586481ad6265SDimitry Andric   return ::simplifyFMulInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5865fe6060f1SDimitry Andric                             Rounding);
58660b57cec5SDimitry Andric }
58670b57cec5SDimitry Andric 
586881ad6265SDimitry Andric Value *llvm::simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
5869fe6060f1SDimitry Andric                              const SimplifyQuery &Q,
5870fe6060f1SDimitry Andric                              fp::ExceptionBehavior ExBehavior,
5871fe6060f1SDimitry Andric                              RoundingMode Rounding) {
587281ad6265SDimitry Andric   return ::simplifyFMAFMul(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5873fe6060f1SDimitry Andric                            Rounding);
58748bcb0991SDimitry Andric }
58758bcb0991SDimitry Andric 
5876fe6060f1SDimitry Andric static Value *
587781ad6265SDimitry Andric simplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5878fe6060f1SDimitry Andric                  const SimplifyQuery &Q, unsigned,
5879fe6060f1SDimitry Andric                  fp::ExceptionBehavior ExBehavior = fp::ebIgnore,
5880fe6060f1SDimitry Andric                  RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5881fe6060f1SDimitry Andric   if (isDefaultFPEnvironment(ExBehavior, Rounding))
58820b57cec5SDimitry Andric     if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
58830b57cec5SDimitry Andric       return C;
58840b57cec5SDimitry Andric 
5885fe6060f1SDimitry Andric   if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q, ExBehavior, Rounding))
58860b57cec5SDimitry Andric     return C;
58870b57cec5SDimitry Andric 
5888fe6060f1SDimitry Andric   if (!isDefaultFPEnvironment(ExBehavior, Rounding))
5889fe6060f1SDimitry Andric     return nullptr;
5890fe6060f1SDimitry Andric 
58910b57cec5SDimitry Andric   // X / 1.0 -> X
58920b57cec5SDimitry Andric   if (match(Op1, m_FPOne()))
58930b57cec5SDimitry Andric     return Op0;
58940b57cec5SDimitry Andric 
58950b57cec5SDimitry Andric   // 0 / X -> 0
58960b57cec5SDimitry Andric   // Requires that NaNs are off (X could be zero) and signed zeroes are
58970b57cec5SDimitry Andric   // ignored (X could be positive or negative, so the output sign is unknown).
58980b57cec5SDimitry Andric   if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()))
589906c3fb27SDimitry Andric     return ConstantFP::getZero(Op0->getType());
59000b57cec5SDimitry Andric 
59010b57cec5SDimitry Andric   if (FMF.noNaNs()) {
59020b57cec5SDimitry Andric     // X / X -> 1.0 is legal when NaNs are ignored.
59030b57cec5SDimitry Andric     // We can ignore infinities because INF/INF is NaN.
59040b57cec5SDimitry Andric     if (Op0 == Op1)
59050b57cec5SDimitry Andric       return ConstantFP::get(Op0->getType(), 1.0);
59060b57cec5SDimitry Andric 
59070b57cec5SDimitry Andric     // (X * Y) / Y --> X if we can reassociate to the above form.
59080b57cec5SDimitry Andric     Value *X;
59090b57cec5SDimitry Andric     if (FMF.allowReassoc() && match(Op0, m_c_FMul(m_Value(X), m_Specific(Op1))))
59100b57cec5SDimitry Andric       return X;
59110b57cec5SDimitry Andric 
59120b57cec5SDimitry Andric     // -X /  X -> -1.0 and
59130b57cec5SDimitry Andric     //  X / -X -> -1.0 are legal when NaNs are ignored.
59140b57cec5SDimitry Andric     // We can ignore signed zeros because +-0.0/+-0.0 is NaN and ignored.
59150b57cec5SDimitry Andric     if (match(Op0, m_FNegNSZ(m_Specific(Op1))) ||
59160b57cec5SDimitry Andric         match(Op1, m_FNegNSZ(m_Specific(Op0))))
59170b57cec5SDimitry Andric       return ConstantFP::get(Op0->getType(), -1.0);
5918bdd1243dSDimitry Andric 
5919bdd1243dSDimitry Andric     // nnan ninf X / [-]0.0 -> poison
5920bdd1243dSDimitry Andric     if (FMF.noInfs() && match(Op1, m_AnyZeroFP()))
5921bdd1243dSDimitry Andric       return PoisonValue::get(Op1->getType());
59220b57cec5SDimitry Andric   }
59230b57cec5SDimitry Andric 
59240b57cec5SDimitry Andric   return nullptr;
59250b57cec5SDimitry Andric }
59260b57cec5SDimitry Andric 
592781ad6265SDimitry Andric Value *llvm::simplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5928fe6060f1SDimitry Andric                               const SimplifyQuery &Q,
5929fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5930fe6060f1SDimitry Andric                               RoundingMode Rounding) {
593181ad6265SDimitry Andric   return ::simplifyFDivInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5932fe6060f1SDimitry Andric                             Rounding);
59330b57cec5SDimitry Andric }
59340b57cec5SDimitry Andric 
5935fe6060f1SDimitry Andric static Value *
593681ad6265SDimitry Andric simplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5937fe6060f1SDimitry Andric                  const SimplifyQuery &Q, unsigned,
5938fe6060f1SDimitry Andric                  fp::ExceptionBehavior ExBehavior = fp::ebIgnore,
5939fe6060f1SDimitry Andric                  RoundingMode Rounding = RoundingMode::NearestTiesToEven) {
5940fe6060f1SDimitry Andric   if (isDefaultFPEnvironment(ExBehavior, Rounding))
59410b57cec5SDimitry Andric     if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
59420b57cec5SDimitry Andric       return C;
59430b57cec5SDimitry Andric 
5944fe6060f1SDimitry Andric   if (Constant *C = simplifyFPOp({Op0, Op1}, FMF, Q, ExBehavior, Rounding))
59450b57cec5SDimitry Andric     return C;
59460b57cec5SDimitry Andric 
5947fe6060f1SDimitry Andric   if (!isDefaultFPEnvironment(ExBehavior, Rounding))
5948fe6060f1SDimitry Andric     return nullptr;
5949fe6060f1SDimitry Andric 
59500b57cec5SDimitry Andric   // Unlike fdiv, the result of frem always matches the sign of the dividend.
59510b57cec5SDimitry Andric   // The constant match may include undef elements in a vector, so return a full
59520b57cec5SDimitry Andric   // zero constant as the result.
59530b57cec5SDimitry Andric   if (FMF.noNaNs()) {
59540b57cec5SDimitry Andric     // +0 % X -> 0
59550b57cec5SDimitry Andric     if (match(Op0, m_PosZeroFP()))
595606c3fb27SDimitry Andric       return ConstantFP::getZero(Op0->getType());
59570b57cec5SDimitry Andric     // -0 % X -> -0
59580b57cec5SDimitry Andric     if (match(Op0, m_NegZeroFP()))
59590b57cec5SDimitry Andric       return ConstantFP::getNegativeZero(Op0->getType());
59600b57cec5SDimitry Andric   }
59610b57cec5SDimitry Andric 
59620b57cec5SDimitry Andric   return nullptr;
59630b57cec5SDimitry Andric }
59640b57cec5SDimitry Andric 
596581ad6265SDimitry Andric Value *llvm::simplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
5966fe6060f1SDimitry Andric                               const SimplifyQuery &Q,
5967fe6060f1SDimitry Andric                               fp::ExceptionBehavior ExBehavior,
5968fe6060f1SDimitry Andric                               RoundingMode Rounding) {
596981ad6265SDimitry Andric   return ::simplifyFRemInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,
5970fe6060f1SDimitry Andric                             Rounding);
59710b57cec5SDimitry Andric }
59720b57cec5SDimitry Andric 
59730b57cec5SDimitry Andric //=== Helper functions for higher up the class hierarchy.
59740b57cec5SDimitry Andric 
59750b57cec5SDimitry Andric /// Given the operand for a UnaryOperator, see if we can fold the result.
59760b57cec5SDimitry Andric /// If not, this returns null.
59770b57cec5SDimitry Andric static Value *simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q,
59780b57cec5SDimitry Andric                            unsigned MaxRecurse) {
59790b57cec5SDimitry Andric   switch (Opcode) {
59800b57cec5SDimitry Andric   case Instruction::FNeg:
59810b57cec5SDimitry Andric     return simplifyFNegInst(Op, FastMathFlags(), Q, MaxRecurse);
59820b57cec5SDimitry Andric   default:
59830b57cec5SDimitry Andric     llvm_unreachable("Unexpected opcode");
59840b57cec5SDimitry Andric   }
59850b57cec5SDimitry Andric }
59860b57cec5SDimitry Andric 
59870b57cec5SDimitry Andric /// Given the operand for a UnaryOperator, see if we can fold the result.
59880b57cec5SDimitry Andric /// If not, this returns null.
59898bcb0991SDimitry Andric /// Try to use FastMathFlags when folding the result.
59900b57cec5SDimitry Andric static Value *simplifyFPUnOp(unsigned Opcode, Value *Op,
599181ad6265SDimitry Andric                              const FastMathFlags &FMF, const SimplifyQuery &Q,
599281ad6265SDimitry Andric                              unsigned MaxRecurse) {
59930b57cec5SDimitry Andric   switch (Opcode) {
59940b57cec5SDimitry Andric   case Instruction::FNeg:
59950b57cec5SDimitry Andric     return simplifyFNegInst(Op, FMF, Q, MaxRecurse);
59960b57cec5SDimitry Andric   default:
59970b57cec5SDimitry Andric     return simplifyUnOp(Opcode, Op, Q, MaxRecurse);
59980b57cec5SDimitry Andric   }
59990b57cec5SDimitry Andric }
60000b57cec5SDimitry Andric 
600181ad6265SDimitry Andric Value *llvm::simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q) {
60020b57cec5SDimitry Andric   return ::simplifyUnOp(Opcode, Op, Q, RecursionLimit);
60030b57cec5SDimitry Andric }
60040b57cec5SDimitry Andric 
600581ad6265SDimitry Andric Value *llvm::simplifyUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
60060b57cec5SDimitry Andric                           const SimplifyQuery &Q) {
60070b57cec5SDimitry Andric   return ::simplifyFPUnOp(Opcode, Op, FMF, Q, RecursionLimit);
60080b57cec5SDimitry Andric }
60090b57cec5SDimitry Andric 
60100b57cec5SDimitry Andric /// Given operands for a BinaryOperator, see if we can fold the result.
60110b57cec5SDimitry Andric /// If not, this returns null.
601281ad6265SDimitry Andric static Value *simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
60130b57cec5SDimitry Andric                             const SimplifyQuery &Q, unsigned MaxRecurse) {
60140b57cec5SDimitry Andric   switch (Opcode) {
60150b57cec5SDimitry Andric   case Instruction::Add:
6016bdd1243dSDimitry Andric     return simplifyAddInst(LHS, RHS, /* IsNSW */ false, /* IsNUW */ false, Q,
6017bdd1243dSDimitry Andric                            MaxRecurse);
60180b57cec5SDimitry Andric   case Instruction::Sub:
6019bdd1243dSDimitry Andric     return simplifySubInst(LHS, RHS,  /* IsNSW */ false, /* IsNUW */ false, Q,
6020bdd1243dSDimitry Andric                            MaxRecurse);
60210b57cec5SDimitry Andric   case Instruction::Mul:
6022bdd1243dSDimitry Andric     return simplifyMulInst(LHS, RHS, /* IsNSW */ false, /* IsNUW */ false, Q,
6023bdd1243dSDimitry Andric                            MaxRecurse);
60240b57cec5SDimitry Andric   case Instruction::SDiv:
6025bdd1243dSDimitry Andric     return simplifySDivInst(LHS, RHS, /* IsExact */ false, Q, MaxRecurse);
60260b57cec5SDimitry Andric   case Instruction::UDiv:
6027bdd1243dSDimitry Andric     return simplifyUDivInst(LHS, RHS, /* IsExact */ false, Q, MaxRecurse);
60280b57cec5SDimitry Andric   case Instruction::SRem:
602981ad6265SDimitry Andric     return simplifySRemInst(LHS, RHS, Q, MaxRecurse);
60300b57cec5SDimitry Andric   case Instruction::URem:
603181ad6265SDimitry Andric     return simplifyURemInst(LHS, RHS, Q, MaxRecurse);
60320b57cec5SDimitry Andric   case Instruction::Shl:
6033bdd1243dSDimitry Andric     return simplifyShlInst(LHS, RHS, /* IsNSW */ false, /* IsNUW */ false, Q,
6034bdd1243dSDimitry Andric                            MaxRecurse);
60350b57cec5SDimitry Andric   case Instruction::LShr:
6036bdd1243dSDimitry Andric     return simplifyLShrInst(LHS, RHS, /* IsExact */ false, Q, MaxRecurse);
60370b57cec5SDimitry Andric   case Instruction::AShr:
6038bdd1243dSDimitry Andric     return simplifyAShrInst(LHS, RHS, /* IsExact */ false, Q, MaxRecurse);
60390b57cec5SDimitry Andric   case Instruction::And:
604081ad6265SDimitry Andric     return simplifyAndInst(LHS, RHS, Q, MaxRecurse);
60410b57cec5SDimitry Andric   case Instruction::Or:
604281ad6265SDimitry Andric     return simplifyOrInst(LHS, RHS, Q, MaxRecurse);
60430b57cec5SDimitry Andric   case Instruction::Xor:
604481ad6265SDimitry Andric     return simplifyXorInst(LHS, RHS, Q, MaxRecurse);
60450b57cec5SDimitry Andric   case Instruction::FAdd:
604681ad6265SDimitry Andric     return simplifyFAddInst(LHS, RHS, FastMathFlags(), Q, MaxRecurse);
60470b57cec5SDimitry Andric   case Instruction::FSub:
604881ad6265SDimitry Andric     return simplifyFSubInst(LHS, RHS, FastMathFlags(), Q, MaxRecurse);
60490b57cec5SDimitry Andric   case Instruction::FMul:
605081ad6265SDimitry Andric     return simplifyFMulInst(LHS, RHS, FastMathFlags(), Q, MaxRecurse);
60510b57cec5SDimitry Andric   case Instruction::FDiv:
605281ad6265SDimitry Andric     return simplifyFDivInst(LHS, RHS, FastMathFlags(), Q, MaxRecurse);
60530b57cec5SDimitry Andric   case Instruction::FRem:
605481ad6265SDimitry Andric     return simplifyFRemInst(LHS, RHS, FastMathFlags(), Q, MaxRecurse);
60550b57cec5SDimitry Andric   default:
60560b57cec5SDimitry Andric     llvm_unreachable("Unexpected opcode");
60570b57cec5SDimitry Andric   }
60580b57cec5SDimitry Andric }
60590b57cec5SDimitry Andric 
60600b57cec5SDimitry Andric /// Given operands for a BinaryOperator, see if we can fold the result.
60610b57cec5SDimitry Andric /// If not, this returns null.
60628bcb0991SDimitry Andric /// Try to use FastMathFlags when folding the result.
606381ad6265SDimitry Andric static Value *simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
60640b57cec5SDimitry Andric                             const FastMathFlags &FMF, const SimplifyQuery &Q,
60650b57cec5SDimitry Andric                             unsigned MaxRecurse) {
60660b57cec5SDimitry Andric   switch (Opcode) {
60670b57cec5SDimitry Andric   case Instruction::FAdd:
606881ad6265SDimitry Andric     return simplifyFAddInst(LHS, RHS, FMF, Q, MaxRecurse);
60690b57cec5SDimitry Andric   case Instruction::FSub:
607081ad6265SDimitry Andric     return simplifyFSubInst(LHS, RHS, FMF, Q, MaxRecurse);
60710b57cec5SDimitry Andric   case Instruction::FMul:
607281ad6265SDimitry Andric     return simplifyFMulInst(LHS, RHS, FMF, Q, MaxRecurse);
60730b57cec5SDimitry Andric   case Instruction::FDiv:
607481ad6265SDimitry Andric     return simplifyFDivInst(LHS, RHS, FMF, Q, MaxRecurse);
60750b57cec5SDimitry Andric   default:
607681ad6265SDimitry Andric     return simplifyBinOp(Opcode, LHS, RHS, Q, MaxRecurse);
60770b57cec5SDimitry Andric   }
60780b57cec5SDimitry Andric }
60790b57cec5SDimitry Andric 
608081ad6265SDimitry Andric Value *llvm::simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
60810b57cec5SDimitry Andric                            const SimplifyQuery &Q) {
608281ad6265SDimitry Andric   return ::simplifyBinOp(Opcode, LHS, RHS, Q, RecursionLimit);
60830b57cec5SDimitry Andric }
60840b57cec5SDimitry Andric 
608581ad6265SDimitry Andric Value *llvm::simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
60860b57cec5SDimitry Andric                            FastMathFlags FMF, const SimplifyQuery &Q) {
608781ad6265SDimitry Andric   return ::simplifyBinOp(Opcode, LHS, RHS, FMF, Q, RecursionLimit);
60880b57cec5SDimitry Andric }
60890b57cec5SDimitry Andric 
60900b57cec5SDimitry Andric /// Given operands for a CmpInst, see if we can fold the result.
609181ad6265SDimitry Andric static Value *simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
60920b57cec5SDimitry Andric                               const SimplifyQuery &Q, unsigned MaxRecurse) {
60930b57cec5SDimitry Andric   if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate))
609481ad6265SDimitry Andric     return simplifyICmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
609581ad6265SDimitry Andric   return simplifyFCmpInst(Predicate, LHS, RHS, FastMathFlags(), Q, MaxRecurse);
60960b57cec5SDimitry Andric }
60970b57cec5SDimitry Andric 
609881ad6265SDimitry Andric Value *llvm::simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
60990b57cec5SDimitry Andric                              const SimplifyQuery &Q) {
610081ad6265SDimitry Andric   return ::simplifyCmpInst(Predicate, LHS, RHS, Q, RecursionLimit);
61010b57cec5SDimitry Andric }
61020b57cec5SDimitry Andric 
610381ad6265SDimitry Andric static bool isIdempotent(Intrinsic::ID ID) {
61040b57cec5SDimitry Andric   switch (ID) {
610581ad6265SDimitry Andric   default:
610681ad6265SDimitry Andric     return false;
61070b57cec5SDimitry Andric 
61080b57cec5SDimitry Andric   // Unary idempotent: f(f(x)) = f(x)
61090b57cec5SDimitry Andric   case Intrinsic::fabs:
61100b57cec5SDimitry Andric   case Intrinsic::floor:
61110b57cec5SDimitry Andric   case Intrinsic::ceil:
61120b57cec5SDimitry Andric   case Intrinsic::trunc:
61130b57cec5SDimitry Andric   case Intrinsic::rint:
61140b57cec5SDimitry Andric   case Intrinsic::nearbyint:
61150b57cec5SDimitry Andric   case Intrinsic::round:
61165ffd83dbSDimitry Andric   case Intrinsic::roundeven:
61170b57cec5SDimitry Andric   case Intrinsic::canonicalize:
6118bdd1243dSDimitry Andric   case Intrinsic::arithmetic_fence:
6119bdd1243dSDimitry Andric     return true;
6120bdd1243dSDimitry Andric   }
6121bdd1243dSDimitry Andric }
6122bdd1243dSDimitry Andric 
6123bdd1243dSDimitry Andric /// Return true if the intrinsic rounds a floating-point value to an integral
6124bdd1243dSDimitry Andric /// floating-point value (not an integer type).
6125bdd1243dSDimitry Andric static bool removesFPFraction(Intrinsic::ID ID) {
6126bdd1243dSDimitry Andric   switch (ID) {
6127bdd1243dSDimitry Andric   default:
6128bdd1243dSDimitry Andric     return false;
6129bdd1243dSDimitry Andric 
6130bdd1243dSDimitry Andric   case Intrinsic::floor:
6131bdd1243dSDimitry Andric   case Intrinsic::ceil:
6132bdd1243dSDimitry Andric   case Intrinsic::trunc:
6133bdd1243dSDimitry Andric   case Intrinsic::rint:
6134bdd1243dSDimitry Andric   case Intrinsic::nearbyint:
6135bdd1243dSDimitry Andric   case Intrinsic::round:
6136bdd1243dSDimitry Andric   case Intrinsic::roundeven:
61370b57cec5SDimitry Andric     return true;
61380b57cec5SDimitry Andric   }
61390b57cec5SDimitry Andric }
61400b57cec5SDimitry Andric 
614181ad6265SDimitry Andric static Value *simplifyRelativeLoad(Constant *Ptr, Constant *Offset,
61420b57cec5SDimitry Andric                                    const DataLayout &DL) {
61430b57cec5SDimitry Andric   GlobalValue *PtrSym;
61440b57cec5SDimitry Andric   APInt PtrOffset;
61450b57cec5SDimitry Andric   if (!IsConstantOffsetFromGlobal(Ptr, PtrSym, PtrOffset, DL))
61460b57cec5SDimitry Andric     return nullptr;
61470b57cec5SDimitry Andric 
61480b57cec5SDimitry Andric   Type *Int32Ty = Type::getInt32Ty(Ptr->getContext());
61490b57cec5SDimitry Andric 
61500b57cec5SDimitry Andric   auto *OffsetConstInt = dyn_cast<ConstantInt>(Offset);
6151cb14a3feSDimitry Andric   if (!OffsetConstInt || OffsetConstInt->getBitWidth() > 64)
61520b57cec5SDimitry Andric     return nullptr;
61530b57cec5SDimitry Andric 
61545f757f3fSDimitry Andric   APInt OffsetInt = OffsetConstInt->getValue().sextOrTrunc(
61555f757f3fSDimitry Andric       DL.getIndexTypeSizeInBits(Ptr->getType()));
61565f757f3fSDimitry Andric   if (OffsetInt.srem(4) != 0)
61570b57cec5SDimitry Andric     return nullptr;
61580b57cec5SDimitry Andric 
6159*0fca6ea1SDimitry Andric   Constant *Loaded =
6160*0fca6ea1SDimitry Andric       ConstantFoldLoadFromConstPtr(Ptr, Int32Ty, std::move(OffsetInt), DL);
61610b57cec5SDimitry Andric   if (!Loaded)
61620b57cec5SDimitry Andric     return nullptr;
61630b57cec5SDimitry Andric 
61640b57cec5SDimitry Andric   auto *LoadedCE = dyn_cast<ConstantExpr>(Loaded);
61650b57cec5SDimitry Andric   if (!LoadedCE)
61660b57cec5SDimitry Andric     return nullptr;
61670b57cec5SDimitry Andric 
61680b57cec5SDimitry Andric   if (LoadedCE->getOpcode() == Instruction::Trunc) {
61690b57cec5SDimitry Andric     LoadedCE = dyn_cast<ConstantExpr>(LoadedCE->getOperand(0));
61700b57cec5SDimitry Andric     if (!LoadedCE)
61710b57cec5SDimitry Andric       return nullptr;
61720b57cec5SDimitry Andric   }
61730b57cec5SDimitry Andric 
61740b57cec5SDimitry Andric   if (LoadedCE->getOpcode() != Instruction::Sub)
61750b57cec5SDimitry Andric     return nullptr;
61760b57cec5SDimitry Andric 
61770b57cec5SDimitry Andric   auto *LoadedLHS = dyn_cast<ConstantExpr>(LoadedCE->getOperand(0));
61780b57cec5SDimitry Andric   if (!LoadedLHS || LoadedLHS->getOpcode() != Instruction::PtrToInt)
61790b57cec5SDimitry Andric     return nullptr;
61800b57cec5SDimitry Andric   auto *LoadedLHSPtr = LoadedLHS->getOperand(0);
61810b57cec5SDimitry Andric 
61820b57cec5SDimitry Andric   Constant *LoadedRHS = LoadedCE->getOperand(1);
61830b57cec5SDimitry Andric   GlobalValue *LoadedRHSSym;
61840b57cec5SDimitry Andric   APInt LoadedRHSOffset;
61850b57cec5SDimitry Andric   if (!IsConstantOffsetFromGlobal(LoadedRHS, LoadedRHSSym, LoadedRHSOffset,
61860b57cec5SDimitry Andric                                   DL) ||
61870b57cec5SDimitry Andric       PtrSym != LoadedRHSSym || PtrOffset != LoadedRHSOffset)
61880b57cec5SDimitry Andric     return nullptr;
61890b57cec5SDimitry Andric 
61905f757f3fSDimitry Andric   return LoadedLHSPtr;
61915f757f3fSDimitry Andric }
61925f757f3fSDimitry Andric 
61935f757f3fSDimitry Andric // TODO: Need to pass in FastMathFlags
61945f757f3fSDimitry Andric static Value *simplifyLdexp(Value *Op0, Value *Op1, const SimplifyQuery &Q,
61955f757f3fSDimitry Andric                             bool IsStrict) {
61965f757f3fSDimitry Andric   // ldexp(poison, x) -> poison
61975f757f3fSDimitry Andric   // ldexp(x, poison) -> poison
61985f757f3fSDimitry Andric   if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
61995f757f3fSDimitry Andric     return Op0;
62005f757f3fSDimitry Andric 
62015f757f3fSDimitry Andric   // ldexp(undef, x) -> nan
62025f757f3fSDimitry Andric   if (Q.isUndefValue(Op0))
62035f757f3fSDimitry Andric     return ConstantFP::getNaN(Op0->getType());
62045f757f3fSDimitry Andric 
62055f757f3fSDimitry Andric   if (!IsStrict) {
62065f757f3fSDimitry Andric     // TODO: Could insert a canonicalize for strict
62075f757f3fSDimitry Andric 
62085f757f3fSDimitry Andric     // ldexp(x, undef) -> x
62095f757f3fSDimitry Andric     if (Q.isUndefValue(Op1))
62105f757f3fSDimitry Andric       return Op0;
62115f757f3fSDimitry Andric   }
62125f757f3fSDimitry Andric 
62135f757f3fSDimitry Andric   const APFloat *C = nullptr;
62145f757f3fSDimitry Andric   match(Op0, PatternMatch::m_APFloat(C));
62155f757f3fSDimitry Andric 
62165f757f3fSDimitry Andric   // These cases should be safe, even with strictfp.
62175f757f3fSDimitry Andric   // ldexp(0.0, x) -> 0.0
62185f757f3fSDimitry Andric   // ldexp(-0.0, x) -> -0.0
62195f757f3fSDimitry Andric   // ldexp(inf, x) -> inf
62205f757f3fSDimitry Andric   // ldexp(-inf, x) -> -inf
62215f757f3fSDimitry Andric   if (C && (C->isZero() || C->isInfinity()))
62225f757f3fSDimitry Andric     return Op0;
62235f757f3fSDimitry Andric 
62245f757f3fSDimitry Andric   // These are canonicalization dropping, could do it if we knew how we could
62255f757f3fSDimitry Andric   // ignore denormal flushes and target handling of nan payload bits.
62265f757f3fSDimitry Andric   if (IsStrict)
62275f757f3fSDimitry Andric     return nullptr;
62285f757f3fSDimitry Andric 
62295f757f3fSDimitry Andric   // TODO: Could quiet this with strictfp if the exception mode isn't strict.
62305f757f3fSDimitry Andric   if (C && C->isNaN())
62315f757f3fSDimitry Andric     return ConstantFP::get(Op0->getType(), C->makeQuiet());
62325f757f3fSDimitry Andric 
62335f757f3fSDimitry Andric   // ldexp(x, 0) -> x
62345f757f3fSDimitry Andric 
62355f757f3fSDimitry Andric   // TODO: Could fold this if we know the exception mode isn't
62365f757f3fSDimitry Andric   // strict, we know the denormal mode and other target modes.
62375f757f3fSDimitry Andric   if (match(Op1, PatternMatch::m_ZeroInt()))
62385f757f3fSDimitry Andric     return Op0;
62395f757f3fSDimitry Andric 
62405f757f3fSDimitry Andric   return nullptr;
62410b57cec5SDimitry Andric }
62420b57cec5SDimitry Andric 
62430b57cec5SDimitry Andric static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
62445f757f3fSDimitry Andric                                      const SimplifyQuery &Q,
62455f757f3fSDimitry Andric                                      const CallBase *Call) {
62460b57cec5SDimitry Andric   // Idempotent functions return the same result when called repeatedly.
62470b57cec5SDimitry Andric   Intrinsic::ID IID = F->getIntrinsicID();
624881ad6265SDimitry Andric   if (isIdempotent(IID))
62490b57cec5SDimitry Andric     if (auto *II = dyn_cast<IntrinsicInst>(Op0))
62500b57cec5SDimitry Andric       if (II->getIntrinsicID() == IID)
62510b57cec5SDimitry Andric         return II;
62520b57cec5SDimitry Andric 
6253bdd1243dSDimitry Andric   if (removesFPFraction(IID)) {
6254bdd1243dSDimitry Andric     // Converting from int or calling a rounding function always results in a
6255bdd1243dSDimitry Andric     // finite integral number or infinity. For those inputs, rounding functions
6256bdd1243dSDimitry Andric     // always return the same value, so the (2nd) rounding is eliminated. Ex:
6257bdd1243dSDimitry Andric     // floor (sitofp x) -> sitofp x
6258bdd1243dSDimitry Andric     // round (ceil x) -> ceil x
6259bdd1243dSDimitry Andric     auto *II = dyn_cast<IntrinsicInst>(Op0);
6260bdd1243dSDimitry Andric     if ((II && removesFPFraction(II->getIntrinsicID())) ||
6261bdd1243dSDimitry Andric         match(Op0, m_SIToFP(m_Value())) || match(Op0, m_UIToFP(m_Value())))
6262bdd1243dSDimitry Andric       return Op0;
6263bdd1243dSDimitry Andric   }
6264bdd1243dSDimitry Andric 
62650b57cec5SDimitry Andric   Value *X;
62660b57cec5SDimitry Andric   switch (IID) {
62670b57cec5SDimitry Andric   case Intrinsic::fabs:
6268*0fca6ea1SDimitry Andric     if (computeKnownFPSignBit(Op0, /*Depth=*/0, Q) == false)
626981ad6265SDimitry Andric       return Op0;
62700b57cec5SDimitry Andric     break;
62710b57cec5SDimitry Andric   case Intrinsic::bswap:
62720b57cec5SDimitry Andric     // bswap(bswap(x)) -> x
627381ad6265SDimitry Andric     if (match(Op0, m_BSwap(m_Value(X))))
627481ad6265SDimitry Andric       return X;
62750b57cec5SDimitry Andric     break;
62760b57cec5SDimitry Andric   case Intrinsic::bitreverse:
62770b57cec5SDimitry Andric     // bitreverse(bitreverse(x)) -> x
627881ad6265SDimitry Andric     if (match(Op0, m_BitReverse(m_Value(X))))
627981ad6265SDimitry Andric       return X;
62800b57cec5SDimitry Andric     break;
6281e8d8bef9SDimitry Andric   case Intrinsic::ctpop: {
6282bdd1243dSDimitry Andric     // ctpop(X) -> 1 iff X is non-zero power of 2.
6283bdd1243dSDimitry Andric     if (isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ false, 0, Q.AC, Q.CxtI,
6284bdd1243dSDimitry Andric                                Q.DT))
6285bdd1243dSDimitry Andric       return ConstantInt::get(Op0->getType(), 1);
6286e8d8bef9SDimitry Andric     // If everything but the lowest bit is zero, that bit is the pop-count. Ex:
6287e8d8bef9SDimitry Andric     // ctpop(and X, 1) --> and X, 1
6288e8d8bef9SDimitry Andric     unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
6289e8d8bef9SDimitry Andric     if (MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, BitWidth - 1),
62905f757f3fSDimitry Andric                           Q))
6291e8d8bef9SDimitry Andric       return Op0;
6292e8d8bef9SDimitry Andric     break;
6293e8d8bef9SDimitry Andric   }
62940b57cec5SDimitry Andric   case Intrinsic::exp:
62950b57cec5SDimitry Andric     // exp(log(x)) -> x
62965f757f3fSDimitry Andric     if (Call->hasAllowReassoc() &&
629781ad6265SDimitry Andric         match(Op0, m_Intrinsic<Intrinsic::log>(m_Value(X))))
629881ad6265SDimitry Andric       return X;
62990b57cec5SDimitry Andric     break;
63000b57cec5SDimitry Andric   case Intrinsic::exp2:
63010b57cec5SDimitry Andric     // exp2(log2(x)) -> x
63025f757f3fSDimitry Andric     if (Call->hasAllowReassoc() &&
630381ad6265SDimitry Andric         match(Op0, m_Intrinsic<Intrinsic::log2>(m_Value(X))))
630481ad6265SDimitry Andric       return X;
63050b57cec5SDimitry Andric     break;
63065f757f3fSDimitry Andric   case Intrinsic::exp10:
63075f757f3fSDimitry Andric     // exp10(log10(x)) -> x
63085f757f3fSDimitry Andric     if (Call->hasAllowReassoc() &&
63095f757f3fSDimitry Andric         match(Op0, m_Intrinsic<Intrinsic::log10>(m_Value(X))))
63105f757f3fSDimitry Andric       return X;
63115f757f3fSDimitry Andric     break;
63120b57cec5SDimitry Andric   case Intrinsic::log:
63130b57cec5SDimitry Andric     // log(exp(x)) -> x
63145f757f3fSDimitry Andric     if (Call->hasAllowReassoc() &&
631581ad6265SDimitry Andric         match(Op0, m_Intrinsic<Intrinsic::exp>(m_Value(X))))
631681ad6265SDimitry Andric       return X;
63170b57cec5SDimitry Andric     break;
63180b57cec5SDimitry Andric   case Intrinsic::log2:
63190b57cec5SDimitry Andric     // log2(exp2(x)) -> x
63205f757f3fSDimitry Andric     if (Call->hasAllowReassoc() &&
63210b57cec5SDimitry Andric         (match(Op0, m_Intrinsic<Intrinsic::exp2>(m_Value(X))) ||
632281ad6265SDimitry Andric          match(Op0,
632381ad6265SDimitry Andric                m_Intrinsic<Intrinsic::pow>(m_SpecificFP(2.0), m_Value(X)))))
632481ad6265SDimitry Andric       return X;
63250b57cec5SDimitry Andric     break;
63260b57cec5SDimitry Andric   case Intrinsic::log10:
63270b57cec5SDimitry Andric     // log10(pow(10.0, x)) -> x
63285f757f3fSDimitry Andric     // log10(exp10(x)) -> x
63295f757f3fSDimitry Andric     if (Call->hasAllowReassoc() &&
63305f757f3fSDimitry Andric         (match(Op0, m_Intrinsic<Intrinsic::exp10>(m_Value(X))) ||
63315f757f3fSDimitry Andric          match(Op0,
63325f757f3fSDimitry Andric                m_Intrinsic<Intrinsic::pow>(m_SpecificFP(10.0), m_Value(X)))))
633381ad6265SDimitry Andric       return X;
63340b57cec5SDimitry Andric     break;
6335*0fca6ea1SDimitry Andric   case Intrinsic::vector_reverse:
6336*0fca6ea1SDimitry Andric     // vector.reverse(vector.reverse(x)) -> x
6337bdd1243dSDimitry Andric     if (match(Op0, m_VecReverse(m_Value(X))))
6338fe6060f1SDimitry Andric       return X;
6339*0fca6ea1SDimitry Andric     // vector.reverse(splat(X)) -> splat(X)
6340349cc55cSDimitry Andric     if (isSplatValue(Op0))
6341349cc55cSDimitry Andric       return Op0;
6342fe6060f1SDimitry Andric     break;
634306c3fb27SDimitry Andric   case Intrinsic::frexp: {
634406c3fb27SDimitry Andric     // Frexp is idempotent with the added complication of the struct return.
634506c3fb27SDimitry Andric     if (match(Op0, m_ExtractValue<0>(m_Value(X)))) {
634606c3fb27SDimitry Andric       if (match(X, m_Intrinsic<Intrinsic::frexp>(m_Value())))
634706c3fb27SDimitry Andric         return X;
634806c3fb27SDimitry Andric     }
634906c3fb27SDimitry Andric 
635006c3fb27SDimitry Andric     break;
635106c3fb27SDimitry Andric   }
63520b57cec5SDimitry Andric   default:
63530b57cec5SDimitry Andric     break;
63540b57cec5SDimitry Andric   }
63550b57cec5SDimitry Andric 
63560b57cec5SDimitry Andric   return nullptr;
63570b57cec5SDimitry Andric }
63580b57cec5SDimitry Andric 
6359e8d8bef9SDimitry Andric /// Given a min/max intrinsic, see if it can be removed based on having an
6360e8d8bef9SDimitry Andric /// operand that is another min/max intrinsic with shared operand(s). The caller
6361e8d8bef9SDimitry Andric /// is expected to swap the operand arguments to handle commutation.
6362e8d8bef9SDimitry Andric static Value *foldMinMaxSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1) {
6363e8d8bef9SDimitry Andric   Value *X, *Y;
6364e8d8bef9SDimitry Andric   if (!match(Op0, m_MaxOrMin(m_Value(X), m_Value(Y))))
6365e8d8bef9SDimitry Andric     return nullptr;
6366e8d8bef9SDimitry Andric 
6367e8d8bef9SDimitry Andric   auto *MM0 = dyn_cast<IntrinsicInst>(Op0);
6368e8d8bef9SDimitry Andric   if (!MM0)
6369e8d8bef9SDimitry Andric     return nullptr;
6370e8d8bef9SDimitry Andric   Intrinsic::ID IID0 = MM0->getIntrinsicID();
6371e8d8bef9SDimitry Andric 
6372e8d8bef9SDimitry Andric   if (Op1 == X || Op1 == Y ||
6373e8d8bef9SDimitry Andric       match(Op1, m_c_MaxOrMin(m_Specific(X), m_Specific(Y)))) {
6374e8d8bef9SDimitry Andric     // max (max X, Y), X --> max X, Y
6375e8d8bef9SDimitry Andric     if (IID0 == IID)
6376e8d8bef9SDimitry Andric       return MM0;
6377e8d8bef9SDimitry Andric     // max (min X, Y), X --> X
6378fe6060f1SDimitry Andric     if (IID0 == getInverseMinMaxIntrinsic(IID))
6379e8d8bef9SDimitry Andric       return Op1;
6380e8d8bef9SDimitry Andric   }
6381e8d8bef9SDimitry Andric   return nullptr;
6382e8d8bef9SDimitry Andric }
6383e8d8bef9SDimitry Andric 
638406c3fb27SDimitry Andric /// Given a min/max intrinsic, see if it can be removed based on having an
638506c3fb27SDimitry Andric /// operand that is another min/max intrinsic with shared operand(s). The caller
638606c3fb27SDimitry Andric /// is expected to swap the operand arguments to handle commutation.
638706c3fb27SDimitry Andric static Value *foldMinimumMaximumSharedOp(Intrinsic::ID IID, Value *Op0,
638806c3fb27SDimitry Andric                                          Value *Op1) {
638906c3fb27SDimitry Andric   assert((IID == Intrinsic::maxnum || IID == Intrinsic::minnum ||
639006c3fb27SDimitry Andric           IID == Intrinsic::maximum || IID == Intrinsic::minimum) &&
639106c3fb27SDimitry Andric          "Unsupported intrinsic");
639206c3fb27SDimitry Andric 
639306c3fb27SDimitry Andric   auto *M0 = dyn_cast<IntrinsicInst>(Op0);
639406c3fb27SDimitry Andric   // If Op0 is not the same intrinsic as IID, do not process.
639506c3fb27SDimitry Andric   // This is a difference with integer min/max handling. We do not process the
639606c3fb27SDimitry Andric   // case like max(min(X,Y),min(X,Y)) => min(X,Y). But it can be handled by GVN.
639706c3fb27SDimitry Andric   if (!M0 || M0->getIntrinsicID() != IID)
639806c3fb27SDimitry Andric     return nullptr;
639906c3fb27SDimitry Andric   Value *X0 = M0->getOperand(0);
640006c3fb27SDimitry Andric   Value *Y0 = M0->getOperand(1);
640106c3fb27SDimitry Andric   // Simple case, m(m(X,Y), X) => m(X, Y)
640206c3fb27SDimitry Andric   //              m(m(X,Y), Y) => m(X, Y)
640306c3fb27SDimitry Andric   // For minimum/maximum, X is NaN => m(NaN, Y) == NaN and m(NaN, NaN) == NaN.
640406c3fb27SDimitry Andric   // For minimum/maximum, Y is NaN => m(X, NaN) == NaN  and m(NaN, NaN) == NaN.
640506c3fb27SDimitry Andric   // For minnum/maxnum, X is NaN => m(NaN, Y) == Y and m(Y, Y) == Y.
640606c3fb27SDimitry Andric   // For minnum/maxnum, Y is NaN => m(X, NaN) == X and m(X, NaN) == X.
640706c3fb27SDimitry Andric   if (X0 == Op1 || Y0 == Op1)
640806c3fb27SDimitry Andric     return M0;
640906c3fb27SDimitry Andric 
641006c3fb27SDimitry Andric   auto *M1 = dyn_cast<IntrinsicInst>(Op1);
641106c3fb27SDimitry Andric   if (!M1)
641206c3fb27SDimitry Andric     return nullptr;
641306c3fb27SDimitry Andric   Value *X1 = M1->getOperand(0);
641406c3fb27SDimitry Andric   Value *Y1 = M1->getOperand(1);
641506c3fb27SDimitry Andric   Intrinsic::ID IID1 = M1->getIntrinsicID();
641606c3fb27SDimitry Andric   // we have a case m(m(X,Y),m'(X,Y)) taking into account m' is commutative.
641706c3fb27SDimitry Andric   // if m' is m or inversion of m => m(m(X,Y),m'(X,Y)) == m(X,Y).
641806c3fb27SDimitry Andric   // For minimum/maximum, X is NaN => m(NaN,Y) == m'(NaN, Y) == NaN.
641906c3fb27SDimitry Andric   // For minimum/maximum, Y is NaN => m(X,NaN) == m'(X, NaN) == NaN.
642006c3fb27SDimitry Andric   // For minnum/maxnum, X is NaN => m(NaN,Y) == m'(NaN, Y) == Y.
642106c3fb27SDimitry Andric   // For minnum/maxnum, Y is NaN => m(X,NaN) == m'(X, NaN) == X.
642206c3fb27SDimitry Andric   if ((X0 == X1 && Y0 == Y1) || (X0 == Y1 && Y0 == X1))
642306c3fb27SDimitry Andric     if (IID1 == IID || getInverseMinMaxIntrinsic(IID1) == IID)
642406c3fb27SDimitry Andric       return M0;
642506c3fb27SDimitry Andric 
642606c3fb27SDimitry Andric   return nullptr;
642706c3fb27SDimitry Andric }
642806c3fb27SDimitry Andric 
6429*0fca6ea1SDimitry Andric Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
6430*0fca6ea1SDimitry Andric                                      Value *Op0, Value *Op1,
64315f757f3fSDimitry Andric                                      const SimplifyQuery &Q,
64325f757f3fSDimitry Andric                                      const CallBase *Call) {
6433e8d8bef9SDimitry Andric   unsigned BitWidth = ReturnType->getScalarSizeInBits();
64340b57cec5SDimitry Andric   switch (IID) {
6435e8d8bef9SDimitry Andric   case Intrinsic::abs:
6436e8d8bef9SDimitry Andric     // abs(abs(x)) -> abs(x). We don't need to worry about the nsw arg here.
6437e8d8bef9SDimitry Andric     // It is always ok to pick the earlier abs. We'll just lose nsw if its only
6438e8d8bef9SDimitry Andric     // on the outer abs.
6439e8d8bef9SDimitry Andric     if (match(Op0, m_Intrinsic<Intrinsic::abs>(m_Value(), m_Value())))
6440e8d8bef9SDimitry Andric       return Op0;
6441e8d8bef9SDimitry Andric     break;
6442e8d8bef9SDimitry Andric 
6443fe6060f1SDimitry Andric   case Intrinsic::cttz: {
6444fe6060f1SDimitry Andric     Value *X;
6445fe6060f1SDimitry Andric     if (match(Op0, m_Shl(m_One(), m_Value(X))))
6446fe6060f1SDimitry Andric       return X;
6447fe6060f1SDimitry Andric     break;
6448fe6060f1SDimitry Andric   }
6449fe6060f1SDimitry Andric   case Intrinsic::ctlz: {
6450fe6060f1SDimitry Andric     Value *X;
6451fe6060f1SDimitry Andric     if (match(Op0, m_LShr(m_Negative(), m_Value(X))))
6452fe6060f1SDimitry Andric       return X;
6453fe6060f1SDimitry Andric     if (match(Op0, m_AShr(m_Negative(), m_Value())))
6454fe6060f1SDimitry Andric       return Constant::getNullValue(ReturnType);
6455fe6060f1SDimitry Andric     break;
6456fe6060f1SDimitry Andric   }
64575f757f3fSDimitry Andric   case Intrinsic::ptrmask: {
64585f757f3fSDimitry Andric     if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
64595f757f3fSDimitry Andric       return PoisonValue::get(Op0->getType());
64605f757f3fSDimitry Andric 
64615f757f3fSDimitry Andric     // NOTE: We can't apply this simplifications based on the value of Op1
64625f757f3fSDimitry Andric     // because we need to preserve provenance.
64635f757f3fSDimitry Andric     if (Q.isUndefValue(Op0) || match(Op0, m_Zero()))
64645f757f3fSDimitry Andric       return Constant::getNullValue(Op0->getType());
64655f757f3fSDimitry Andric 
64665f757f3fSDimitry Andric     assert(Op1->getType()->getScalarSizeInBits() ==
64675f757f3fSDimitry Andric                Q.DL.getIndexTypeSizeInBits(Op0->getType()) &&
64685f757f3fSDimitry Andric            "Invalid mask width");
64695f757f3fSDimitry Andric     // If index-width (mask size) is less than pointer-size then mask is
64705f757f3fSDimitry Andric     // 1-extended.
64715f757f3fSDimitry Andric     if (match(Op1, m_PtrToInt(m_Specific(Op0))))
64725f757f3fSDimitry Andric       return Op0;
64735f757f3fSDimitry Andric 
64745f757f3fSDimitry Andric     // NOTE: We may have attributes associated with the return value of the
64755f757f3fSDimitry Andric     // llvm.ptrmask intrinsic that will be lost when we just return the
64765f757f3fSDimitry Andric     // operand. We should try to preserve them.
64775f757f3fSDimitry Andric     if (match(Op1, m_AllOnes()) || Q.isUndefValue(Op1))
64785f757f3fSDimitry Andric       return Op0;
64795f757f3fSDimitry Andric 
64805f757f3fSDimitry Andric     Constant *C;
64815f757f3fSDimitry Andric     if (match(Op1, m_ImmConstant(C))) {
64825f757f3fSDimitry Andric       KnownBits PtrKnown = computeKnownBits(Op0, /*Depth=*/0, Q);
64835f757f3fSDimitry Andric       // See if we only masking off bits we know are already zero due to
64845f757f3fSDimitry Andric       // alignment.
64855f757f3fSDimitry Andric       APInt IrrelevantPtrBits =
64865f757f3fSDimitry Andric           PtrKnown.Zero.zextOrTrunc(C->getType()->getScalarSizeInBits());
64875f757f3fSDimitry Andric       C = ConstantFoldBinaryOpOperands(
64885f757f3fSDimitry Andric           Instruction::Or, C, ConstantInt::get(C->getType(), IrrelevantPtrBits),
64895f757f3fSDimitry Andric           Q.DL);
64905f757f3fSDimitry Andric       if (C != nullptr && C->isAllOnesValue())
64915f757f3fSDimitry Andric         return Op0;
64925f757f3fSDimitry Andric     }
64935f757f3fSDimitry Andric     break;
64945f757f3fSDimitry Andric   }
6495e8d8bef9SDimitry Andric   case Intrinsic::smax:
6496e8d8bef9SDimitry Andric   case Intrinsic::smin:
6497e8d8bef9SDimitry Andric   case Intrinsic::umax:
6498e8d8bef9SDimitry Andric   case Intrinsic::umin: {
6499e8d8bef9SDimitry Andric     // If the arguments are the same, this is a no-op.
6500e8d8bef9SDimitry Andric     if (Op0 == Op1)
6501e8d8bef9SDimitry Andric       return Op0;
6502e8d8bef9SDimitry Andric 
6503bdd1243dSDimitry Andric     // Canonicalize immediate constant operand as Op1.
6504bdd1243dSDimitry Andric     if (match(Op0, m_ImmConstant()))
6505e8d8bef9SDimitry Andric       std::swap(Op0, Op1);
6506e8d8bef9SDimitry Andric 
6507e8d8bef9SDimitry Andric     // Assume undef is the limit value.
6508e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op1))
650904eeddc0SDimitry Andric       return ConstantInt::get(
651004eeddc0SDimitry Andric           ReturnType, MinMaxIntrinsic::getSaturationPoint(IID, BitWidth));
6511e8d8bef9SDimitry Andric 
6512e8d8bef9SDimitry Andric     const APInt *C;
6513*0fca6ea1SDimitry Andric     if (match(Op1, m_APIntAllowPoison(C))) {
6514e8d8bef9SDimitry Andric       // Clamp to limit value. For example:
6515e8d8bef9SDimitry Andric       // umax(i8 %x, i8 255) --> 255
651604eeddc0SDimitry Andric       if (*C == MinMaxIntrinsic::getSaturationPoint(IID, BitWidth))
6517e8d8bef9SDimitry Andric         return ConstantInt::get(ReturnType, *C);
6518e8d8bef9SDimitry Andric 
6519e8d8bef9SDimitry Andric       // If the constant op is the opposite of the limit value, the other must
6520e8d8bef9SDimitry Andric       // be larger/smaller or equal. For example:
6521e8d8bef9SDimitry Andric       // umin(i8 %x, i8 255) --> %x
652204eeddc0SDimitry Andric       if (*C == MinMaxIntrinsic::getSaturationPoint(
652304eeddc0SDimitry Andric                     getInverseMinMaxIntrinsic(IID), BitWidth))
6524e8d8bef9SDimitry Andric         return Op0;
6525e8d8bef9SDimitry Andric 
6526e8d8bef9SDimitry Andric       // Remove nested call if constant operands allow it. Example:
6527e8d8bef9SDimitry Andric       // max (max X, 7), 5 -> max X, 7
6528e8d8bef9SDimitry Andric       auto *MinMax0 = dyn_cast<IntrinsicInst>(Op0);
6529e8d8bef9SDimitry Andric       if (MinMax0 && MinMax0->getIntrinsicID() == IID) {
6530e8d8bef9SDimitry Andric         // TODO: loosen undef/splat restrictions for vector constants.
6531e8d8bef9SDimitry Andric         Value *M00 = MinMax0->getOperand(0), *M01 = MinMax0->getOperand(1);
6532e8d8bef9SDimitry Andric         const APInt *InnerC;
6533e8d8bef9SDimitry Andric         if ((match(M00, m_APInt(InnerC)) || match(M01, m_APInt(InnerC))) &&
653404eeddc0SDimitry Andric             ICmpInst::compare(*InnerC, *C,
653504eeddc0SDimitry Andric                               ICmpInst::getNonStrictPredicate(
653604eeddc0SDimitry Andric                                   MinMaxIntrinsic::getPredicate(IID))))
6537e8d8bef9SDimitry Andric           return Op0;
6538e8d8bef9SDimitry Andric       }
6539e8d8bef9SDimitry Andric     }
6540e8d8bef9SDimitry Andric 
6541e8d8bef9SDimitry Andric     if (Value *V = foldMinMaxSharedOp(IID, Op0, Op1))
6542e8d8bef9SDimitry Andric       return V;
6543e8d8bef9SDimitry Andric     if (Value *V = foldMinMaxSharedOp(IID, Op1, Op0))
6544e8d8bef9SDimitry Andric       return V;
6545e8d8bef9SDimitry Andric 
654604eeddc0SDimitry Andric     ICmpInst::Predicate Pred =
654704eeddc0SDimitry Andric         ICmpInst::getNonStrictPredicate(MinMaxIntrinsic::getPredicate(IID));
6548e8d8bef9SDimitry Andric     if (isICmpTrue(Pred, Op0, Op1, Q.getWithoutUndef(), RecursionLimit))
6549e8d8bef9SDimitry Andric       return Op0;
6550e8d8bef9SDimitry Andric     if (isICmpTrue(Pred, Op1, Op0, Q.getWithoutUndef(), RecursionLimit))
6551e8d8bef9SDimitry Andric       return Op1;
6552e8d8bef9SDimitry Andric 
6553e8d8bef9SDimitry Andric     break;
6554e8d8bef9SDimitry Andric   }
6555*0fca6ea1SDimitry Andric   case Intrinsic::scmp:
6556*0fca6ea1SDimitry Andric   case Intrinsic::ucmp: {
6557*0fca6ea1SDimitry Andric     // Fold to a constant if the relationship between operands can be
6558*0fca6ea1SDimitry Andric     // established with certainty
6559*0fca6ea1SDimitry Andric     if (isICmpTrue(CmpInst::ICMP_EQ, Op0, Op1, Q, RecursionLimit))
6560*0fca6ea1SDimitry Andric       return Constant::getNullValue(ReturnType);
6561*0fca6ea1SDimitry Andric 
6562*0fca6ea1SDimitry Andric     ICmpInst::Predicate PredGT =
6563*0fca6ea1SDimitry Andric         IID == Intrinsic::scmp ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
6564*0fca6ea1SDimitry Andric     if (isICmpTrue(PredGT, Op0, Op1, Q, RecursionLimit))
6565*0fca6ea1SDimitry Andric       return ConstantInt::get(ReturnType, 1);
6566*0fca6ea1SDimitry Andric 
6567*0fca6ea1SDimitry Andric     ICmpInst::Predicate PredLT =
6568*0fca6ea1SDimitry Andric         IID == Intrinsic::scmp ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
6569*0fca6ea1SDimitry Andric     if (isICmpTrue(PredLT, Op0, Op1, Q, RecursionLimit))
6570*0fca6ea1SDimitry Andric       return ConstantInt::getSigned(ReturnType, -1);
6571*0fca6ea1SDimitry Andric 
6572*0fca6ea1SDimitry Andric     break;
6573*0fca6ea1SDimitry Andric   }
65740b57cec5SDimitry Andric   case Intrinsic::usub_with_overflow:
65750b57cec5SDimitry Andric   case Intrinsic::ssub_with_overflow:
65760b57cec5SDimitry Andric     // X - X -> { 0, false }
6577e8d8bef9SDimitry Andric     // X - undef -> { 0, false }
6578e8d8bef9SDimitry Andric     // undef - X -> { 0, false }
6579e8d8bef9SDimitry Andric     if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
65800b57cec5SDimitry Andric       return Constant::getNullValue(ReturnType);
6581e8d8bef9SDimitry Andric     break;
65820b57cec5SDimitry Andric   case Intrinsic::uadd_with_overflow:
65830b57cec5SDimitry Andric   case Intrinsic::sadd_with_overflow:
6584e8d8bef9SDimitry Andric     // X + undef -> { -1, false }
6585e8d8bef9SDimitry Andric     // undef + x -> { -1, false }
6586e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1)) {
65870b57cec5SDimitry Andric       return ConstantStruct::get(
65880b57cec5SDimitry Andric           cast<StructType>(ReturnType),
6589e8d8bef9SDimitry Andric           {Constant::getAllOnesValue(ReturnType->getStructElementType(0)),
65900b57cec5SDimitry Andric            Constant::getNullValue(ReturnType->getStructElementType(1))});
65910b57cec5SDimitry Andric     }
65920b57cec5SDimitry Andric     break;
65930b57cec5SDimitry Andric   case Intrinsic::umul_with_overflow:
65940b57cec5SDimitry Andric   case Intrinsic::smul_with_overflow:
65950b57cec5SDimitry Andric     // 0 * X -> { 0, false }
65960b57cec5SDimitry Andric     // X * 0 -> { 0, false }
65970b57cec5SDimitry Andric     if (match(Op0, m_Zero()) || match(Op1, m_Zero()))
65980b57cec5SDimitry Andric       return Constant::getNullValue(ReturnType);
65990b57cec5SDimitry Andric     // undef * X -> { 0, false }
66000b57cec5SDimitry Andric     // X * undef -> { 0, false }
6601e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
66020b57cec5SDimitry Andric       return Constant::getNullValue(ReturnType);
66030b57cec5SDimitry Andric     break;
66040b57cec5SDimitry Andric   case Intrinsic::uadd_sat:
66050b57cec5SDimitry Andric     // sat(MAX + X) -> MAX
66060b57cec5SDimitry Andric     // sat(X + MAX) -> MAX
66070b57cec5SDimitry Andric     if (match(Op0, m_AllOnes()) || match(Op1, m_AllOnes()))
66080b57cec5SDimitry Andric       return Constant::getAllOnesValue(ReturnType);
6609bdd1243dSDimitry Andric     [[fallthrough]];
66100b57cec5SDimitry Andric   case Intrinsic::sadd_sat:
66110b57cec5SDimitry Andric     // sat(X + undef) -> -1
66120b57cec5SDimitry Andric     // sat(undef + X) -> -1
66130b57cec5SDimitry Andric     // For unsigned: Assume undef is MAX, thus we saturate to MAX (-1).
66140b57cec5SDimitry Andric     // For signed: Assume undef is ~X, in which case X + ~X = -1.
6615e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
66160b57cec5SDimitry Andric       return Constant::getAllOnesValue(ReturnType);
66170b57cec5SDimitry Andric 
66180b57cec5SDimitry Andric     // X + 0 -> X
66190b57cec5SDimitry Andric     if (match(Op1, m_Zero()))
66200b57cec5SDimitry Andric       return Op0;
66210b57cec5SDimitry Andric     // 0 + X -> X
66220b57cec5SDimitry Andric     if (match(Op0, m_Zero()))
66230b57cec5SDimitry Andric       return Op1;
66240b57cec5SDimitry Andric     break;
66250b57cec5SDimitry Andric   case Intrinsic::usub_sat:
66260b57cec5SDimitry Andric     // sat(0 - X) -> 0, sat(X - MAX) -> 0
66270b57cec5SDimitry Andric     if (match(Op0, m_Zero()) || match(Op1, m_AllOnes()))
66280b57cec5SDimitry Andric       return Constant::getNullValue(ReturnType);
6629bdd1243dSDimitry Andric     [[fallthrough]];
66300b57cec5SDimitry Andric   case Intrinsic::ssub_sat:
66310b57cec5SDimitry Andric     // X - X -> 0, X - undef -> 0, undef - X -> 0
6632e8d8bef9SDimitry Andric     if (Op0 == Op1 || Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
66330b57cec5SDimitry Andric       return Constant::getNullValue(ReturnType);
66340b57cec5SDimitry Andric     // X - 0 -> X
66350b57cec5SDimitry Andric     if (match(Op1, m_Zero()))
66360b57cec5SDimitry Andric       return Op0;
66370b57cec5SDimitry Andric     break;
66380b57cec5SDimitry Andric   case Intrinsic::load_relative:
66390b57cec5SDimitry Andric     if (auto *C0 = dyn_cast<Constant>(Op0))
66400b57cec5SDimitry Andric       if (auto *C1 = dyn_cast<Constant>(Op1))
664181ad6265SDimitry Andric         return simplifyRelativeLoad(C0, C1, Q.DL);
66420b57cec5SDimitry Andric     break;
66430b57cec5SDimitry Andric   case Intrinsic::powi:
66440b57cec5SDimitry Andric     if (auto *Power = dyn_cast<ConstantInt>(Op1)) {
66450b57cec5SDimitry Andric       // powi(x, 0) -> 1.0
66460b57cec5SDimitry Andric       if (Power->isZero())
66470b57cec5SDimitry Andric         return ConstantFP::get(Op0->getType(), 1.0);
66480b57cec5SDimitry Andric       // powi(x, 1) -> x
66490b57cec5SDimitry Andric       if (Power->isOne())
66500b57cec5SDimitry Andric         return Op0;
66510b57cec5SDimitry Andric     }
66520b57cec5SDimitry Andric     break;
66535f757f3fSDimitry Andric   case Intrinsic::ldexp:
66545f757f3fSDimitry Andric     return simplifyLdexp(Op0, Op1, Q, false);
6655480093f4SDimitry Andric   case Intrinsic::copysign:
6656480093f4SDimitry Andric     // copysign X, X --> X
6657480093f4SDimitry Andric     if (Op0 == Op1)
6658480093f4SDimitry Andric       return Op0;
6659480093f4SDimitry Andric     // copysign -X, X --> X
6660480093f4SDimitry Andric     // copysign X, -X --> -X
6661480093f4SDimitry Andric     if (match(Op0, m_FNeg(m_Specific(Op1))) ||
6662480093f4SDimitry Andric         match(Op1, m_FNeg(m_Specific(Op0))))
6663480093f4SDimitry Andric       return Op1;
6664480093f4SDimitry Andric     break;
6665bdd1243dSDimitry Andric   case Intrinsic::is_fpclass: {
6666bdd1243dSDimitry Andric     if (isa<PoisonValue>(Op0))
6667bdd1243dSDimitry Andric       return PoisonValue::get(ReturnType);
6668bdd1243dSDimitry Andric 
6669bdd1243dSDimitry Andric     uint64_t Mask = cast<ConstantInt>(Op1)->getZExtValue();
6670bdd1243dSDimitry Andric     // If all tests are made, it doesn't matter what the value is.
6671bdd1243dSDimitry Andric     if ((Mask & fcAllFlags) == fcAllFlags)
6672bdd1243dSDimitry Andric       return ConstantInt::get(ReturnType, true);
6673bdd1243dSDimitry Andric     if ((Mask & fcAllFlags) == 0)
6674bdd1243dSDimitry Andric       return ConstantInt::get(ReturnType, false);
6675bdd1243dSDimitry Andric     if (Q.isUndefValue(Op0))
6676bdd1243dSDimitry Andric       return UndefValue::get(ReturnType);
6677bdd1243dSDimitry Andric     break;
6678bdd1243dSDimitry Andric   }
66790b57cec5SDimitry Andric   case Intrinsic::maxnum:
66800b57cec5SDimitry Andric   case Intrinsic::minnum:
66810b57cec5SDimitry Andric   case Intrinsic::maximum:
66820b57cec5SDimitry Andric   case Intrinsic::minimum: {
66830b57cec5SDimitry Andric     // If the arguments are the same, this is a no-op.
668481ad6265SDimitry Andric     if (Op0 == Op1)
668581ad6265SDimitry Andric       return Op0;
66860b57cec5SDimitry Andric 
6687e8d8bef9SDimitry Andric     // Canonicalize constant operand as Op1.
6688e8d8bef9SDimitry Andric     if (isa<Constant>(Op0))
6689e8d8bef9SDimitry Andric       std::swap(Op0, Op1);
6690e8d8bef9SDimitry Andric 
6691e8d8bef9SDimitry Andric     // If an argument is undef, return the other argument.
6692e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op1))
66930b57cec5SDimitry Andric       return Op0;
66940b57cec5SDimitry Andric 
66950b57cec5SDimitry Andric     bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
6696e8d8bef9SDimitry Andric     bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
6697e8d8bef9SDimitry Andric 
6698e8d8bef9SDimitry Andric     // minnum(X, nan) -> X
6699e8d8bef9SDimitry Andric     // maxnum(X, nan) -> X
6700e8d8bef9SDimitry Andric     // minimum(X, nan) -> nan
6701e8d8bef9SDimitry Andric     // maximum(X, nan) -> nan
67020b57cec5SDimitry Andric     if (match(Op1, m_NaN()))
6703e8d8bef9SDimitry Andric       return PropagateNaN ? propagateNaN(cast<Constant>(Op1)) : Op0;
6704e8d8bef9SDimitry Andric 
6705e8d8bef9SDimitry Andric     // In the following folds, inf can be replaced with the largest finite
6706e8d8bef9SDimitry Andric     // float, if the ninf flag is set.
6707e8d8bef9SDimitry Andric     const APFloat *C;
6708e8d8bef9SDimitry Andric     if (match(Op1, m_APFloat(C)) &&
6709*0fca6ea1SDimitry Andric         (C->isInfinity() || (Call && Call->hasNoInfs() && C->isLargest()))) {
6710e8d8bef9SDimitry Andric       // minnum(X, -inf) -> -inf
6711e8d8bef9SDimitry Andric       // maxnum(X, +inf) -> +inf
6712e8d8bef9SDimitry Andric       // minimum(X, -inf) -> -inf if nnan
6713e8d8bef9SDimitry Andric       // maximum(X, +inf) -> +inf if nnan
6714*0fca6ea1SDimitry Andric       if (C->isNegative() == IsMin &&
6715*0fca6ea1SDimitry Andric           (!PropagateNaN || (Call && Call->hasNoNaNs())))
6716e8d8bef9SDimitry Andric         return ConstantFP::get(ReturnType, *C);
6717e8d8bef9SDimitry Andric 
6718e8d8bef9SDimitry Andric       // minnum(X, +inf) -> X if nnan
6719e8d8bef9SDimitry Andric       // maxnum(X, -inf) -> X if nnan
6720e8d8bef9SDimitry Andric       // minimum(X, +inf) -> X
6721e8d8bef9SDimitry Andric       // maximum(X, -inf) -> X
6722*0fca6ea1SDimitry Andric       if (C->isNegative() != IsMin &&
6723*0fca6ea1SDimitry Andric           (PropagateNaN || (Call && Call->hasNoNaNs())))
6724e8d8bef9SDimitry Andric         return Op0;
6725e8d8bef9SDimitry Andric     }
67260b57cec5SDimitry Andric 
67270b57cec5SDimitry Andric     // Min/max of the same operation with common operand:
67280b57cec5SDimitry Andric     // m(m(X, Y)), X --> m(X, Y) (4 commuted variants)
672906c3fb27SDimitry Andric     if (Value *V = foldMinimumMaximumSharedOp(IID, Op0, Op1))
673006c3fb27SDimitry Andric       return V;
673106c3fb27SDimitry Andric     if (Value *V = foldMinimumMaximumSharedOp(IID, Op1, Op0))
673206c3fb27SDimitry Andric       return V;
67330b57cec5SDimitry Andric 
67340b57cec5SDimitry Andric     break;
67350b57cec5SDimitry Andric   }
673681ad6265SDimitry Andric   case Intrinsic::vector_extract: {
6737fe6060f1SDimitry Andric     // (extract_vector (insert_vector _, X, 0), 0) -> X
6738fe6060f1SDimitry Andric     unsigned IdxN = cast<ConstantInt>(Op1)->getZExtValue();
6739fe6060f1SDimitry Andric     Value *X = nullptr;
674081ad6265SDimitry Andric     if (match(Op0, m_Intrinsic<Intrinsic::vector_insert>(m_Value(), m_Value(X),
674181ad6265SDimitry Andric                                                          m_Zero())) &&
6742fe6060f1SDimitry Andric         IdxN == 0 && X->getType() == ReturnType)
6743fe6060f1SDimitry Andric       return X;
6744fe6060f1SDimitry Andric 
6745fe6060f1SDimitry Andric     break;
6746fe6060f1SDimitry Andric   }
67470b57cec5SDimitry Andric   default:
67480b57cec5SDimitry Andric     break;
67490b57cec5SDimitry Andric   }
67500b57cec5SDimitry Andric 
67510b57cec5SDimitry Andric   return nullptr;
67520b57cec5SDimitry Andric }
67530b57cec5SDimitry Andric 
675406c3fb27SDimitry Andric static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
675506c3fb27SDimitry Andric                                 ArrayRef<Value *> Args,
675606c3fb27SDimitry Andric                                 const SimplifyQuery &Q) {
675706c3fb27SDimitry Andric   // Operand bundles should not be in Args.
675806c3fb27SDimitry Andric   assert(Call->arg_size() == Args.size());
675906c3fb27SDimitry Andric   unsigned NumOperands = Args.size();
676006c3fb27SDimitry Andric   Function *F = cast<Function>(Callee);
67610b57cec5SDimitry Andric   Intrinsic::ID IID = F->getIntrinsicID();
6762349cc55cSDimitry Andric 
6763349cc55cSDimitry Andric   // Most of the intrinsics with no operands have some kind of side effect.
6764349cc55cSDimitry Andric   // Don't simplify.
6765349cc55cSDimitry Andric   if (!NumOperands) {
6766349cc55cSDimitry Andric     switch (IID) {
6767349cc55cSDimitry Andric     case Intrinsic::vscale: {
67685f757f3fSDimitry Andric       Type *RetTy = F->getReturnType();
67695f757f3fSDimitry Andric       ConstantRange CR = getVScaleRange(Call->getFunction(), 64);
67705f757f3fSDimitry Andric       if (const APInt *C = CR.getSingleElement())
67715f757f3fSDimitry Andric         return ConstantInt::get(RetTy, C->getZExtValue());
6772349cc55cSDimitry Andric       return nullptr;
6773349cc55cSDimitry Andric     }
6774349cc55cSDimitry Andric     default:
6775349cc55cSDimitry Andric       return nullptr;
6776349cc55cSDimitry Andric     }
6777349cc55cSDimitry Andric   }
6778349cc55cSDimitry Andric 
67790b57cec5SDimitry Andric   if (NumOperands == 1)
67805f757f3fSDimitry Andric     return simplifyUnaryIntrinsic(F, Args[0], Q, Call);
67810b57cec5SDimitry Andric 
67820b57cec5SDimitry Andric   if (NumOperands == 2)
6783*0fca6ea1SDimitry Andric     return simplifyBinaryIntrinsic(IID, F->getReturnType(), Args[0], Args[1], Q,
6784*0fca6ea1SDimitry Andric                                    Call);
67850b57cec5SDimitry Andric 
67860b57cec5SDimitry Andric   // Handle intrinsics with 3 or more arguments.
67870b57cec5SDimitry Andric   switch (IID) {
67880b57cec5SDimitry Andric   case Intrinsic::masked_load:
67890b57cec5SDimitry Andric   case Intrinsic::masked_gather: {
679006c3fb27SDimitry Andric     Value *MaskArg = Args[2];
679106c3fb27SDimitry Andric     Value *PassthruArg = Args[3];
67920b57cec5SDimitry Andric     // If the mask is all zeros or undef, the "passthru" argument is the result.
67930b57cec5SDimitry Andric     if (maskIsAllZeroOrUndef(MaskArg))
67940b57cec5SDimitry Andric       return PassthruArg;
67950b57cec5SDimitry Andric     return nullptr;
67960b57cec5SDimitry Andric   }
67970b57cec5SDimitry Andric   case Intrinsic::fshl:
67980b57cec5SDimitry Andric   case Intrinsic::fshr: {
679906c3fb27SDimitry Andric     Value *Op0 = Args[0], *Op1 = Args[1], *ShAmtArg = Args[2];
68000b57cec5SDimitry Andric 
68010b57cec5SDimitry Andric     // If both operands are undef, the result is undef.
6802e8d8bef9SDimitry Andric     if (Q.isUndefValue(Op0) && Q.isUndefValue(Op1))
68030b57cec5SDimitry Andric       return UndefValue::get(F->getReturnType());
68040b57cec5SDimitry Andric 
68050b57cec5SDimitry Andric     // If shift amount is undef, assume it is zero.
6806e8d8bef9SDimitry Andric     if (Q.isUndefValue(ShAmtArg))
680706c3fb27SDimitry Andric       return Args[IID == Intrinsic::fshl ? 0 : 1];
68080b57cec5SDimitry Andric 
68090b57cec5SDimitry Andric     const APInt *ShAmtC;
68100b57cec5SDimitry Andric     if (match(ShAmtArg, m_APInt(ShAmtC))) {
68110b57cec5SDimitry Andric       // If there's effectively no shift, return the 1st arg or 2nd arg.
68120b57cec5SDimitry Andric       APInt BitWidth = APInt(ShAmtC->getBitWidth(), ShAmtC->getBitWidth());
6813349cc55cSDimitry Andric       if (ShAmtC->urem(BitWidth).isZero())
681406c3fb27SDimitry Andric         return Args[IID == Intrinsic::fshl ? 0 : 1];
68150b57cec5SDimitry Andric     }
6816349cc55cSDimitry Andric 
6817349cc55cSDimitry Andric     // Rotating zero by anything is zero.
6818349cc55cSDimitry Andric     if (match(Op0, m_Zero()) && match(Op1, m_Zero()))
6819349cc55cSDimitry Andric       return ConstantInt::getNullValue(F->getReturnType());
6820349cc55cSDimitry Andric 
6821349cc55cSDimitry Andric     // Rotating -1 by anything is -1.
6822349cc55cSDimitry Andric     if (match(Op0, m_AllOnes()) && match(Op1, m_AllOnes()))
6823349cc55cSDimitry Andric       return ConstantInt::getAllOnesValue(F->getReturnType());
6824349cc55cSDimitry Andric 
68250b57cec5SDimitry Andric     return nullptr;
68260b57cec5SDimitry Andric   }
6827fe6060f1SDimitry Andric   case Intrinsic::experimental_constrained_fma: {
6828fe6060f1SDimitry Andric     auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
682906c3fb27SDimitry Andric     if (Value *V = simplifyFPOp(Args, {}, Q, *FPI->getExceptionBehavior(),
6830bdd1243dSDimitry Andric                                 *FPI->getRoundingMode()))
6831fe6060f1SDimitry Andric       return V;
6832fe6060f1SDimitry Andric     return nullptr;
6833fe6060f1SDimitry Andric   }
68348bcb0991SDimitry Andric   case Intrinsic::fma:
68358bcb0991SDimitry Andric   case Intrinsic::fmuladd: {
683606c3fb27SDimitry Andric     if (Value *V = simplifyFPOp(Args, {}, Q, fp::ebIgnore,
6837fe6060f1SDimitry Andric                                 RoundingMode::NearestTiesToEven))
68388bcb0991SDimitry Andric       return V;
68398bcb0991SDimitry Andric     return nullptr;
68408bcb0991SDimitry Andric   }
6841fe6060f1SDimitry Andric   case Intrinsic::smul_fix:
6842fe6060f1SDimitry Andric   case Intrinsic::smul_fix_sat: {
684306c3fb27SDimitry Andric     Value *Op0 = Args[0];
684406c3fb27SDimitry Andric     Value *Op1 = Args[1];
684506c3fb27SDimitry Andric     Value *Op2 = Args[2];
6846fe6060f1SDimitry Andric     Type *ReturnType = F->getReturnType();
6847fe6060f1SDimitry Andric 
6848fe6060f1SDimitry Andric     // Canonicalize constant operand as Op1 (ConstantFolding handles the case
6849fe6060f1SDimitry Andric     // when both Op0 and Op1 are constant so we do not care about that special
6850fe6060f1SDimitry Andric     // case here).
6851fe6060f1SDimitry Andric     if (isa<Constant>(Op0))
6852fe6060f1SDimitry Andric       std::swap(Op0, Op1);
6853fe6060f1SDimitry Andric 
6854fe6060f1SDimitry Andric     // X * 0 -> 0
6855fe6060f1SDimitry Andric     if (match(Op1, m_Zero()))
6856fe6060f1SDimitry Andric       return Constant::getNullValue(ReturnType);
6857fe6060f1SDimitry Andric 
6858fe6060f1SDimitry Andric     // X * undef -> 0
6859fe6060f1SDimitry Andric     if (Q.isUndefValue(Op1))
6860fe6060f1SDimitry Andric       return Constant::getNullValue(ReturnType);
6861fe6060f1SDimitry Andric 
6862fe6060f1SDimitry Andric     // X * (1 << Scale) -> X
6863fe6060f1SDimitry Andric     APInt ScaledOne =
6864fe6060f1SDimitry Andric         APInt::getOneBitSet(ReturnType->getScalarSizeInBits(),
6865fe6060f1SDimitry Andric                             cast<ConstantInt>(Op2)->getZExtValue());
6866fe6060f1SDimitry Andric     if (ScaledOne.isNonNegative() && match(Op1, m_SpecificInt(ScaledOne)))
6867fe6060f1SDimitry Andric       return Op0;
6868fe6060f1SDimitry Andric 
6869fe6060f1SDimitry Andric     return nullptr;
6870fe6060f1SDimitry Andric   }
687181ad6265SDimitry Andric   case Intrinsic::vector_insert: {
687206c3fb27SDimitry Andric     Value *Vec = Args[0];
687306c3fb27SDimitry Andric     Value *SubVec = Args[1];
687406c3fb27SDimitry Andric     Value *Idx = Args[2];
6875fe6060f1SDimitry Andric     Type *ReturnType = F->getReturnType();
6876fe6060f1SDimitry Andric 
6877fe6060f1SDimitry Andric     // (insert_vector Y, (extract_vector X, 0), 0) -> X
6878fe6060f1SDimitry Andric     // where: Y is X, or Y is undef
6879fe6060f1SDimitry Andric     unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();
6880fe6060f1SDimitry Andric     Value *X = nullptr;
688181ad6265SDimitry Andric     if (match(SubVec,
688281ad6265SDimitry Andric               m_Intrinsic<Intrinsic::vector_extract>(m_Value(X), m_Zero())) &&
6883fe6060f1SDimitry Andric         (Q.isUndefValue(Vec) || Vec == X) && IdxN == 0 &&
6884fe6060f1SDimitry Andric         X->getType() == ReturnType)
6885fe6060f1SDimitry Andric       return X;
6886fe6060f1SDimitry Andric 
6887fe6060f1SDimitry Andric     return nullptr;
6888fe6060f1SDimitry Andric   }
6889fe6060f1SDimitry Andric   case Intrinsic::experimental_constrained_fadd: {
6890fe6060f1SDimitry Andric     auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
689106c3fb27SDimitry Andric     return simplifyFAddInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
689206c3fb27SDimitry Andric                             *FPI->getExceptionBehavior(),
689306c3fb27SDimitry Andric                             *FPI->getRoundingMode());
6894fe6060f1SDimitry Andric   }
6895fe6060f1SDimitry Andric   case Intrinsic::experimental_constrained_fsub: {
6896fe6060f1SDimitry Andric     auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
689706c3fb27SDimitry Andric     return simplifyFSubInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
689806c3fb27SDimitry Andric                             *FPI->getExceptionBehavior(),
689906c3fb27SDimitry Andric                             *FPI->getRoundingMode());
6900fe6060f1SDimitry Andric   }
6901fe6060f1SDimitry Andric   case Intrinsic::experimental_constrained_fmul: {
6902fe6060f1SDimitry Andric     auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
690306c3fb27SDimitry Andric     return simplifyFMulInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
690406c3fb27SDimitry Andric                             *FPI->getExceptionBehavior(),
690506c3fb27SDimitry Andric                             *FPI->getRoundingMode());
6906fe6060f1SDimitry Andric   }
6907fe6060f1SDimitry Andric   case Intrinsic::experimental_constrained_fdiv: {
6908fe6060f1SDimitry Andric     auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
690906c3fb27SDimitry Andric     return simplifyFDivInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
691006c3fb27SDimitry Andric                             *FPI->getExceptionBehavior(),
691106c3fb27SDimitry Andric                             *FPI->getRoundingMode());
6912fe6060f1SDimitry Andric   }
6913fe6060f1SDimitry Andric   case Intrinsic::experimental_constrained_frem: {
6914fe6060f1SDimitry Andric     auto *FPI = cast<ConstrainedFPIntrinsic>(Call);
691506c3fb27SDimitry Andric     return simplifyFRemInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,
691606c3fb27SDimitry Andric                             *FPI->getExceptionBehavior(),
691706c3fb27SDimitry Andric                             *FPI->getRoundingMode());
6918fe6060f1SDimitry Andric   }
69195f757f3fSDimitry Andric   case Intrinsic::experimental_constrained_ldexp:
69205f757f3fSDimitry Andric     return simplifyLdexp(Args[0], Args[1], Q, true);
6921*0fca6ea1SDimitry Andric   case Intrinsic::experimental_gc_relocate: {
6922*0fca6ea1SDimitry Andric     GCRelocateInst &GCR = *cast<GCRelocateInst>(Call);
6923*0fca6ea1SDimitry Andric     Value *DerivedPtr = GCR.getDerivedPtr();
6924*0fca6ea1SDimitry Andric     Value *BasePtr = GCR.getBasePtr();
6925*0fca6ea1SDimitry Andric 
6926*0fca6ea1SDimitry Andric     // Undef is undef, even after relocation.
6927*0fca6ea1SDimitry Andric     if (isa<UndefValue>(DerivedPtr) || isa<UndefValue>(BasePtr)) {
6928*0fca6ea1SDimitry Andric       return UndefValue::get(GCR.getType());
6929*0fca6ea1SDimitry Andric     }
6930*0fca6ea1SDimitry Andric 
6931*0fca6ea1SDimitry Andric     if (auto *PT = dyn_cast<PointerType>(GCR.getType())) {
6932*0fca6ea1SDimitry Andric       // For now, the assumption is that the relocation of null will be null
6933*0fca6ea1SDimitry Andric       // for most any collector. If this ever changes, a corresponding hook
6934*0fca6ea1SDimitry Andric       // should be added to GCStrategy and this code should check it first.
6935*0fca6ea1SDimitry Andric       if (isa<ConstantPointerNull>(DerivedPtr)) {
6936*0fca6ea1SDimitry Andric         // Use null-pointer of gc_relocate's type to replace it.
6937*0fca6ea1SDimitry Andric         return ConstantPointerNull::get(PT);
6938*0fca6ea1SDimitry Andric       }
6939*0fca6ea1SDimitry Andric     }
6940*0fca6ea1SDimitry Andric     return nullptr;
6941*0fca6ea1SDimitry Andric   }
69420b57cec5SDimitry Andric   default:
69430b57cec5SDimitry Andric     return nullptr;
69440b57cec5SDimitry Andric   }
69450b57cec5SDimitry Andric }
69460b57cec5SDimitry Andric 
694706c3fb27SDimitry Andric static Value *tryConstantFoldCall(CallBase *Call, Value *Callee,
694806c3fb27SDimitry Andric                                   ArrayRef<Value *> Args,
694906c3fb27SDimitry Andric                                   const SimplifyQuery &Q) {
695006c3fb27SDimitry Andric   auto *F = dyn_cast<Function>(Callee);
6951e8d8bef9SDimitry Andric   if (!F || !canConstantFoldCallTo(Call, F))
69520b57cec5SDimitry Andric     return nullptr;
69530b57cec5SDimitry Andric 
69540b57cec5SDimitry Andric   SmallVector<Constant *, 4> ConstantArgs;
695506c3fb27SDimitry Andric   ConstantArgs.reserve(Args.size());
695606c3fb27SDimitry Andric   for (Value *Arg : Args) {
695706c3fb27SDimitry Andric     Constant *C = dyn_cast<Constant>(Arg);
69585ffd83dbSDimitry Andric     if (!C) {
695906c3fb27SDimitry Andric       if (isa<MetadataAsValue>(Arg))
69605ffd83dbSDimitry Andric         continue;
69610b57cec5SDimitry Andric       return nullptr;
69625ffd83dbSDimitry Andric     }
69630b57cec5SDimitry Andric     ConstantArgs.push_back(C);
69640b57cec5SDimitry Andric   }
69650b57cec5SDimitry Andric 
69660b57cec5SDimitry Andric   return ConstantFoldCall(Call, F, ConstantArgs, Q.TLI);
69670b57cec5SDimitry Andric }
69680b57cec5SDimitry Andric 
696906c3fb27SDimitry Andric Value *llvm::simplifyCall(CallBase *Call, Value *Callee, ArrayRef<Value *> Args,
697006c3fb27SDimitry Andric                           const SimplifyQuery &Q) {
697106c3fb27SDimitry Andric   // Args should not contain operand bundle operands.
697206c3fb27SDimitry Andric   assert(Call->arg_size() == Args.size());
697306c3fb27SDimitry Andric 
6974e8d8bef9SDimitry Andric   // musttail calls can only be simplified if they are also DCEd.
6975e8d8bef9SDimitry Andric   // As we can't guarantee this here, don't simplify them.
6976e8d8bef9SDimitry Andric   if (Call->isMustTailCall())
6977e8d8bef9SDimitry Andric     return nullptr;
6978e8d8bef9SDimitry Andric 
6979e8d8bef9SDimitry Andric   // call undef -> poison
6980e8d8bef9SDimitry Andric   // call null -> poison
6981e8d8bef9SDimitry Andric   if (isa<UndefValue>(Callee) || isa<ConstantPointerNull>(Callee))
6982e8d8bef9SDimitry Andric     return PoisonValue::get(Call->getType());
6983e8d8bef9SDimitry Andric 
698406c3fb27SDimitry Andric   if (Value *V = tryConstantFoldCall(Call, Callee, Args, Q))
6985e8d8bef9SDimitry Andric     return V;
6986e8d8bef9SDimitry Andric 
6987e8d8bef9SDimitry Andric   auto *F = dyn_cast<Function>(Callee);
6988e8d8bef9SDimitry Andric   if (F && F->isIntrinsic())
698906c3fb27SDimitry Andric     if (Value *Ret = simplifyIntrinsic(Call, Callee, Args, Q))
6990e8d8bef9SDimitry Andric       return Ret;
6991e8d8bef9SDimitry Andric 
6992e8d8bef9SDimitry Andric   return nullptr;
6993e8d8bef9SDimitry Andric }
6994e8d8bef9SDimitry Andric 
699581ad6265SDimitry Andric Value *llvm::simplifyConstrainedFPCall(CallBase *Call, const SimplifyQuery &Q) {
699681ad6265SDimitry Andric   assert(isa<ConstrainedFPIntrinsic>(Call));
699706c3fb27SDimitry Andric   SmallVector<Value *, 4> Args(Call->args());
699806c3fb27SDimitry Andric   if (Value *V = tryConstantFoldCall(Call, Call->getCalledOperand(), Args, Q))
699981ad6265SDimitry Andric     return V;
700006c3fb27SDimitry Andric   if (Value *Ret = simplifyIntrinsic(Call, Call->getCalledOperand(), Args, Q))
700181ad6265SDimitry Andric     return Ret;
700281ad6265SDimitry Andric   return nullptr;
700381ad6265SDimitry Andric }
700481ad6265SDimitry Andric 
7005480093f4SDimitry Andric /// Given operands for a Freeze, see if we can fold the result.
700681ad6265SDimitry Andric static Value *simplifyFreezeInst(Value *Op0, const SimplifyQuery &Q) {
7007480093f4SDimitry Andric   // Use a utility function defined in ValueTracking.
7008e8d8bef9SDimitry Andric   if (llvm::isGuaranteedNotToBeUndefOrPoison(Op0, Q.AC, Q.CxtI, Q.DT))
7009480093f4SDimitry Andric     return Op0;
7010480093f4SDimitry Andric   // We have room for improvement.
7011480093f4SDimitry Andric   return nullptr;
7012480093f4SDimitry Andric }
7013480093f4SDimitry Andric 
701481ad6265SDimitry Andric Value *llvm::simplifyFreezeInst(Value *Op0, const SimplifyQuery &Q) {
701581ad6265SDimitry Andric   return ::simplifyFreezeInst(Op0, Q);
7016480093f4SDimitry Andric }
7017480093f4SDimitry Andric 
701806c3fb27SDimitry Andric Value *llvm::simplifyLoadInst(LoadInst *LI, Value *PtrOp,
7019fe6060f1SDimitry Andric                               const SimplifyQuery &Q) {
7020fe6060f1SDimitry Andric   if (LI->isVolatile())
7021fe6060f1SDimitry Andric     return nullptr;
7022fe6060f1SDimitry Andric 
702306c3fb27SDimitry Andric   if (auto *PtrOpC = dyn_cast<Constant>(PtrOp))
702406c3fb27SDimitry Andric     return ConstantFoldLoadFromConstPtr(PtrOpC, LI->getType(), Q.DL);
702506c3fb27SDimitry Andric 
702606c3fb27SDimitry Andric   // We can only fold the load if it is from a constant global with definitive
702706c3fb27SDimitry Andric   // initializer. Skip expensive logic if this is not the case.
702806c3fb27SDimitry Andric   auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(PtrOp));
702906c3fb27SDimitry Andric   if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
703006c3fb27SDimitry Andric     return nullptr;
703106c3fb27SDimitry Andric 
703206c3fb27SDimitry Andric   // If GlobalVariable's initializer is uniform, then return the constant
703306c3fb27SDimitry Andric   // regardless of its offset.
7034*0fca6ea1SDimitry Andric   if (Constant *C = ConstantFoldLoadFromUniformValue(GV->getInitializer(),
7035*0fca6ea1SDimitry Andric                                                      LI->getType(), Q.DL))
703606c3fb27SDimitry Andric     return C;
703706c3fb27SDimitry Andric 
7038349cc55cSDimitry Andric   // Try to convert operand into a constant by stripping offsets while looking
703906c3fb27SDimitry Andric   // through invariant.group intrinsics.
704006c3fb27SDimitry Andric   APInt Offset(Q.DL.getIndexTypeSizeInBits(PtrOp->getType()), 0);
7041349cc55cSDimitry Andric   PtrOp = PtrOp->stripAndAccumulateConstantOffsets(
7042349cc55cSDimitry Andric       Q.DL, Offset, /* AllowNonInbounts */ true,
7043349cc55cSDimitry Andric       /* AllowInvariantGroup */ true);
704406c3fb27SDimitry Andric   if (PtrOp == GV) {
7045349cc55cSDimitry Andric     // Index size may have changed due to address space casts.
7046349cc55cSDimitry Andric     Offset = Offset.sextOrTrunc(Q.DL.getIndexTypeSizeInBits(PtrOp->getType()));
7047*0fca6ea1SDimitry Andric     return ConstantFoldLoadFromConstPtr(GV, LI->getType(), std::move(Offset),
7048*0fca6ea1SDimitry Andric                                         Q.DL);
7049349cc55cSDimitry Andric   }
7050fe6060f1SDimitry Andric 
7051fe6060f1SDimitry Andric   return nullptr;
7052fe6060f1SDimitry Andric }
7053fe6060f1SDimitry Andric 
70540b57cec5SDimitry Andric /// See if we can compute a simplified version of this instruction.
70550b57cec5SDimitry Andric /// If not, this returns null.
70560b57cec5SDimitry Andric 
7057fe6060f1SDimitry Andric static Value *simplifyInstructionWithOperands(Instruction *I,
7058fe6060f1SDimitry Andric                                               ArrayRef<Value *> NewOps,
7059fe6060f1SDimitry Andric                                               const SimplifyQuery &SQ,
706006c3fb27SDimitry Andric                                               unsigned MaxRecurse) {
706106c3fb27SDimitry Andric   assert(I->getFunction() && "instruction should be inserted in a function");
70625f757f3fSDimitry Andric   assert((!SQ.CxtI || SQ.CxtI->getFunction() == I->getFunction()) &&
70635f757f3fSDimitry Andric          "context instruction should be in the same function");
70645f757f3fSDimitry Andric 
70650b57cec5SDimitry Andric   const SimplifyQuery Q = SQ.CxtI ? SQ : SQ.getWithInstruction(I);
70660b57cec5SDimitry Andric 
70670b57cec5SDimitry Andric   switch (I->getOpcode()) {
70680b57cec5SDimitry Andric   default:
7069fe6060f1SDimitry Andric     if (llvm::all_of(NewOps, [](Value *V) { return isa<Constant>(V); })) {
7070fe6060f1SDimitry Andric       SmallVector<Constant *, 8> NewConstOps(NewOps.size());
7071fe6060f1SDimitry Andric       transform(NewOps, NewConstOps.begin(),
7072fe6060f1SDimitry Andric                 [](Value *V) { return cast<Constant>(V); });
7073bdd1243dSDimitry Andric       return ConstantFoldInstOperands(I, NewConstOps, Q.DL, Q.TLI);
7074fe6060f1SDimitry Andric     }
7075bdd1243dSDimitry Andric     return nullptr;
70760b57cec5SDimitry Andric   case Instruction::FNeg:
707706c3fb27SDimitry Andric     return simplifyFNegInst(NewOps[0], I->getFastMathFlags(), Q, MaxRecurse);
70780b57cec5SDimitry Andric   case Instruction::FAdd:
707906c3fb27SDimitry Andric     return simplifyFAddInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
708006c3fb27SDimitry Andric                             MaxRecurse);
70810b57cec5SDimitry Andric   case Instruction::Add:
708206c3fb27SDimitry Andric     return simplifyAddInst(
708306c3fb27SDimitry Andric         NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
708406c3fb27SDimitry Andric         Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q, MaxRecurse);
70850b57cec5SDimitry Andric   case Instruction::FSub:
708606c3fb27SDimitry Andric     return simplifyFSubInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
708706c3fb27SDimitry Andric                             MaxRecurse);
70880b57cec5SDimitry Andric   case Instruction::Sub:
708906c3fb27SDimitry Andric     return simplifySubInst(
709006c3fb27SDimitry Andric         NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
709106c3fb27SDimitry Andric         Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q, MaxRecurse);
70920b57cec5SDimitry Andric   case Instruction::FMul:
709306c3fb27SDimitry Andric     return simplifyFMulInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
709406c3fb27SDimitry Andric                             MaxRecurse);
70950b57cec5SDimitry Andric   case Instruction::Mul:
709606c3fb27SDimitry Andric     return simplifyMulInst(
709706c3fb27SDimitry Andric         NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
709806c3fb27SDimitry Andric         Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q, MaxRecurse);
7099bdd1243dSDimitry Andric   case Instruction::SDiv:
7100bdd1243dSDimitry Andric     return simplifySDivInst(NewOps[0], NewOps[1],
710106c3fb27SDimitry Andric                             Q.IIQ.isExact(cast<BinaryOperator>(I)), Q,
710206c3fb27SDimitry Andric                             MaxRecurse);
7103bdd1243dSDimitry Andric   case Instruction::UDiv:
7104bdd1243dSDimitry Andric     return simplifyUDivInst(NewOps[0], NewOps[1],
710506c3fb27SDimitry Andric                             Q.IIQ.isExact(cast<BinaryOperator>(I)), Q,
710606c3fb27SDimitry Andric                             MaxRecurse);
7107bdd1243dSDimitry Andric   case Instruction::FDiv:
710806c3fb27SDimitry Andric     return simplifyFDivInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
710906c3fb27SDimitry Andric                             MaxRecurse);
7110bdd1243dSDimitry Andric   case Instruction::SRem:
711106c3fb27SDimitry Andric     return simplifySRemInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7112bdd1243dSDimitry Andric   case Instruction::URem:
711306c3fb27SDimitry Andric     return simplifyURemInst(NewOps[0], NewOps[1], Q, MaxRecurse);
7114bdd1243dSDimitry Andric   case Instruction::FRem:
711506c3fb27SDimitry Andric     return simplifyFRemInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,
711606c3fb27SDimitry Andric                             MaxRecurse);
7117bdd1243dSDimitry Andric   case Instruction::Shl:
711806c3fb27SDimitry Andric     return simplifyShlInst(
711906c3fb27SDimitry Andric         NewOps[0], NewOps[1], Q.IIQ.hasNoSignedWrap(cast<BinaryOperator>(I)),
712006c3fb27SDimitry Andric         Q.IIQ.hasNoUnsignedWrap(cast<BinaryOperator>(I)), Q, MaxRecurse);
71210b57cec5SDimitry Andric   case Instruction::LShr:
7122bdd1243dSDimitry Andric     return simplifyLShrInst(NewOps[0], NewOps[1],
712306c3fb27SDimitry Andric                             Q.IIQ.isExact(cast<BinaryOperator>(I)), Q,
712406c3fb27SDimitry Andric                             MaxRecurse);
71250b57cec5SDimitry Andric   case Instruction::AShr:
7126bdd1243dSDimitry Andric     return simplifyAShrInst(NewOps[0], NewOps[1],
712706c3fb27SDimitry Andric                             Q.IIQ.isExact(cast<BinaryOperator>(I)), Q,
712806c3fb27SDimitry Andric                             MaxRecurse);
71290b57cec5SDimitry Andric   case Instruction::And:
713006c3fb27SDimitry Andric     return simplifyAndInst(NewOps[0], NewOps[1], Q, MaxRecurse);
71310b57cec5SDimitry Andric   case Instruction::Or:
713206c3fb27SDimitry Andric     return simplifyOrInst(NewOps[0], NewOps[1], Q, MaxRecurse);
71330b57cec5SDimitry Andric   case Instruction::Xor:
713406c3fb27SDimitry Andric     return simplifyXorInst(NewOps[0], NewOps[1], Q, MaxRecurse);
71350b57cec5SDimitry Andric   case Instruction::ICmp:
7136bdd1243dSDimitry Andric     return simplifyICmpInst(cast<ICmpInst>(I)->getPredicate(), NewOps[0],
713706c3fb27SDimitry Andric                             NewOps[1], Q, MaxRecurse);
71380b57cec5SDimitry Andric   case Instruction::FCmp:
7139bdd1243dSDimitry Andric     return simplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), NewOps[0],
714006c3fb27SDimitry Andric                             NewOps[1], I->getFastMathFlags(), Q, MaxRecurse);
71410b57cec5SDimitry Andric   case Instruction::Select:
714206c3fb27SDimitry Andric     return simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q, MaxRecurse);
71430b57cec5SDimitry Andric     break;
71440b57cec5SDimitry Andric   case Instruction::GetElementPtr: {
7145349cc55cSDimitry Andric     auto *GEPI = cast<GetElementPtrInst>(I);
7146bdd1243dSDimitry Andric     return simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0],
7147*0fca6ea1SDimitry Andric                            ArrayRef(NewOps).slice(1), GEPI->getNoWrapFlags(), Q,
714806c3fb27SDimitry Andric                            MaxRecurse);
71490b57cec5SDimitry Andric   }
71500b57cec5SDimitry Andric   case Instruction::InsertValue: {
71510b57cec5SDimitry Andric     InsertValueInst *IV = cast<InsertValueInst>(I);
715206c3fb27SDimitry Andric     return simplifyInsertValueInst(NewOps[0], NewOps[1], IV->getIndices(), Q,
715306c3fb27SDimitry Andric                                    MaxRecurse);
71540b57cec5SDimitry Andric   }
7155bdd1243dSDimitry Andric   case Instruction::InsertElement:
7156bdd1243dSDimitry Andric     return simplifyInsertElementInst(NewOps[0], NewOps[1], NewOps[2], Q);
71570b57cec5SDimitry Andric   case Instruction::ExtractValue: {
71580b57cec5SDimitry Andric     auto *EVI = cast<ExtractValueInst>(I);
715906c3fb27SDimitry Andric     return simplifyExtractValueInst(NewOps[0], EVI->getIndices(), Q,
716006c3fb27SDimitry Andric                                     MaxRecurse);
71610b57cec5SDimitry Andric   }
7162bdd1243dSDimitry Andric   case Instruction::ExtractElement:
716306c3fb27SDimitry Andric     return simplifyExtractElementInst(NewOps[0], NewOps[1], Q, MaxRecurse);
71640b57cec5SDimitry Andric   case Instruction::ShuffleVector: {
71650b57cec5SDimitry Andric     auto *SVI = cast<ShuffleVectorInst>(I);
7166bdd1243dSDimitry Andric     return simplifyShuffleVectorInst(NewOps[0], NewOps[1],
716706c3fb27SDimitry Andric                                      SVI->getShuffleMask(), SVI->getType(), Q,
716806c3fb27SDimitry Andric                                      MaxRecurse);
71690b57cec5SDimitry Andric   }
71700b57cec5SDimitry Andric   case Instruction::PHI:
7171bdd1243dSDimitry Andric     return simplifyPHINode(cast<PHINode>(I), NewOps, Q);
7172bdd1243dSDimitry Andric   case Instruction::Call:
717306c3fb27SDimitry Andric     return simplifyCall(
717406c3fb27SDimitry Andric         cast<CallInst>(I), NewOps.back(),
717506c3fb27SDimitry Andric         NewOps.drop_back(1 + cast<CallInst>(I)->getNumTotalBundleOperands()), Q);
7176480093f4SDimitry Andric   case Instruction::Freeze:
7177bdd1243dSDimitry Andric     return llvm::simplifyFreezeInst(NewOps[0], Q);
71780b57cec5SDimitry Andric #define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
71790b57cec5SDimitry Andric #include "llvm/IR/Instruction.def"
71800b57cec5SDimitry Andric #undef HANDLE_CAST_INST
718106c3fb27SDimitry Andric     return simplifyCastInst(I->getOpcode(), NewOps[0], I->getType(), Q,
718206c3fb27SDimitry Andric                             MaxRecurse);
71830b57cec5SDimitry Andric   case Instruction::Alloca:
71840b57cec5SDimitry Andric     // No simplifications for Alloca and it can't be constant folded.
7185bdd1243dSDimitry Andric     return nullptr;
7186fe6060f1SDimitry Andric   case Instruction::Load:
7187bdd1243dSDimitry Andric     return simplifyLoadInst(cast<LoadInst>(I), NewOps[0], Q);
71880b57cec5SDimitry Andric   }
71890b57cec5SDimitry Andric }
71900b57cec5SDimitry Andric 
719181ad6265SDimitry Andric Value *llvm::simplifyInstructionWithOperands(Instruction *I,
7192fe6060f1SDimitry Andric                                              ArrayRef<Value *> NewOps,
719306c3fb27SDimitry Andric                                              const SimplifyQuery &SQ) {
7194fe6060f1SDimitry Andric   assert(NewOps.size() == I->getNumOperands() &&
7195fe6060f1SDimitry Andric          "Number of operands should match the instruction!");
719606c3fb27SDimitry Andric   return ::simplifyInstructionWithOperands(I, NewOps, SQ, RecursionLimit);
7197fe6060f1SDimitry Andric }
7198fe6060f1SDimitry Andric 
719906c3fb27SDimitry Andric Value *llvm::simplifyInstruction(Instruction *I, const SimplifyQuery &SQ) {
7200fe6060f1SDimitry Andric   SmallVector<Value *, 8> Ops(I->operands());
720106c3fb27SDimitry Andric   Value *Result = ::simplifyInstructionWithOperands(I, Ops, SQ, RecursionLimit);
7202bdd1243dSDimitry Andric 
7203bdd1243dSDimitry Andric   /// If called on unreachable code, the instruction may simplify to itself.
7204bdd1243dSDimitry Andric   /// Make life easier for users by detecting that case here, and returning a
7205bdd1243dSDimitry Andric   /// safe value instead.
7206*0fca6ea1SDimitry Andric   return Result == I ? PoisonValue::get(I->getType()) : Result;
7207fe6060f1SDimitry Andric }
7208fe6060f1SDimitry Andric 
72090b57cec5SDimitry Andric /// Implementation of recursive simplification through an instruction's
72100b57cec5SDimitry Andric /// uses.
72110b57cec5SDimitry Andric ///
72120b57cec5SDimitry Andric /// This is the common implementation of the recursive simplification routines.
72130b57cec5SDimitry Andric /// If we have a pre-simplified value in 'SimpleV', that is forcibly used to
72140b57cec5SDimitry Andric /// replace the instruction 'I'. Otherwise, we simply add 'I' to the list of
72150b57cec5SDimitry Andric /// instructions to process and attempt to simplify it using
72160b57cec5SDimitry Andric /// InstructionSimplify. Recursively visited users which could not be
72170b57cec5SDimitry Andric /// simplified themselves are to the optional UnsimplifiedUsers set for
72180b57cec5SDimitry Andric /// further processing by the caller.
72190b57cec5SDimitry Andric ///
72200b57cec5SDimitry Andric /// This routine returns 'true' only when *it* simplifies something. The passed
72210b57cec5SDimitry Andric /// in simplified value does not count toward this.
72220b57cec5SDimitry Andric static bool replaceAndRecursivelySimplifyImpl(
72230b57cec5SDimitry Andric     Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI,
72240b57cec5SDimitry Andric     const DominatorTree *DT, AssumptionCache *AC,
72250b57cec5SDimitry Andric     SmallSetVector<Instruction *, 8> *UnsimplifiedUsers = nullptr) {
72260b57cec5SDimitry Andric   bool Simplified = false;
72270b57cec5SDimitry Andric   SmallSetVector<Instruction *, 8> Worklist;
7228*0fca6ea1SDimitry Andric   const DataLayout &DL = I->getDataLayout();
72290b57cec5SDimitry Andric 
72300b57cec5SDimitry Andric   // If we have an explicit value to collapse to, do that round of the
72310b57cec5SDimitry Andric   // simplification loop by hand initially.
72320b57cec5SDimitry Andric   if (SimpleV) {
72330b57cec5SDimitry Andric     for (User *U : I->users())
72340b57cec5SDimitry Andric       if (U != I)
72350b57cec5SDimitry Andric         Worklist.insert(cast<Instruction>(U));
72360b57cec5SDimitry Andric 
72370b57cec5SDimitry Andric     // Replace the instruction with its simplified value.
72380b57cec5SDimitry Andric     I->replaceAllUsesWith(SimpleV);
72390b57cec5SDimitry Andric 
724006c3fb27SDimitry Andric     if (!I->isEHPad() && !I->isTerminator() && !I->mayHaveSideEffects())
72410b57cec5SDimitry Andric       I->eraseFromParent();
72420b57cec5SDimitry Andric   } else {
72430b57cec5SDimitry Andric     Worklist.insert(I);
72440b57cec5SDimitry Andric   }
72450b57cec5SDimitry Andric 
72460b57cec5SDimitry Andric   // Note that we must test the size on each iteration, the worklist can grow.
72470b57cec5SDimitry Andric   for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) {
72480b57cec5SDimitry Andric     I = Worklist[Idx];
72490b57cec5SDimitry Andric 
72500b57cec5SDimitry Andric     // See if this instruction simplifies.
725181ad6265SDimitry Andric     SimpleV = simplifyInstruction(I, {DL, TLI, DT, AC});
72520b57cec5SDimitry Andric     if (!SimpleV) {
72530b57cec5SDimitry Andric       if (UnsimplifiedUsers)
72540b57cec5SDimitry Andric         UnsimplifiedUsers->insert(I);
72550b57cec5SDimitry Andric       continue;
72560b57cec5SDimitry Andric     }
72570b57cec5SDimitry Andric 
72580b57cec5SDimitry Andric     Simplified = true;
72590b57cec5SDimitry Andric 
72600b57cec5SDimitry Andric     // Stash away all the uses of the old instruction so we can check them for
72610b57cec5SDimitry Andric     // recursive simplifications after a RAUW. This is cheaper than checking all
72620b57cec5SDimitry Andric     // uses of To on the recursive step in most cases.
72630b57cec5SDimitry Andric     for (User *U : I->users())
72640b57cec5SDimitry Andric       Worklist.insert(cast<Instruction>(U));
72650b57cec5SDimitry Andric 
72660b57cec5SDimitry Andric     // Replace the instruction with its simplified value.
72670b57cec5SDimitry Andric     I->replaceAllUsesWith(SimpleV);
72680b57cec5SDimitry Andric 
726906c3fb27SDimitry Andric     if (!I->isEHPad() && !I->isTerminator() && !I->mayHaveSideEffects())
72700b57cec5SDimitry Andric       I->eraseFromParent();
72710b57cec5SDimitry Andric   }
72720b57cec5SDimitry Andric   return Simplified;
72730b57cec5SDimitry Andric }
72740b57cec5SDimitry Andric 
72750b57cec5SDimitry Andric bool llvm::replaceAndRecursivelySimplify(
72760b57cec5SDimitry Andric     Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI,
72770b57cec5SDimitry Andric     const DominatorTree *DT, AssumptionCache *AC,
72780b57cec5SDimitry Andric     SmallSetVector<Instruction *, 8> *UnsimplifiedUsers) {
72790b57cec5SDimitry Andric   assert(I != SimpleV && "replaceAndRecursivelySimplify(X,X) is not valid!");
72800b57cec5SDimitry Andric   assert(SimpleV && "Must provide a simplified value.");
72810b57cec5SDimitry Andric   return replaceAndRecursivelySimplifyImpl(I, SimpleV, TLI, DT, AC,
72820b57cec5SDimitry Andric                                            UnsimplifiedUsers);
72830b57cec5SDimitry Andric }
72840b57cec5SDimitry Andric 
72850b57cec5SDimitry Andric namespace llvm {
72860b57cec5SDimitry Andric const SimplifyQuery getBestSimplifyQuery(Pass &P, Function &F) {
72870b57cec5SDimitry Andric   auto *DTWP = P.getAnalysisIfAvailable<DominatorTreeWrapperPass>();
72880b57cec5SDimitry Andric   auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
72890b57cec5SDimitry Andric   auto *TLIWP = P.getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
72908bcb0991SDimitry Andric   auto *TLI = TLIWP ? &TLIWP->getTLI(F) : nullptr;
72910b57cec5SDimitry Andric   auto *ACWP = P.getAnalysisIfAvailable<AssumptionCacheTracker>();
72920b57cec5SDimitry Andric   auto *AC = ACWP ? &ACWP->getAssumptionCache(F) : nullptr;
7293*0fca6ea1SDimitry Andric   return {F.getDataLayout(), TLI, DT, AC};
72940b57cec5SDimitry Andric }
72950b57cec5SDimitry Andric 
72960b57cec5SDimitry Andric const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &AR,
72970b57cec5SDimitry Andric                                          const DataLayout &DL) {
72980b57cec5SDimitry Andric   return {DL, &AR.TLI, &AR.DT, &AR.AC};
72990b57cec5SDimitry Andric }
73000b57cec5SDimitry Andric 
73010b57cec5SDimitry Andric template <class T, class... TArgs>
73020b57cec5SDimitry Andric const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &AM,
73030b57cec5SDimitry Andric                                          Function &F) {
73040b57cec5SDimitry Andric   auto *DT = AM.template getCachedResult<DominatorTreeAnalysis>(F);
73050b57cec5SDimitry Andric   auto *TLI = AM.template getCachedResult<TargetLibraryAnalysis>(F);
73060b57cec5SDimitry Andric   auto *AC = AM.template getCachedResult<AssumptionAnalysis>(F);
7307*0fca6ea1SDimitry Andric   return {F.getDataLayout(), TLI, DT, AC};
73080b57cec5SDimitry Andric }
73090b57cec5SDimitry Andric template const SimplifyQuery getBestSimplifyQuery(AnalysisManager<Function> &,
73100b57cec5SDimitry Andric                                                   Function &);
7311*0fca6ea1SDimitry Andric 
7312*0fca6ea1SDimitry Andric bool SimplifyQuery::isUndefValue(Value *V) const {
7313*0fca6ea1SDimitry Andric   if (!CanUseUndef)
7314*0fca6ea1SDimitry Andric     return false;
7315*0fca6ea1SDimitry Andric 
7316*0fca6ea1SDimitry Andric   return match(V, m_Undef());
7317*0fca6ea1SDimitry Andric }
7318*0fca6ea1SDimitry Andric 
731981ad6265SDimitry Andric } // namespace llvm
732004eeddc0SDimitry Andric 
732104eeddc0SDimitry Andric void InstSimplifyFolder::anchor() {}
7322