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