blob: 4e6e666922671d7181e61a837eab206448d166f9 [file] [log] [blame]
//===- InstructionSimplify.cpp - Fold instruction operands ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements routines for folding instructions into simpler forms
// that do not require creating new instructions. This does constant folding
// ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
// returning a constant ("and i32 %x, 0" -> "0") or an already existing value
// ("and i32 %x, %x" -> "%x"). All operands are assumed to have already been
// simplified: This is usually true and assuming it simplifies the logic (if
// they have not been simplified then results are correct but maybe suboptimal).
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstSimplifyFolder.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/OverflowInstAnalysis.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/Support/KnownBits.h"
#include <algorithm>
#include <optional>
using namespace llvm;
using namespace llvm::PatternMatch;
#define DEBUG_TYPE "instsimplify"
enum { RecursionLimit = 3 };
STATISTIC(NumExpand, "Number of expansions");
STATISTIC(NumReassoc, "Number of reassociations");
static Value *simplifyAndInst(Value *, Value *, const SimplifyQuery &,
unsigned);
static Value *simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned);
static Value *simplifyFPUnOp(unsigned, Value *, const FastMathFlags &,
const SimplifyQuery &, unsigned);
static Value *simplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &,
unsigned);
static Value *simplifyBinOp(unsigned, Value *, Value *, const FastMathFlags &,
const SimplifyQuery &, unsigned);
static Value *simplifyCmpInst(unsigned, Value *, Value *, const SimplifyQuery &,
unsigned);
static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const SimplifyQuery &Q, unsigned MaxRecurse);
static Value *simplifyOrInst(Value *, Value *, const SimplifyQuery &, unsigned);
static Value *simplifyXorInst(Value *, Value *, const SimplifyQuery &,
unsigned);
static Value *simplifyCastInst(unsigned, Value *, Type *, const SimplifyQuery &,
unsigned);
static Value *simplifyGEPInst(Type *, Value *, ArrayRef<Value *>, bool,
const SimplifyQuery &, unsigned);
static Value *simplifySelectInst(Value *, Value *, Value *,
const SimplifyQuery &, unsigned);
static Value *simplifyInstructionWithOperands(Instruction *I,
ArrayRef<Value *> NewOps,
const SimplifyQuery &SQ,
unsigned MaxRecurse);
static Value *foldSelectWithBinaryOp(Value *Cond, Value *TrueVal,
Value *FalseVal) {
BinaryOperator::BinaryOps BinOpCode;
if (auto *BO = dyn_cast<BinaryOperator>(Cond))
BinOpCode = BO->getOpcode();
else
return nullptr;
CmpInst::Predicate ExpectedPred, Pred1, Pred2;
if (BinOpCode == BinaryOperator::Or) {
ExpectedPred = ICmpInst::ICMP_NE;
} else if (BinOpCode == BinaryOperator::And) {
ExpectedPred = ICmpInst::ICMP_EQ;
} else
return nullptr;
// %A = icmp eq %TV, %FV
// %B = icmp eq %X, %Y (and one of these is a select operand)
// %C = and %A, %B
// %D = select %C, %TV, %FV
// -->
// %FV
// %A = icmp ne %TV, %FV
// %B = icmp ne %X, %Y (and one of these is a select operand)
// %C = or %A, %B
// %D = select %C, %TV, %FV
// -->
// %TV
Value *X, *Y;
if (!match(Cond, m_c_BinOp(m_c_ICmp(Pred1, m_Specific(TrueVal),
m_Specific(FalseVal)),
m_ICmp(Pred2, m_Value(X), m_Value(Y)))) ||
Pred1 != Pred2 || Pred1 != ExpectedPred)
return nullptr;
if (X == TrueVal || X == FalseVal || Y == TrueVal || Y == FalseVal)
return BinOpCode == BinaryOperator::Or ? TrueVal : FalseVal;
return nullptr;
}
/// For a boolean type or a vector of boolean type, return false or a vector
/// with every element false.
static Constant *getFalse(Type *Ty) { return ConstantInt::getFalse(Ty); }
/// For a boolean type or a vector of boolean type, return true or a vector
/// with every element true.
static Constant *getTrue(Type *Ty) { return ConstantInt::getTrue(Ty); }
/// isSameCompare - Is V equivalent to the comparison "LHS Pred RHS"?
static bool isSameCompare(Value *V, CmpInst::Predicate Pred, Value *LHS,
Value *RHS) {
CmpInst *Cmp = dyn_cast<CmpInst>(V);
if (!Cmp)
return false;
CmpInst::Predicate CPred = Cmp->getPredicate();
Value *CLHS = Cmp->getOperand(0), *CRHS = Cmp->getOperand(1);
if (CPred == Pred && CLHS == LHS && CRHS == RHS)
return true;
return CPred == CmpInst::getSwappedPredicate(Pred) && CLHS == RHS &&
CRHS == LHS;
}
/// Simplify comparison with true or false branch of select:
/// %sel = select i1 %cond, i32 %tv, i32 %fv
/// %cmp = icmp sle i32 %sel, %rhs
/// Compose new comparison by substituting %sel with either %tv or %fv
/// and see if it simplifies.
static Value *simplifyCmpSelCase(CmpInst::Predicate Pred, Value *LHS,
Value *RHS, Value *Cond,
const SimplifyQuery &Q, unsigned MaxRecurse,
Constant *TrueOrFalse) {
Value *SimplifiedCmp = simplifyCmpInst(Pred, LHS, RHS, Q, MaxRecurse);
if (SimplifiedCmp == Cond) {
// %cmp simplified to the select condition (%cond).
return TrueOrFalse;
} else if (!SimplifiedCmp && isSameCompare(Cond, Pred, LHS, RHS)) {
// It didn't simplify. However, if composed comparison is equivalent
// to the select condition (%cond) then we can replace it.
return TrueOrFalse;
}
return SimplifiedCmp;
}
/// Simplify comparison with true branch of select
static Value *simplifyCmpSelTrueCase(CmpInst::Predicate Pred, Value *LHS,
Value *RHS, Value *Cond,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
return simplifyCmpSelCase(Pred, LHS, RHS, Cond, Q, MaxRecurse,
getTrue(Cond->getType()));
}
/// Simplify comparison with false branch of select
static Value *simplifyCmpSelFalseCase(CmpInst::Predicate Pred, Value *LHS,
Value *RHS, Value *Cond,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
return simplifyCmpSelCase(Pred, LHS, RHS, Cond, Q, MaxRecurse,
getFalse(Cond->getType()));
}
/// We know comparison with both branches of select can be simplified, but they
/// are not equal. This routine handles some logical simplifications.
static Value *handleOtherCmpSelSimplifications(Value *TCmp, Value *FCmp,
Value *Cond,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
// If the false value simplified to false, then the result of the compare
// is equal to "Cond && TCmp". This also catches the case when the false
// value simplified to false and the true value to true, returning "Cond".
// Folding select to and/or isn't poison-safe in general; impliesPoison
// checks whether folding it does not convert a well-defined value into
// poison.
if (match(FCmp, m_Zero()) && impliesPoison(TCmp, Cond))
if (Value *V = simplifyAndInst(Cond, TCmp, Q, MaxRecurse))
return V;
// If the true value simplified to true, then the result of the compare
// is equal to "Cond || FCmp".
if (match(TCmp, m_One()) && impliesPoison(FCmp, Cond))
if (Value *V = simplifyOrInst(Cond, FCmp, Q, MaxRecurse))
return V;
// Finally, if the false value simplified to true and the true value to
// false, then the result of the compare is equal to "!Cond".
if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
if (Value *V = simplifyXorInst(
Cond, Constant::getAllOnesValue(Cond->getType()), Q, MaxRecurse))
return V;
return nullptr;
}
/// Does the given value dominate the specified phi node?
static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I)
// Arguments and constants dominate all instructions.
return true;
// If we have a DominatorTree then do a precise test.
if (DT)
return DT->dominates(I, P);
// Otherwise, if the instruction is in the entry block and is not an invoke,
// then it obviously dominates all phi nodes.
if (I->getParent()->isEntryBlock() && !isa<InvokeInst>(I) &&
!isa<CallBrInst>(I))
return true;
return false;
}
/// Try to simplify a binary operator of form "V op OtherOp" where V is
/// "(B0 opex B1)" by distributing 'op' across 'opex' as
/// "(B0 op OtherOp) opex (B1 op OtherOp)".
static Value *expandBinOp(Instruction::BinaryOps Opcode, Value *V,
Value *OtherOp, Instruction::BinaryOps OpcodeToExpand,
const SimplifyQuery &Q, unsigned MaxRecurse) {
auto *B = dyn_cast<BinaryOperator>(V);
if (!B || B->getOpcode() != OpcodeToExpand)
return nullptr;
Value *B0 = B->getOperand(0), *B1 = B->getOperand(1);
Value *L =
simplifyBinOp(Opcode, B0, OtherOp, Q.getWithoutUndef(), MaxRecurse);
if (!L)
return nullptr;
Value *R =
simplifyBinOp(Opcode, B1, OtherOp, Q.getWithoutUndef(), MaxRecurse);
if (!R)
return nullptr;
// Does the expanded pair of binops simplify to the existing binop?
if ((L == B0 && R == B1) ||
(Instruction::isCommutative(OpcodeToExpand) && L == B1 && R == B0)) {
++NumExpand;
return B;
}
// Otherwise, return "L op' R" if it simplifies.
Value *S = simplifyBinOp(OpcodeToExpand, L, R, Q, MaxRecurse);
if (!S)
return nullptr;
++NumExpand;
return S;
}
/// Try to simplify binops of form "A op (B op' C)" or the commuted variant by
/// distributing op over op'.
static Value *expandCommutativeBinOp(Instruction::BinaryOps Opcode, Value *L,
Value *R,
Instruction::BinaryOps OpcodeToExpand,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
if (Value *V = expandBinOp(Opcode, L, R, OpcodeToExpand, Q, MaxRecurse))
return V;
if (Value *V = expandBinOp(Opcode, R, L, OpcodeToExpand, Q, MaxRecurse))
return V;
return nullptr;
}
/// Generic simplifications for associative binary operations.
/// Returns the simpler value, or null if none was found.
static Value *simplifyAssociativeBinOp(Instruction::BinaryOps Opcode,
Value *LHS, Value *RHS,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
assert(Instruction::isAssociative(Opcode) && "Not an associative operation!");
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
BinaryOperator *Op0 = dyn_cast<BinaryOperator>(LHS);
BinaryOperator *Op1 = dyn_cast<BinaryOperator>(RHS);
// Transform: "(A op B) op C" ==> "A op (B op C)" if it simplifies completely.
if (Op0 && Op0->getOpcode() == Opcode) {
Value *A = Op0->getOperand(0);
Value *B = Op0->getOperand(1);
Value *C = RHS;
// Does "B op C" simplify?
if (Value *V = simplifyBinOp(Opcode, B, C, Q, MaxRecurse)) {
// It does! Return "A op V" if it simplifies or is already available.
// If V equals B then "A op V" is just the LHS.
if (V == B)
return LHS;
// Otherwise return "A op V" if it simplifies.
if (Value *W = simplifyBinOp(Opcode, A, V, Q, MaxRecurse)) {
++NumReassoc;
return W;
}
}
}
// Transform: "A op (B op C)" ==> "(A op B) op C" if it simplifies completely.
if (Op1 && Op1->getOpcode() == Opcode) {
Value *A = LHS;
Value *B = Op1->getOperand(0);
Value *C = Op1->getOperand(1);
// Does "A op B" simplify?
if (Value *V = simplifyBinOp(Opcode, A, B, Q, MaxRecurse)) {
// It does! Return "V op C" if it simplifies or is already available.
// If V equals B then "V op C" is just the RHS.
if (V == B)
return RHS;
// Otherwise return "V op C" if it simplifies.
if (Value *W = simplifyBinOp(Opcode, V, C, Q, MaxRecurse)) {
++NumReassoc;
return W;
}
}
}
// The remaining transforms require commutativity as well as associativity.
if (!Instruction::isCommutative(Opcode))
return nullptr;
// Transform: "(A op B) op C" ==> "(C op A) op B" if it simplifies completely.
if (Op0 && Op0->getOpcode() == Opcode) {
Value *A = Op0->getOperand(0);
Value *B = Op0->getOperand(1);
Value *C = RHS;
// Does "C op A" simplify?
if (Value *V = simplifyBinOp(Opcode, C, A, Q, MaxRecurse)) {
// It does! Return "V op B" if it simplifies or is already available.
// If V equals A then "V op B" is just the LHS.
if (V == A)
return LHS;
// Otherwise return "V op B" if it simplifies.
if (Value *W = simplifyBinOp(Opcode, V, B, Q, MaxRecurse)) {
++NumReassoc;
return W;
}
}
}
// Transform: "A op (B op C)" ==> "B op (C op A)" if it simplifies completely.
if (Op1 && Op1->getOpcode() == Opcode) {
Value *A = LHS;
Value *B = Op1->getOperand(0);
Value *C = Op1->getOperand(1);
// Does "C op A" simplify?
if (Value *V = simplifyBinOp(Opcode, C, A, Q, MaxRecurse)) {
// It does! Return "B op V" if it simplifies or is already available.
// If V equals C then "B op V" is just the RHS.
if (V == C)
return RHS;
// Otherwise return "B op V" if it simplifies.
if (Value *W = simplifyBinOp(Opcode, B, V, Q, MaxRecurse)) {
++NumReassoc;
return W;
}
}
}
return nullptr;
}
/// In the case of a binary operation with a select instruction as an operand,
/// try to simplify the binop by seeing whether evaluating it on both branches
/// of the select results in the same value. Returns the common value if so,
/// otherwise returns null.
static Value *threadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS,
Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
SelectInst *SI;
if (isa<SelectInst>(LHS)) {
SI = cast<SelectInst>(LHS);
} else {
assert(isa<SelectInst>(RHS) && "No select instruction operand!");
SI = cast<SelectInst>(RHS);
}
// Evaluate the BinOp on the true and false branches of the select.
Value *TV;
Value *FV;
if (SI == LHS) {
TV = simplifyBinOp(Opcode, SI->getTrueValue(), RHS, Q, MaxRecurse);
FV = simplifyBinOp(Opcode, SI->getFalseValue(), RHS, Q, MaxRecurse);
} else {
TV = simplifyBinOp(Opcode, LHS, SI->getTrueValue(), Q, MaxRecurse);
FV = simplifyBinOp(Opcode, LHS, SI->getFalseValue(), Q, MaxRecurse);
}
// If they simplified to the same value, then return the common value.
// If they both failed to simplify then return null.
if (TV == FV)
return TV;
// If one branch simplified to undef, return the other one.
if (TV && Q.isUndefValue(TV))
return FV;
if (FV && Q.isUndefValue(FV))
return TV;
// If applying the operation did not change the true and false select values,
// then the result of the binop is the select itself.
if (TV == SI->getTrueValue() && FV == SI->getFalseValue())
return SI;
// If one branch simplified and the other did not, and the simplified
// value is equal to the unsimplified one, return the simplified value.
// For example, select (cond, X, X & Z) & Z -> X & Z.
if ((FV && !TV) || (TV && !FV)) {
// Check that the simplified value has the form "X op Y" where "op" is the
// same as the original operation.
Instruction *Simplified = dyn_cast<Instruction>(FV ? FV : TV);
if (Simplified && Simplified->getOpcode() == unsigned(Opcode) &&
!Simplified->hasPoisonGeneratingFlags()) {
// The value that didn't simplify is "UnsimplifiedLHS op UnsimplifiedRHS".
// We already know that "op" is the same as for the simplified value. See
// if the operands match too. If so, return the simplified value.
Value *UnsimplifiedBranch = FV ? SI->getTrueValue() : SI->getFalseValue();
Value *UnsimplifiedLHS = SI == LHS ? UnsimplifiedBranch : LHS;
Value *UnsimplifiedRHS = SI == LHS ? RHS : UnsimplifiedBranch;
if (Simplified->getOperand(0) == UnsimplifiedLHS &&
Simplified->getOperand(1) == UnsimplifiedRHS)
return Simplified;
if (Simplified->isCommutative() &&
Simplified->getOperand(1) == UnsimplifiedLHS &&
Simplified->getOperand(0) == UnsimplifiedRHS)
return Simplified;
}
}
return nullptr;
}
/// In the case of a comparison with a select instruction, try to simplify the
/// comparison by seeing whether both branches of the select result in the same
/// value. Returns the common value if so, otherwise returns null.
/// For example, if we have:
/// %tmp = select i1 %cmp, i32 1, i32 2
/// %cmp1 = icmp sle i32 %tmp, 3
/// We can simplify %cmp1 to true, because both branches of select are
/// less than 3. We compose new comparison by substituting %tmp with both
/// branches of select and see if it can be simplified.
static Value *threadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
// Make sure the select is on the LHS.
if (!isa<SelectInst>(LHS)) {
std::swap(LHS, RHS);
Pred = CmpInst::getSwappedPredicate(Pred);
}
assert(isa<SelectInst>(LHS) && "Not comparing with a select instruction!");
SelectInst *SI = cast<SelectInst>(LHS);
Value *Cond = SI->getCondition();
Value *TV = SI->getTrueValue();
Value *FV = SI->getFalseValue();
// Now that we have "cmp select(Cond, TV, FV), RHS", analyse it.
// Does "cmp TV, RHS" simplify?
Value *TCmp = simplifyCmpSelTrueCase(Pred, TV, RHS, Cond, Q, MaxRecurse);
if (!TCmp)
return nullptr;
// Does "cmp FV, RHS" simplify?
Value *FCmp = simplifyCmpSelFalseCase(Pred, FV, RHS, Cond, Q, MaxRecurse);
if (!FCmp)
return nullptr;
// If both sides simplified to the same value, then use it as the result of
// the original comparison.
if (TCmp == FCmp)
return TCmp;
// The remaining cases only make sense if the select condition has the same
// type as the result of the comparison, so bail out if this is not so.
if (Cond->getType()->isVectorTy() == RHS->getType()->isVectorTy())
return handleOtherCmpSelSimplifications(TCmp, FCmp, Cond, Q, MaxRecurse);
return nullptr;
}
/// In the case of a binary operation with an operand that is a PHI instruction,
/// try to simplify the binop by seeing whether evaluating it on the incoming
/// phi values yields the same result for every value. If so returns the common
/// value, otherwise returns null.
static Value *threadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS,
Value *RHS, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
PHINode *PI;
if (isa<PHINode>(LHS)) {
PI = cast<PHINode>(LHS);
// Bail out if RHS and the phi may be mutually interdependent due to a loop.
if (!valueDominatesPHI(RHS, PI, Q.DT))
return nullptr;
} else {
assert(isa<PHINode>(RHS) && "No PHI instruction operand!");
PI = cast<PHINode>(RHS);
// Bail out if LHS and the phi may be mutually interdependent due to a loop.
if (!valueDominatesPHI(LHS, PI, Q.DT))
return nullptr;
}
// Evaluate the BinOp on the incoming phi values.
Value *CommonValue = nullptr;
for (Use &Incoming : PI->incoming_values()) {
// If the incoming value is the phi node itself, it can safely be skipped.
if (Incoming == PI)
continue;
Instruction *InTI = PI->getIncomingBlock(Incoming)->getTerminator();
Value *V = PI == LHS
? simplifyBinOp(Opcode, Incoming, RHS,
Q.getWithInstruction(InTI), MaxRecurse)
: simplifyBinOp(Opcode, LHS, Incoming,
Q.getWithInstruction(InTI), MaxRecurse);
// If the operation failed to simplify, or simplified to a different value
// to previously, then give up.
if (!V || (CommonValue && V != CommonValue))
return nullptr;
CommonValue = V;
}
return CommonValue;
}
/// In the case of a comparison with a PHI instruction, try to simplify the
/// comparison by seeing whether comparing with all of the incoming phi values
/// yields the same result every time. If so returns the common result,
/// otherwise returns null.
static Value *threadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
const SimplifyQuery &Q, unsigned MaxRecurse) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return nullptr;
// Make sure the phi is on the LHS.
if (!isa<PHINode>(LHS)) {
std::swap(LHS, RHS);
Pred = CmpInst::getSwappedPredicate(Pred);
}
assert(isa<PHINode>(LHS) && "Not comparing with a phi instruction!");
PHINode *PI = cast<PHINode>(LHS);
// Bail out if RHS and the phi may be mutually interdependent due to a loop.
if (!valueDominatesPHI(RHS, PI, Q.DT))
return nullptr;
// Evaluate the BinOp on the incoming phi values.
Value *CommonValue = nullptr;
for (unsigned u = 0, e = PI->getNumIncomingValues(); u < e; ++u) {
Value *Incoming = PI->getIncomingValue(u);
Instruction *InTI = PI->getIncomingBlock(u)->getTerminator();
// If the incoming value is the phi node itself, it can safely be skipped.
if (Incoming == PI)
continue;
// Change the context instruction to the "edge" that flows into the phi.
// This is important because that is where incoming is actually "evaluated"
// even though it is used later somewhere else.
Value *V = simplifyCmpInst(Pred, Incoming, RHS, Q.getWithInstruction(InTI),
MaxRecurse);
// If the operation failed to simplify, or simplified to a different value
// to previously, then give up.
if (!V || (CommonValue && V != CommonValue))
return nullptr;
CommonValue = V;
}
return CommonValue;
}
static Constant *foldOrCommuteConstant(Instruction::BinaryOps Opcode,
Value *&Op0, Value *&Op1,
const SimplifyQuery &Q) {
if (auto *CLHS = dyn_cast<Constant>(Op0)) {
if (auto *CRHS = dyn_cast<Constant>(Op1)) {
switch (Opcode) {
default:
break;
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul:
case Instruction::FDiv:
case Instruction::FRem:
if (Q.CxtI != nullptr)
return ConstantFoldFPInstOperands(Opcode, CLHS, CRHS, Q.DL, Q.CxtI);
}
return ConstantFoldBinaryOpOperands(Opcode, CLHS, CRHS, Q.DL);
}
// Canonicalize the constant to the RHS if this is a commutative operation.
if (Instruction::isCommutative(Opcode))
std::swap(Op0, Op1);
}
return nullptr;
}
/// Given operands for an Add, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Add, Op0, Op1, Q))
return C;
// X + poison -> poison
if (isa<PoisonValue>(Op1))
return Op1;
// X + undef -> undef
if (Q.isUndefValue(Op1))
return Op1;
// X + 0 -> X
if (match(Op1, m_Zero()))
return Op0;
// If two operands are negative, return 0.
if (isKnownNegation(Op0, Op1))
return Constant::getNullValue(Op0->getType());
// X + (Y - X) -> Y
// (Y - X) + X -> Y
// Eg: X + -X -> 0
Value *Y = nullptr;
if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) ||
match(Op0, m_Sub(m_Value(Y), m_Specific(Op1))))
return Y;
// X + ~X -> -1 since ~X = -X-1
Type *Ty = Op0->getType();
if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0))))
return Constant::getAllOnesValue(Ty);
// add nsw/nuw (xor Y, signmask), signmask --> Y
// The no-wrapping add guarantees that the top bit will be set by the add.
// Therefore, the xor must be clearing the already set sign bit of Y.
if ((IsNSW || IsNUW) && match(Op1, m_SignMask()) &&
match(Op0, m_Xor(m_Value(Y), m_SignMask())))
return Y;
// add nuw %x, -1 -> -1, because %x can only be 0.
if (IsNUW && match(Op1, m_AllOnes()))
return Op1; // Which is -1.
/// i1 add -> xor.
if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1))
if (Value *V = simplifyXorInst(Op0, Op1, Q, MaxRecurse - 1))
return V;
// Try some generic simplifications for associative operations.
if (Value *V =
simplifyAssociativeBinOp(Instruction::Add, Op0, Op1, Q, MaxRecurse))
return V;
// Threading Add over selects and phi nodes is pointless, so don't bother.
// Threading over the select in "A + select(cond, B, C)" means evaluating
// "A+B" and "A+C" and seeing if they are equal; but they are equal if and
// only if B and C are equal. If B and C are equal then (since we assume
// that operands have already been simplified) "select(cond, B, C)" should
// have been simplified to the common value of B and C already. Analysing
// "A+B" and "A+C" thus gains nothing, but costs compile time. Similarly
// for threading over phi nodes.
return nullptr;
}
Value *llvm::simplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Query) {
return ::simplifyAddInst(Op0, Op1, IsNSW, IsNUW, Query, RecursionLimit);
}
/// Compute the base pointer and cumulative constant offsets for V.
///
/// This strips all constant offsets off of V, leaving it the base pointer, and
/// accumulates the total constant offset applied in the returned constant.
/// It returns zero if there are no constant offsets applied.
///
/// This is very similar to stripAndAccumulateConstantOffsets(), except it
/// normalizes the offset bitwidth to the stripped pointer type, not the
/// original pointer type.
static APInt stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V,
bool AllowNonInbounds = false) {
assert(V->getType()->isPtrOrPtrVectorTy());
APInt Offset = APInt::getZero(DL.getIndexTypeSizeInBits(V->getType()));
V = V->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds);
// As that strip may trace through `addrspacecast`, need to sext or trunc
// the offset calculated.
return Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(V->getType()));
}
/// Compute the constant difference between two pointer values.
/// If the difference is not a constant, returns zero.
static Constant *computePointerDifference(const DataLayout &DL, Value *LHS,
Value *RHS) {
APInt LHSOffset = stripAndComputeConstantOffsets(DL, LHS);
APInt RHSOffset = stripAndComputeConstantOffsets(DL, RHS);
// If LHS and RHS are not related via constant offsets to the same base
// value, there is nothing we can do here.
if (LHS != RHS)
return nullptr;
// Otherwise, the difference of LHS - RHS can be computed as:
// LHS - RHS
// = (LHSOffset + Base) - (RHSOffset + Base)
// = LHSOffset - RHSOffset
Constant *Res = ConstantInt::get(LHS->getContext(), LHSOffset - RHSOffset);
if (auto *VecTy = dyn_cast<VectorType>(LHS->getType()))
Res = ConstantVector::getSplat(VecTy->getElementCount(), Res);
return Res;
}
/// Test if there is a dominating equivalence condition for the
/// two operands. If there is, try to reduce the binary operation
/// between the two operands.
/// Example: Op0 - Op1 --> 0 when Op0 == Op1
static Value *simplifyByDomEq(unsigned Opcode, Value *Op0, Value *Op1,
const SimplifyQuery &Q, unsigned MaxRecurse) {
// Recursive run it can not get any benefit
if (MaxRecurse != RecursionLimit)
return nullptr;
std::optional<bool> Imp =
isImpliedByDomCondition(CmpInst::ICMP_EQ, Op0, Op1, Q.CxtI, Q.DL);
if (Imp && *Imp) {
Type *Ty = Op0->getType();
switch (Opcode) {
case Instruction::Sub:
case Instruction::Xor:
case Instruction::URem:
case Instruction::SRem:
return Constant::getNullValue(Ty);
case Instruction::SDiv:
case Instruction::UDiv:
return ConstantInt::get(Ty, 1);
case Instruction::And:
case Instruction::Or:
// Could be either one - choose Op1 since that's more likely a constant.
return Op1;
default:
break;
}
}
return nullptr;
}
/// Given operands for a Sub, see if we can fold the result.
/// If not, this returns null.
static Value *simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Sub, Op0, Op1, Q))
return C;
// X - poison -> poison
// poison - X -> poison
if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
return PoisonValue::get(Op0->getType());
// X - undef -> undef
// undef - X -> undef
if (Q.isUndefValue(Op0) || Q.isUndefValue(Op1))
return UndefValue::get(Op0->getType());
// X - 0 -> X
if (match(Op1, m_Zero()))
return Op0;
// X - X -> 0
if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
// Is this a negation?
if (match(Op0, m_Zero())) {
// 0 - X -> 0 if the sub is NUW.
if (IsNUW)
return Constant::getNullValue(Op0->getType());
KnownBits Known = computeKnownBits(Op1, /* Depth */ 0, Q);
if (Known.Zero.isMaxSignedValue()) {
// Op1 is either 0 or the minimum signed value. If the sub is NSW, then
// Op1 must be 0 because negating the minimum signed value is undefined.
if (IsNSW)
return Constant::getNullValue(Op0->getType());
// 0 - X -> X if X is 0 or the minimum signed value.
return Op1;
}
}
// (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
// For example, (X + Y) - Y -> X; (Y + X) - Y -> X
Value *X = nullptr, *Y = nullptr, *Z = Op1;
if (MaxRecurse && match(Op0, m_Add(m_Value(X), m_Value(Y)))) { // (X + Y) - Z
// See if "V === Y - Z" simplifies.
if (Value *V = simplifyBinOp(Instruction::Sub, Y, Z, Q, MaxRecurse - 1))
// It does! Now see if "X + V" simplifies.
if (Value *W = simplifyBinOp(Instruction::Add, X, V, Q, MaxRecurse - 1)) {
// It does, we successfully reassociated!
++NumReassoc;
return W;
}
// See if "V === X - Z" simplifies.
if (Value *V = simplifyBinOp(Instruction::Sub, X, Z, Q, MaxRecurse - 1))
// It does! Now see if "Y + V" simplifies.
if (Value *W = simplifyBinOp(Instruction::Add, Y, V, Q, MaxRecurse - 1)) {
// It does, we successfully reassociated!
++NumReassoc;
return W;
}
}
// X - (Y + Z) -> (X - Y) - Z or (X - Z) - Y if everything simplifies.
// For example, X - (X + 1) -> -1
X = Op0;
if (MaxRecurse && match(Op1, m_Add(m_Value(Y), m_Value(Z)))) { // X - (Y + Z)
// See if "V === X - Y" simplifies.
if (Value *V = simplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse - 1))
// It does! Now see if "V - Z" simplifies.
if (Value *W = simplifyBinOp(Instruction::Sub, V, Z, Q, MaxRecurse - 1)) {
// It does, we successfully reassociated!
++NumReassoc;
return W;
}
// See if "V === X - Z" simplifies.
if (Value *V = simplifyBinOp(Instruction::Sub, X, Z, Q, MaxRecurse - 1))
// It does! Now see if "V - Y" simplifies.
if (Value *W = simplifyBinOp(Instruction::Sub, V, Y, Q, MaxRecurse - 1)) {
// It does, we successfully reassociated!
++NumReassoc;
return W;
}
}
// Z - (X - Y) -> (Z - X) + Y if everything simplifies.
// For example, X - (X - Y) -> Y.
Z = Op0;
if (MaxRecurse && match(Op1, m_Sub(m_Value(X), m_Value(Y)))) // Z - (X - Y)
// See if "V === Z - X" simplifies.
if (Value *V = simplifyBinOp(Instruction::Sub, Z, X, Q, MaxRecurse - 1))
// It does! Now see if "V + Y" simplifies.
if (Value *W = simplifyBinOp(Instruction::Add, V, Y, Q, MaxRecurse - 1)) {
// It does, we successfully reassociated!
++NumReassoc;
return W;
}
// trunc(X) - trunc(Y) -> trunc(X - Y) if everything simplifies.
if (MaxRecurse && match(Op0, m_Trunc(m_Value(X))) &&
match(Op1, m_Trunc(m_Value(Y))))
if (X->getType() == Y->getType())
// See if "V === X - Y" simplifies.
if (Value *V = simplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse - 1))
// It does! Now see if "trunc V" simplifies.
if (Value *W = simplifyCastInst(Instruction::Trunc, V, Op0->getType(),
Q, MaxRecurse - 1))
// It does, return the simplified "trunc V".
return W;
// Variations on GEP(base, I, ...) - GEP(base, i, ...) -> GEP(null, I-i, ...).
if (match(Op0, m_PtrToInt(m_Value(X))) && match(Op1, m_PtrToInt(m_Value(Y))))
if (Constant *Result = computePointerDifference(Q.DL, X, Y))
return ConstantFoldIntegerCast(Result, Op0->getType(), /*IsSigned*/ true,
Q.DL);
// i1 sub -> xor.
if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1))
if (Value *V = simplifyXorInst(Op0, Op1, Q, MaxRecurse - 1))
return V;
// Threading Sub over selects and phi nodes is pointless, so don't bother.
// Threading over the select in "A - select(cond, B, C)" means evaluating
// "A-B" and "A-C" and seeing if they are equal; but they are equal if and
// only if B and C are equal. If B and C are equal then (since we assume
// that operands have already been simplified) "select(cond, B, C)" should
// have been simplified to the common value of B and C already. Analysing
// "A-B" and "A-C" thus gains nothing, but costs compile time. Similarly
// for threading over phi nodes.
if (Value *V = simplifyByDomEq(Instruction::Sub, Op0, Op1, Q, MaxRecurse))
return V;
return nullptr;
}
Value *llvm::simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q) {
return ::simplifySubInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
}
/// Given operands for a Mul, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Mul, Op0, Op1, Q))
return C;
// X * poison -> poison
if (isa<PoisonValue>(Op1))
return Op1;
// X * undef -> 0
// X * 0 -> 0
if (Q.isUndefValue(Op1) || match(Op1, m_Zero()))
return Constant::getNullValue(Op0->getType());
// X * 1 -> X
if (match(Op1, m_One()))
return Op0;
// (X / Y) * Y -> X if the division is exact.
Value *X = nullptr;
if (Q.IIQ.UseInstrInfo &&
(match(Op0,
m_Exact(m_IDiv(m_Value(X), m_Specific(Op1)))) || // (X / Y) * Y
match(Op1, m_Exact(m_IDiv(m_Value(X), m_Specific(Op0)))))) // Y * (X / Y)
return X;
if (Op0->getType()->isIntOrIntVectorTy(1)) {
// mul i1 nsw is a special-case because -1 * -1 is poison (+1 is not
// representable). All other cases reduce to 0, so just return 0.
if (IsNSW)
return ConstantInt::getNullValue(Op0->getType());
// Treat "mul i1" as "and i1".
if (MaxRecurse)
if (Value *V = simplifyAndInst(Op0, Op1, Q, MaxRecurse - 1))
return V;
}
// Try some generic simplifications for associative operations.
if (Value *V =
simplifyAssociativeBinOp(Instruction::Mul, Op0, Op1, Q, MaxRecurse))
return V;
// Mul distributes over Add. Try some generic simplifications based on this.
if (Value *V = expandCommutativeBinOp(Instruction::Mul, Op0, Op1,
Instruction::Add, Q, MaxRecurse))
return V;
// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
if (Value *V =
threadBinOpOverSelect(Instruction::Mul, Op0, Op1, Q, MaxRecurse))
return V;
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
if (Value *V =
threadBinOpOverPHI(Instruction::Mul, Op0, Op1, Q, MaxRecurse))
return V;
return nullptr;
}
Value *llvm::simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q) {
return ::simplifyMulInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
}
/// Given a predicate and two operands, return true if the comparison is true.
/// This is a helper for div/rem simplification where we return some other value
/// when we can prove a relationship between the operands.
static bool isICmpTrue(ICmpInst::Predicate Pred, Value *LHS, Value *RHS,
const SimplifyQuery &Q, unsigned MaxRecurse) {
Value *V = simplifyICmpInst(Pred, LHS, RHS, Q, MaxRecurse);
Constant *C = dyn_cast_or_null<Constant>(V);
return (C && C->isAllOnesValue());
}
/// Return true if we can simplify X / Y to 0. Remainder can adapt that answer
/// to simplify X % Y to X.
static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q,
unsigned MaxRecurse, bool IsSigned) {
// Recursion is always used, so bail out at once if we already hit the limit.
if (!MaxRecurse--)
return false;
if (IsSigned) {
// (X srem Y) sdiv Y --> 0
if (match(X, m_SRem(m_Value(), m_Specific(Y))))
return true;
// |X| / |Y| --> 0
//
// We require that 1 operand is a simple constant. That could be extended to
// 2 variables if we computed the sign bit for each.
//
// Make sure that a constant is not the minimum signed value because taking
// the abs() of that is undefined.
Type *Ty = X->getType();
const APInt *C;
if (match(X, m_APInt(C)) && !C->isMinSignedValue()) {
// Is the variable divisor magnitude always greater than the constant
// dividend magnitude?
// |Y| > |C| --> Y < -abs(C) or Y > abs(C)
Constant *PosDividendC = ConstantInt::get(Ty, C->abs());
Constant *NegDividendC = ConstantInt::get(Ty, -C->abs());
if (isICmpTrue(CmpInst::ICMP_SLT, Y, NegDividendC, Q, MaxRecurse) ||
isICmpTrue(CmpInst::ICMP_SGT, Y, PosDividendC, Q, MaxRecurse))
return true;
}
if (match(Y, m_APInt(C))) {
// Special-case: we can't take the abs() of a minimum signed value. If
// that's the divisor, then all we have to do is prove that the dividend
// is also not the minimum signed value.
if (C->isMinSignedValue())
return isICmpTrue(CmpInst::ICMP_NE, X, Y, Q, MaxRecurse);
// Is the variable dividend magnitude always less than the constant
// divisor magnitude?
// |X| < |C| --> X > -abs(C) and X < abs(C)
Constant *PosDivisorC = ConstantInt::get(Ty, C->abs());
Constant *NegDivisorC = ConstantInt::get(Ty, -C->abs());
if (isICmpTrue(CmpInst::ICMP_SGT, X, NegDivisorC, Q, MaxRecurse) &&
isICmpTrue(CmpInst::ICMP_SLT, X, PosDivisorC, Q, MaxRecurse))
return true;
}
return false;
}
// IsSigned == false.
// Is the unsigned dividend known to be less than a constant divisor?
// TODO: Convert this (and above) to range analysis
// ("computeConstantRangeIncludingKnownBits")?
const APInt *C;
if (match(Y, m_APInt(C)) &&
computeKnownBits(X, /* Depth */ 0, Q).getMaxValue().ult(*C))
return true;
// Try again for any divisor:
// Is the dividend unsigned less than the divisor?
return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
}
/// Check for common or similar folds of integer division or integer remainder.
/// This applies to all 4 opcodes (sdiv/udiv/srem/urem).
static Value *simplifyDivRem(Instruction::BinaryOps Opcode, Value *Op0,
Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
bool IsDiv = (Opcode == Instruction::SDiv || Opcode == Instruction::UDiv);
bool IsSigned = (Opcode == Instruction::SDiv || Opcode == Instruction::SRem);
Type *Ty = Op0->getType();
// X / undef -> poison
// X % undef -> poison
if (Q.isUndefValue(Op1) || isa<PoisonValue>(Op1))
return PoisonValue::get(Ty);
// X / 0 -> poison
// X % 0 -> poison
// We don't need to preserve faults!
if (match(Op1, m_Zero()))
return PoisonValue::get(Ty);
// If any element of a constant divisor fixed width vector is zero or undef
// the behavior is undefined and we can fold the whole op to poison.
auto *Op1C = dyn_cast<Constant>(Op1);
auto *VTy = dyn_cast<FixedVectorType>(Ty);
if (Op1C && VTy) {
unsigned NumElts = VTy->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = Op1C->getAggregateElement(i);
if (Elt && (Elt->isNullValue() || Q.isUndefValue(Elt)))
return PoisonValue::get(Ty);
}
}
// poison / X -> poison
// poison % X -> poison
if (isa<PoisonValue>(Op0))
return Op0;
// undef / X -> 0
// undef % X -> 0
if (Q.isUndefValue(Op0))
return Constant::getNullValue(Ty);
// 0 / X -> 0
// 0 % X -> 0
if (match(Op0, m_Zero()))
return Constant::getNullValue(Op0->getType());
// X / X -> 1
// X % X -> 0
if (Op0 == Op1)
return IsDiv ? ConstantInt::get(Ty, 1) : Constant::getNullValue(Ty);
KnownBits Known = computeKnownBits(Op1, /* Depth */ 0, Q);
// X / 0 -> poison
// X % 0 -> poison
// If the divisor is known to be zero, just return poison. This can happen in
// some cases where its provable indirectly the denominator is zero but it's
// not trivially simplifiable (i.e known zero through a phi node).
if (Known.isZero())
return PoisonValue::get(Ty);
// X / 1 -> X
// X % 1 -> 0
// If the divisor can only be zero or one, we can't have division-by-zero
// or remainder-by-zero, so assume the divisor is 1.
// e.g. 1, zext (i8 X), sdiv X (Y and 1)
if (Known.countMinLeadingZeros() == Known.getBitWidth() - 1)
return IsDiv ? Op0 : Constant::getNullValue(Ty);
// If X * Y does not overflow, then:
// X * Y / Y -> X
// X * Y % Y -> 0
Value *X;
if (match(Op0, m_c_Mul(m_Value(X), m_Specific(Op1)))) {
auto *Mul = cast<OverflowingBinaryOperator>(Op0);
// The multiplication can't overflow if it is defined not to, or if
// X == A / Y for some A.
if ((IsSigned && Q.IIQ.hasNoSignedWrap(Mul)) ||
(!IsSigned && Q.IIQ.hasNoUnsignedWrap(Mul)) ||
(IsSigned && match(X, m_SDiv(m_Value(), m_Specific(Op1)))) ||
(!IsSigned && match(X, m_UDiv(m_Value(), m_Specific(Op1))))) {
return IsDiv ? X : Constant::getNullValue(Op0->getType());
}
}
if (isDivZero(Op0, Op1, Q, MaxRecurse, IsSigned))
return IsDiv ? Constant::getNullValue(Op0->getType()) : Op0;
if (Value *V = simplifyByDomEq(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
if (Value *V = threadBinOpOverSelect(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
if (Value *V = threadBinOpOverPHI(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
return nullptr;
}
/// These are simplifications common to SDiv and UDiv.
static Value *simplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
bool IsExact, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
if (Value *V = simplifyDivRem(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
const APInt *DivC;
if (IsExact && match(Op1, m_APInt(DivC))) {
// If this is an exact divide by a constant, then the dividend (Op0) must
// have at least as many trailing zeros as the divisor to divide evenly. If
// it has less trailing zeros, then the result must be poison.
if (DivC->countr_zero()) {
KnownBits KnownOp0 = computeKnownBits(Op0, /* Depth */ 0, Q);
if (KnownOp0.countMaxTrailingZeros() < DivC->countr_zero())
return PoisonValue::get(Op0->getType());
}
// udiv exact (mul nsw X, C), C --> X
// sdiv exact (mul nuw X, C), C --> X
// where C is not a power of 2.
Value *X;
if (!DivC->isPowerOf2() &&
(Opcode == Instruction::UDiv
? match(Op0, m_NSWMul(m_Value(X), m_Specific(Op1)))
: match(Op0, m_NUWMul(m_Value(X), m_Specific(Op1)))))
return X;
}
return nullptr;
}
/// These are simplifications common to SRem and URem.
static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
if (Value *V = simplifyDivRem(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
// (X << Y) % X -> 0
if (Q.IIQ.UseInstrInfo &&
((Opcode == Instruction::SRem &&
match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
(Opcode == Instruction::URem &&
match(Op0, m_NUWShl(m_Specific(Op1), m_Value())))))
return Constant::getNullValue(Op0->getType());
return nullptr;
}
/// Given operands for an SDiv, see if we can fold the result.
/// If not, this returns null.
static Value *simplifySDivInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q, unsigned MaxRecurse) {
// If two operands are negated and no signed overflow, return -1.
if (isKnownNegation(Op0, Op1, /*NeedNSW=*/true))
return Constant::getAllOnesValue(Op0->getType());
return simplifyDiv(Instruction::SDiv, Op0, Op1, IsExact, Q, MaxRecurse);
}
Value *llvm::simplifySDivInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q) {
return ::simplifySDivInst(Op0, Op1, IsExact, Q, RecursionLimit);
}
/// Given operands for a UDiv, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyUDivInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q, unsigned MaxRecurse) {
return simplifyDiv(Instruction::UDiv, Op0, Op1, IsExact, Q, MaxRecurse);
}
Value *llvm::simplifyUDivInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q) {
return ::simplifyUDivInst(Op0, Op1, IsExact, Q, RecursionLimit);
}
/// Given operands for an SRem, see if we can fold the result.
/// If not, this returns null.
static Value *simplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
// If the divisor is 0, the result is undefined, so assume the divisor is -1.
// srem Op0, (sext i1 X) --> srem Op0, -1 --> 0
Value *X;
if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
return ConstantInt::getNullValue(Op0->getType());
// If the two operands are negated, return 0.
if (isKnownNegation(Op0, Op1))
return ConstantInt::getNullValue(Op0->getType());
return simplifyRem(Instruction::SRem, Op0, Op1, Q, MaxRecurse);
}
Value *llvm::simplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
return ::simplifySRemInst(Op0, Op1, Q, RecursionLimit);
}
/// Given operands for a URem, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
return simplifyRem(Instruction::URem, Op0, Op1, Q, MaxRecurse);
}
Value *llvm::simplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
return ::simplifyURemInst(Op0, Op1, Q, RecursionLimit);
}
/// Returns true if a shift by \c Amount always yields poison.
static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q) {
Constant *C = dyn_cast<Constant>(Amount);
if (!C)
return false;
// X shift by undef -> poison because it may shift by the bitwidth.
if (Q.isUndefValue(C))
return true;
// Shifting by the bitwidth or more is poison. This covers scalars and
// fixed/scalable vectors with splat constants.
const APInt *AmountC;
if (match(C, m_APInt(AmountC)) && AmountC->uge(AmountC->getBitWidth()))
return true;
// Try harder for fixed-length vectors:
// If all lanes of a vector shift are poison, the whole shift is poison.
if (isa<ConstantVector>(C) || isa<ConstantDataVector>(C)) {
for (unsigned I = 0,
E = cast<FixedVectorType>(C->getType())->getNumElements();
I != E; ++I)
if (!isPoisonShift(C->getAggregateElement(I), Q))
return false;
return true;
}
return false;
}
/// Given operands for an Shl, LShr or AShr, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
Value *Op1, bool IsNSW, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Opcode, Op0, Op1, Q))
return C;
// poison shift by X -> poison
if (isa<PoisonValue>(Op0))
return Op0;
// 0 shift by X -> 0
if (match(Op0, m_Zero()))
return Constant::getNullValue(Op0->getType());
// X shift by 0 -> X
// Shift-by-sign-extended bool must be shift-by-0 because shift-by-all-ones
// would be poison.
Value *X;
if (match(Op1, m_Zero()) ||
(match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)))
return Op0;
// Fold undefined shifts.
if (isPoisonShift(Op1, Q))
return PoisonValue::get(Op0->getType());
// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
if (Value *V = threadBinOpOverSelect(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
if (Value *V = threadBinOpOverPHI(Opcode, Op0, Op1, Q, MaxRecurse))
return V;
// If any bits in the shift amount make that value greater than or equal to
// the number of bits in the type, the shift is undefined.
KnownBits KnownAmt = computeKnownBits(Op1, /* Depth */ 0, Q);
if (KnownAmt.getMinValue().uge(KnownAmt.getBitWidth()))
return PoisonValue::get(Op0->getType());
// If all valid bits in the shift amount are known zero, the first operand is
// unchanged.
unsigned NumValidShiftBits = Log2_32_Ceil(KnownAmt.getBitWidth());
if (KnownAmt.countMinTrailingZeros() >= NumValidShiftBits)
return Op0;
// Check for nsw shl leading to a poison value.
if (IsNSW) {
assert(Opcode == Instruction::Shl && "Expected shl for nsw instruction");
KnownBits KnownVal = computeKnownBits(Op0, /* Depth */ 0, Q);
KnownBits KnownShl = KnownBits::shl(KnownVal, KnownAmt);
if (KnownVal.Zero.isSignBitSet())
KnownShl.Zero.setSignBit();
if (KnownVal.One.isSignBitSet())
KnownShl.One.setSignBit();
if (KnownShl.hasConflict())
return PoisonValue::get(Op0->getType());
}
return nullptr;
}
/// Given operands for an LShr or AShr, see if we can fold the result. If not,
/// this returns null.
static Value *simplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0,
Value *Op1, bool IsExact,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V =
simplifyShift(Opcode, Op0, Op1, /*IsNSW*/ false, Q, MaxRecurse))
return V;
// X >> X -> 0
if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
// undef >> X -> 0
// undef >> X -> undef (if it's exact)
if (Q.isUndefValue(Op0))
return IsExact ? Op0 : Constant::getNullValue(Op0->getType());
// The low bit cannot be shifted out of an exact shift if it is set.
// TODO: Generalize by counting trailing zeros (see fold for exact division).
if (IsExact) {
KnownBits Op0Known = computeKnownBits(Op0, /* Depth */ 0, Q);
if (Op0Known.One[0])
return Op0;
}
return nullptr;
}
/// Given operands for an Shl, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V =
simplifyShift(Instruction::Shl, Op0, Op1, IsNSW, Q, MaxRecurse))
return V;
Type *Ty = Op0->getType();
// undef << X -> 0
// undef << X -> undef if (if it's NSW/NUW)
if (Q.isUndefValue(Op0))
return IsNSW || IsNUW ? Op0 : Constant::getNullValue(Ty);
// (X >> A) << A -> X
Value *X;
if (Q.IIQ.UseInstrInfo &&
match(Op0, m_Exact(m_Shr(m_Value(X), m_Specific(Op1)))))
return X;
// shl nuw i8 C, %x -> C iff C has sign bit set.
if (IsNUW && match(Op0, m_Negative()))
return Op0;
// NOTE: could use computeKnownBits() / LazyValueInfo,
// but the cost-benefit analysis suggests it isn't worth it.
// "nuw" guarantees that only zeros are shifted out, and "nsw" guarantees
// that the sign-bit does not change, so the only input that does not
// produce poison is 0, and "0 << (bitwidth-1) --> 0".
if (IsNSW && IsNUW &&
match(Op1, m_SpecificInt(Ty->getScalarSizeInBits() - 1)))
return Constant::getNullValue(Ty);
return nullptr;
}
Value *llvm::simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
const SimplifyQuery &Q) {
return ::simplifyShlInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);
}
/// Given operands for an LShr, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V = simplifyRightShift(Instruction::LShr, Op0, Op1, IsExact, Q,
MaxRecurse))
return V;
// (X << A) >> A -> X
Value *X;
if (Q.IIQ.UseInstrInfo && match(Op0, m_NUWShl(m_Value(X), m_Specific(Op1))))
return X;
// ((X << A) | Y) >> A -> X if effective width of Y is not larger than A.
// We can return X as we do in the above case since OR alters no bits in X.
// SimplifyDemandedBits in InstCombine can do more general optimization for
// bit manipulation. This pattern aims to provide opportunities for other
// optimizers by supporting a simple but common case in InstSimplify.
Value *Y;
const APInt *ShRAmt, *ShLAmt;
if (Q.IIQ.UseInstrInfo && match(Op1, m_APInt(ShRAmt)) &&
match(Op0, m_c_Or(m_NUWShl(m_Value(X), m_APInt(ShLAmt)), m_Value(Y))) &&
*ShRAmt == *ShLAmt) {
const KnownBits YKnown = computeKnownBits(Y, /* Depth */ 0, Q);
const unsigned EffWidthY = YKnown.countMaxActiveBits();
if (ShRAmt->uge(EffWidthY))
return X;
}
return nullptr;
}
Value *llvm::simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q) {
return ::simplifyLShrInst(Op0, Op1, IsExact, Q, RecursionLimit);
}
/// Given operands for an AShr, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q, unsigned MaxRecurse) {
if (Value *V = simplifyRightShift(Instruction::AShr, Op0, Op1, IsExact, Q,
MaxRecurse))
return V;
// -1 >>a X --> -1
// (-1 << X) a>> X --> -1
// Do not return Op0 because it may contain undef elements if it's a vector.
if (match(Op0, m_AllOnes()) ||
match(Op0, m_Shl(m_AllOnes(), m_Specific(Op1))))
return Constant::getAllOnesValue(Op0->getType());
// (X << A) >> A -> X
Value *X;
if (Q.IIQ.UseInstrInfo && match(Op0, m_NSWShl(m_Value(X), m_Specific(Op1))))
return X;
// Arithmetic shifting an all-sign-bit value is a no-op.
unsigned NumSignBits = ComputeNumSignBits(Op0, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
if (NumSignBits == Op0->getType()->getScalarSizeInBits())
return Op0;
return nullptr;
}
Value *llvm::simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact,
const SimplifyQuery &Q) {
return ::simplifyAShrInst(Op0, Op1, IsExact, Q, RecursionLimit);
}
/// Commuted variants are assumed to be handled by calling this function again
/// with the parameters swapped.
static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
ICmpInst *UnsignedICmp, bool IsAnd,
const SimplifyQuery &Q) {
Value *X, *Y;
ICmpInst::Predicate EqPred;
if (!match(ZeroICmp, m_ICmp(EqPred, m_Value(Y), m_Zero())) ||
!ICmpInst::isEquality(EqPred))
return nullptr;
ICmpInst::Predicate UnsignedPred;
Value *A, *B;
// Y = (A - B);
if (match(Y, m_Sub(m_Value(A), m_Value(B)))) {
if (match(UnsignedICmp,
m_c_ICmp(UnsignedPred, m_Specific(A), m_Specific(B))) &&
ICmpInst::isUnsigned(UnsignedPred)) {
// A >=/<= B || (A - B) != 0 <--> true
if ((UnsignedPred == ICmpInst::ICMP_UGE ||
UnsignedPred == ICmpInst::ICMP_ULE) &&
EqPred == ICmpInst::ICMP_NE && !IsAnd)
return ConstantInt::getTrue(UnsignedICmp->getType());
// A </> B && (A - B) == 0 <--> false
if ((UnsignedPred == ICmpInst::ICMP_ULT ||
UnsignedPred == ICmpInst::ICMP_UGT) &&
EqPred == ICmpInst::ICMP_EQ && IsAnd)
return ConstantInt::getFalse(UnsignedICmp->getType());
// A </> B && (A - B) != 0 <--> A </> B
// A </> B || (A - B) != 0 <--> (A - B) != 0
if (EqPred == ICmpInst::ICMP_NE && (UnsignedPred == ICmpInst::ICMP_ULT ||
UnsignedPred == ICmpInst::ICMP_UGT))
return IsAnd ? UnsignedICmp : ZeroICmp;
// A <=/>= B && (A - B) == 0 <--> (A - B) == 0
// A <=/>= B || (A - B) == 0 <--> A <=/>= B
if (EqPred == ICmpInst::ICMP_EQ && (UnsignedPred == ICmpInst::ICMP_ULE ||
UnsignedPred == ICmpInst::ICMP_UGE))
return IsAnd ? ZeroICmp : UnsignedICmp;
}
// Given Y = (A - B)
// Y >= A && Y != 0 --> Y >= A iff B != 0
// Y < A || Y == 0 --> Y < A iff B != 0
if (match(UnsignedICmp,
m_c_ICmp(UnsignedPred, m_Specific(Y), m_Specific(A)))) {
if (UnsignedPred == ICmpInst::ICMP_UGE && IsAnd &&
EqPred == ICmpInst::ICMP_NE && isKnownNonZero(B, /*Depth=*/0, Q))
return UnsignedICmp;
if (UnsignedPred == ICmpInst::ICMP_ULT && !IsAnd &&
EqPred == ICmpInst::ICMP_EQ && isKnownNonZero(B, /*Depth=*/0, Q))
return UnsignedICmp;
}
}
if (match(UnsignedICmp, m_ICmp(UnsignedPred, m_Value(X), m_Specific(Y))) &&
ICmpInst::isUnsigned(UnsignedPred))
;
else if (match(UnsignedICmp,
m_ICmp(UnsignedPred, m_Specific(Y), m_Value(X))) &&
ICmpInst::isUnsigned(UnsignedPred))
UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
else
return nullptr;
// X > Y && Y == 0 --> Y == 0 iff X != 0
// X > Y || Y == 0 --> X > Y iff X != 0
if (UnsignedPred == ICmpInst::ICMP_UGT && EqPred == ICmpInst::ICMP_EQ &&
isKnownNonZero(X, /*Depth=*/0, Q))
return IsAnd ? ZeroICmp : UnsignedICmp;
// X <= Y && Y != 0 --> X <= Y iff X != 0
// X <= Y || Y != 0 --> Y != 0 iff X != 0
if (UnsignedPred == ICmpInst::ICMP_ULE && EqPred == ICmpInst::ICMP_NE &&
isKnownNonZero(X, /*Depth=*/0, Q))
return IsAnd ? UnsignedICmp : ZeroICmp;
// The transforms below here are expected to be handled more generally with
// simplifyAndOrOfICmpsWithLimitConst() or in InstCombine's
// foldAndOrOfICmpsWithConstEq(). If we are looking to trim optimizer overlap,
// these are candidates for removal.
// X < Y && Y != 0 --> X < Y
// X < Y || Y != 0 --> Y != 0
if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_NE)
return IsAnd ? UnsignedICmp : ZeroICmp;
// X >= Y && Y == 0 --> Y == 0
// X >= Y || Y == 0 --> X >= Y
if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_EQ)
return IsAnd ? ZeroICmp : UnsignedICmp;
// X < Y && Y == 0 --> false
if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_EQ &&
IsAnd)
return getFalse(UnsignedICmp->getType());
// X >= Y || Y != 0 --> true
if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_NE &&
!IsAnd)
return getTrue(UnsignedICmp->getType());
return nullptr;
}
/// Test if a pair of compares with a shared operand and 2 constants has an
/// empty set intersection, full set union, or if one compare is a superset of
/// the other.
static Value *simplifyAndOrOfICmpsWithConstants(ICmpInst *Cmp0, ICmpInst *Cmp1,
bool IsAnd) {
// Look for this pattern: {and/or} (icmp X, C0), (icmp X, C1)).
if (Cmp0->getOperand(0) != Cmp1->getOperand(0))
return nullptr;
const APInt *C0, *C1;
if (!match(Cmp0->getOperand(1), m_APInt(C0)) ||
!match(Cmp1->getOperand(1), m_APInt(C1)))
return nullptr;
auto Range0 = ConstantRange::makeExactICmpRegion(Cmp0->getPredicate(), *C0);
auto Range1 = ConstantRange::makeExactICmpRegion(Cmp1->getPredicate(), *C1);
// For and-of-compares, check if the intersection is empty:
// (icmp X, C0) && (icmp X, C1) --> empty set --> false
if (IsAnd && Range0.intersectWith(Range1).isEmptySet())
return getFalse(Cmp0->getType());
// For or-of-compares, check if the union is full:
// (icmp X, C0) || (icmp X, C1) --> full set --> true
if (!IsAnd && Range0.unionWith(Range1).isFullSet())
return getTrue(Cmp0->getType());
// Is one range a superset of the other?
// If this is and-of-compares, take the smaller set:
// (icmp sgt X, 4) && (icmp sgt X, 42) --> icmp sgt X, 42
// If this is or-of-compares, take the larger set:
// (icmp sgt X, 4) || (icmp sgt X, 42) --> icmp sgt X, 4
if (Range0.contains(Range1))
return IsAnd ? Cmp1 : Cmp0;
if (Range1.contains(Range0))
return IsAnd ? Cmp0 : Cmp1;
return nullptr;
}
static Value *simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1,
const InstrInfoQuery &IIQ) {
// (icmp (add V, C0), C1) & (icmp V, C0)
ICmpInst::Predicate Pred0, Pred1;
const APInt *C0, *C1;
Value *V;
if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_APInt(C0)), m_APInt(C1))))
return nullptr;
if (!match(Op1, m_ICmp(Pred1, m_Specific(V), m_Value())))
return nullptr;
auto *AddInst = cast<OverflowingBinaryOperator>(Op0->getOperand(0));
if (AddInst->getOperand(1) != Op1->getOperand(1))
return nullptr;
Type *ITy = Op0->getType();
bool IsNSW = IIQ.hasNoSignedWrap(AddInst);
bool IsNUW = IIQ.hasNoUnsignedWrap(AddInst);
const APInt Delta = *C1 - *C0;
if (C0->isStrictlyPositive()) {
if (Delta == 2) {
if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_SGT)
return getFalse(ITy);
if (Pred0 == ICmpInst::ICMP_SLT && Pred1 == ICmpInst::ICMP_SGT && IsNSW)
return getFalse(ITy);
}
if (Delta == 1) {
if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_SGT)
return getFalse(ITy);
if (Pred0 == ICmpInst::ICMP_SLE && Pred1 == ICmpInst::ICMP_SGT && IsNSW)
return getFalse(ITy);
}
}
if (C0->getBoolValue() && IsNUW) {
if (Delta == 2)
if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_UGT)
return getFalse(ITy);
if (Delta == 1)
if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_UGT)
return getFalse(ITy);
}
return nullptr;
}
/// Try to simplify and/or of icmp with ctpop intrinsic.
static Value *simplifyAndOrOfICmpsWithCtpop(ICmpInst *Cmp0, ICmpInst *Cmp1,
bool IsAnd) {
ICmpInst::Predicate Pred0, Pred1;
Value *X;
const APInt *C;
if (!match(Cmp0, m_ICmp(Pred0, m_Intrinsic<Intrinsic::ctpop>(m_Value(X)),
m_APInt(C))) ||
!match(Cmp1, m_ICmp(Pred1, m_Specific(X), m_ZeroInt())) || C->isZero())
return nullptr;
// (ctpop(X) == C) || (X != 0) --> X != 0 where C > 0
if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_NE)
return Cmp1;
// (ctpop(X) != C) && (X == 0) --> X == 0 where C > 0
if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_EQ)
return Cmp1;
return nullptr;
}
static Value *simplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1,
const SimplifyQuery &Q) {
if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/true, Q))
return X;
if (Value *X = simplifyUnsignedRangeCheck(Op1, Op0, /*IsAnd=*/true, Q))
return X;
if (Value *X = simplifyAndOrOfICmpsWithConstants(Op0, Op1, true))
return X;
if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op0, Op1, true))
return X;
if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op1, Op0, true))
return X;
if (Value *X = simplifyAndOfICmpsWithAdd(Op0, Op1, Q.IIQ))
return X;
if (Value *X = simplifyAndOfICmpsWithAdd(Op1, Op0, Q.IIQ))
return X;
return nullptr;
}
static Value *simplifyOrOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1,
const InstrInfoQuery &IIQ) {
// (icmp (add V, C0), C1) | (icmp V, C0)
ICmpInst::Predicate Pred0, Pred1;
const APInt *C0, *C1;
Value *V;
if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_APInt(C0)), m_APInt(C1))))
return nullptr;
if (!match(Op1, m_ICmp(Pred1, m_Specific(V), m_Value())))
return nullptr;
auto *AddInst = cast<BinaryOperator>(Op0->getOperand(0));
if (AddInst->getOperand(1) != Op1->getOperand(1))
return nullptr;
Type *ITy = Op0->getType();
bool IsNSW = IIQ.hasNoSignedWrap(AddInst);
bool IsNUW = IIQ.hasNoUnsignedWrap(AddInst);
const APInt Delta = *C1 - *C0;
if (C0->isStrictlyPositive()) {
if (Delta == 2) {
if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_SLE)
return getTrue(ITy);
if (Pred0 == ICmpInst::ICMP_SGE && Pred1 == ICmpInst::ICMP_SLE && IsNSW)
return getTrue(ITy);
}
if (Delta == 1) {
if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_SLE)
return getTrue(ITy);
if (Pred0 == ICmpInst::ICMP_SGT && Pred1 == ICmpInst::ICMP_SLE && IsNSW)
return getTrue(ITy);
}
}
if (C0->getBoolValue() && IsNUW) {
if (Delta == 2)
if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_ULE)
return getTrue(ITy);
if (Delta == 1)
if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_ULE)
return getTrue(ITy);
}
return nullptr;
}
static Value *simplifyOrOfICmps(ICmpInst *Op0, ICmpInst *Op1,
const SimplifyQuery &Q) {
if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/false, Q))
return X;
if (Value *X = simplifyUnsignedRangeCheck(Op1, Op0, /*IsAnd=*/false, Q))
return X;
if (Value *X = simplifyAndOrOfICmpsWithConstants(Op0, Op1, false))
return X;
if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op0, Op1, false))
return X;
if (Value *X = simplifyAndOrOfICmpsWithCtpop(Op1, Op0, false))
return X;
if (Value *X = simplifyOrOfICmpsWithAdd(Op0, Op1, Q.IIQ))
return X;
if (Value *X = simplifyOrOfICmpsWithAdd(Op1, Op0, Q.IIQ))
return X;
return nullptr;
}
static Value *simplifyAndOrOfFCmps(const SimplifyQuery &Q, FCmpInst *LHS,
FCmpInst *RHS, bool IsAnd) {
Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
if (LHS0->getType() != RHS0->getType())
return nullptr;
FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
if ((PredL == FCmpInst::FCMP_ORD || PredL == FCmpInst::FCMP_UNO) &&
((FCmpInst::isOrdered(PredR) && IsAnd) ||
(FCmpInst::isUnordered(PredR) && !IsAnd))) {
// (fcmp ord X, NNAN) & (fcmp o** X, Y) --> fcmp o** X, Y
// (fcmp uno X, NNAN) & (fcmp o** X, Y) --> false
// (fcmp uno X, NNAN) | (fcmp u** X, Y) --> fcmp u** X, Y
// (fcmp ord X, NNAN) | (fcmp u** X, Y) --> true
if (((LHS1 == RHS0 || LHS1 == RHS1) &&
isKnownNeverNaN(LHS0, /*Depth=*/0, Q)) ||
((LHS0 == RHS0 || LHS0 == RHS1) &&
isKnownNeverNaN(LHS1, /*Depth=*/0, Q)))
return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
? static_cast<Value *>(RHS)
: ConstantInt::getBool(LHS->getType(), !IsAnd);
}
if ((PredR == FCmpInst::FCMP_ORD || PredR == FCmpInst::FCMP_UNO) &&
((FCmpInst::isOrdered(PredL) && IsAnd) ||
(FCmpInst::isUnordered(PredL) && !IsAnd))) {
// (fcmp o** X, Y) & (fcmp ord X, NNAN) --> fcmp o** X, Y
// (fcmp o** X, Y) & (fcmp uno X, NNAN) --> false
// (fcmp u** X, Y) | (fcmp uno X, NNAN) --> fcmp u** X, Y
// (fcmp u** X, Y) | (fcmp ord X, NNAN) --> true
if (((RHS1 == LHS0 || RHS1 == LHS1) &&
isKnownNeverNaN(RHS0, /*Depth=*/0, Q)) ||
((RHS0 == LHS0 || RHS0 == LHS1) &&
isKnownNeverNaN(RHS1, /*Depth=*/0, Q)))
return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
? static_cast<Value *>(LHS)
: ConstantInt::getBool(LHS->getType(), !IsAnd);
}
return nullptr;
}
static Value *simplifyAndOrOfCmps(const SimplifyQuery &Q, Value *Op0,
Value *Op1, bool IsAnd) {
// Look through casts of the 'and' operands to find compares.
auto *Cast0 = dyn_cast<CastInst>(Op0);
auto *Cast1 = dyn_cast<CastInst>(Op1);
if (Cast0 && Cast1 && Cast0->getOpcode() == Cast1->getOpcode() &&
Cast0->getSrcTy() == Cast1->getSrcTy()) {
Op0 = Cast0->getOperand(0);
Op1 = Cast1->getOperand(0);
}
Value *V = nullptr;
auto *ICmp0 = dyn_cast<ICmpInst>(Op0);
auto *ICmp1 = dyn_cast<ICmpInst>(Op1);
if (ICmp0 && ICmp1)
V = IsAnd ? simplifyAndOfICmps(ICmp0, ICmp1, Q)
: simplifyOrOfICmps(ICmp0, ICmp1, Q);
auto *FCmp0 = dyn_cast<FCmpInst>(Op0);
auto *FCmp1 = dyn_cast<FCmpInst>(Op1);
if (FCmp0 && FCmp1)
V = simplifyAndOrOfFCmps(Q, FCmp0, FCmp1, IsAnd);
if (!V)
return nullptr;
if (!Cast0)
return V;
// If we looked through casts, we can only handle a constant simplification
// because we are not allowed to create a cast instruction here.
if (auto *C = dyn_cast<Constant>(V))
return ConstantFoldCastOperand(Cast0->getOpcode(), C, Cast0->getType(),
Q.DL);
return nullptr;
}
static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
const SimplifyQuery &Q,
bool AllowRefinement,
SmallVectorImpl<Instruction *> *DropFlags,
unsigned MaxRecurse);
static Value *simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
"Must be and/or");
ICmpInst::Predicate Pred;
Value *A, *B;
if (!match(Op0, m_ICmp(Pred, m_Value(A), m_Value(B))) ||
!ICmpInst::isEquality(Pred))
return nullptr;
auto Simplify = [&](Value *Res) -> Value * {
Constant *Absorber = ConstantExpr::getBinOpAbsorber(Opcode, Res->getType());
// and (icmp eq a, b), x implies (a==b) inside x.
// or (icmp ne a, b), x implies (a==b) inside x.
// If x simplifies to true/false, we can simplify the and/or.
if (Pred ==
(Opcode == Instruction::And ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE)) {
if (Res == Absorber)
return Absorber;
if (Res == ConstantExpr::getBinOpIdentity(Opcode, Res->getType()))
return Op0;
return nullptr;
}
// If we have and (icmp ne a, b), x and for a==b we can simplify x to false,
// then we can drop the icmp, as x will already be false in the case where
// the icmp is false. Similar for or and true.
if (Res == Absorber)
return Op1;
return nullptr;
};
if (Value *Res =
simplifyWithOpReplaced(Op1, A, B, Q, /* AllowRefinement */ true,
/* DropFlags */ nullptr, MaxRecurse))
return Simplify(Res);
if (Value *Res =
simplifyWithOpReplaced(Op1, B, A, Q, /* AllowRefinement */ true,
/* DropFlags */ nullptr, MaxRecurse))
return Simplify(Res);
return nullptr;
}
/// Given a bitwise logic op, check if the operands are add/sub with a common
/// source value and inverted constant (identity: C - X -> ~(X + ~C)).
static Value *simplifyLogicOfAddSub(Value *Op0, Value *Op1,
Instruction::BinaryOps Opcode) {
assert(Op0->getType() == Op1->getType() && "Mismatched binop types");
assert(BinaryOperator::isBitwiseLogicOp(Opcode) && "Expected logic op");
Value *X;
Constant *C1, *C2;
if ((match(Op0, m_Add(m_Value(X), m_Constant(C1))) &&
match(Op1, m_Sub(m_Constant(C2), m_Specific(X)))) ||
(match(Op1, m_Add(m_Value(X), m_Constant(C1))) &&
match(Op0, m_Sub(m_Constant(C2), m_Specific(X))))) {
if (ConstantExpr::getNot(C1) == C2) {
// (X + C) & (~C - X) --> (X + C) & ~(X + C) --> 0
// (X + C) | (~C - X) --> (X + C) | ~(X + C) --> -1
// (X + C) ^ (~C - X) --> (X + C) ^ ~(X + C) --> -1
Type *Ty = Op0->getType();
return Opcode == Instruction::And ? ConstantInt::getNullValue(Ty)
: ConstantInt::getAllOnesValue(Ty);
}
}
return nullptr;
}
// Commutative patterns for and that will be tried with both operand orders.
static Value *simplifyAndCommutative(Value *Op0, Value *Op1,
const SimplifyQuery &Q,
unsigned MaxRecurse) {
// ~A & A = 0
if (match(Op0, m_Not(m_Specific(Op1))))
return Constant::getNullValue(Op0->getType());
// (A | ?) & A = A
if (match(Op0, m_c_Or(m_Specific(Op1), m_Value())))
return Op1;
// (X | ~Y) & (X | Y) --> X
Value *X, *Y;
if (match(Op0, m_c_Or(m_Value(X), m_Not(m_Value(Y)))) &&
match(Op1, m_c_Or(m_Deferred(X), m_Deferred(Y))))
return X;
// If we have a multiplication overflow check that is being 'and'ed with a
// check that one of the multipliers is not zero, we can omit the 'and', and
// only keep the overflow check.
if (isCheckForZeroAndMulWithOverflow(Op0, Op1, true))
return Op1;
// -A & A = A if A is a power of two or zero.
if (match(Op0, m_Neg(m_Specific(Op1))) &&
isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
return Op1;
// This is a similar pattern used for checking if a value is a power-of-2:
// (A - 1) & A --> 0 (if A is a power-of-2 or 0)
if (match(Op0, m_Add(m_Specific(Op1), m_AllOnes())) &&
isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
return Constant::getNullValue(Op1->getType());
// (x << N) & ((x << M) - 1) --> 0, where x is known to be a power of 2 and
// M <= N.
const APInt *Shift1, *Shift2;
if (match(Op0, m_Shl(m_Value(X), m_APInt(Shift1))) &&
match(Op1, m_Add(m_Shl(m_Specific(X), m_APInt(Shift2)), m_AllOnes())) &&
isKnownToBeAPowerOfTwo(X, Q.DL, /*OrZero*/ true, /*Depth*/ 0, Q.AC,
Q.CxtI) &&
Shift1->uge(*Shift2))
return Constant::getNullValue(Op0->getType());
if (Value *V =
simplifyAndOrWithICmpEq(Instruction::And, Op0, Op1, Q, MaxRecurse))
return V;
return nullptr;
}
/// Given operands for an And, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::And, Op0, Op1, Q))
return C;
// X & poison -> poison
if (isa<PoisonValue>(Op1))
return Op1;
// X & undef -> 0
if (Q.isUndefValue(Op1))
return Constant::getNullValue(Op0->getType());
// X & X = X
if (Op0 == Op1)
return Op0;
// X & 0 = 0
if (match(Op1, m_Zero()))
return Constant::getNullValue(Op0->getType());
// X & -1 = X
if (match(Op1, m_AllOnes()))
return Op0;
if (Value *Res = simplifyAndCommutative(Op0, Op1, Q, MaxRecurse))
return Res;
if (Value *Res = simplifyAndCommutative(Op1, Op0, Q, MaxRecurse))
return Res;
if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::And))
return V;
// A mask that only clears known zeros of a shifted value is a no-op.
const APInt *Mask;
const APInt *ShAmt;
Value *X, *Y;
if (match(Op1, m_APInt(Mask))) {
// If all bits in the inverted and shifted mask are clear:
// and (shl X, ShAmt), Mask --> shl X, ShAmt
if (match(Op0, m_Shl(m_Value(X), m_APInt(ShAmt))) &&
(~(*Mask)).lshr(*ShAmt).isZero())
return Op0;
// If all bits in the inverted and shifted mask are clear:
// and (lshr X, ShAmt), Mask --> lshr X, ShAmt
if (match(Op0, m_LShr(m_Value(X), m_APInt(ShAmt))) &&
(~(*Mask)).shl(*ShAmt).isZero())
return Op0;
}
// and 2^x-1, 2^C --> 0 where x <= C.
const APInt *PowerC;
Value *Shift;
if (match(Op1, m_Power2(PowerC)) &&
match(Op0, m_Add(m_Value(Shift), m_AllOnes())) &&
isKnownToBeAPowerOfTwo(Shift, Q.DL, /*OrZero*/ false, 0, Q.AC, Q.CxtI,
Q.DT)) {
KnownBits Known = computeKnownBits(Shift, /* Depth */ 0, Q);
// Use getActiveBits() to make use of the additional power of two knowledge
if (PowerC->getActiveBits() >= Known.getMaxValue().getActiveBits())
return ConstantInt::getNullValue(Op1->getType());
}
if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, true))
return V;
// Try some generic simplifications for associative operations.
if (Value *V =
simplifyAssociativeBinOp(Instruction::And, Op0, Op1, Q, MaxRecurse))
return V;
// And distributes over Or. Try some generic simplifications based on this.
if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
Instruction::Or, Q, MaxRecurse))
return V;
// And distributes over Xor. Try some generic simplifications based on this.
if (Value *V = expandCommutativeBinOp(Instruction::And, Op0, Op1,
Instruction::Xor, Q, MaxRecurse))
return V;
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
if (Op0->getType()->isIntOrIntVectorTy(1)) {
// A & (A && B) -> A && B
if (match(Op1, m_Select(m_Specific(Op0), m_Value(), m_Zero())))
return Op1;
else if (match(Op0, m_Select(m_Specific(Op1), m_Value(), m_Zero())))
return Op0;
}
// If the operation is with the result of a select instruction, check
// whether operating on either branch of the select always yields the same
// value.
if (Value *V =
threadBinOpOverSelect(Instruction::And, Op0, Op1, Q, MaxRecurse))
return V;
}
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
if (Value *V =
threadBinOpOverPHI(Instruction::And, Op0, Op1, Q, MaxRecurse))
return V;
// Assuming the effective width of Y is not larger than A, i.e. all bits
// from X and Y are disjoint in (X << A) | Y,
// if the mask of this AND op covers all bits of X or Y, while it covers
// no bits from the other, we can bypass this AND op. E.g.,
// ((X << A) | Y) & Mask -> Y,
// if Mask = ((1 << effective_width_of(Y)) - 1)
// ((X << A) | Y) & Mask -> X << A,
// if Mask = ((1 << effective_width_of(X)) - 1) << A
// SimplifyDemandedBits in InstCombine can optimize the general case.
// This pattern aims to help other passes for a common case.
Value *XShifted;
if (Q.IIQ.UseInstrInfo && match(Op1, m_APInt(Mask)) &&
match(Op0, m_c_Or(m_CombineAnd(m_NUWShl(m_Value(X), m_APInt(ShAmt)),
m_Value(XShifted)),
m_Value(Y)))) {
const unsigned Width = Op0->getType()->getScalarSizeInBits();
const unsigned ShftCnt = ShAmt->getLimitedValue(Width);
const KnownBits YKnown = computeKnownBits(Y, /* Depth */ 0, Q);
const unsigned EffWidthY = YKnown.countMaxActiveBits();
if (EffWidthY <= ShftCnt) {
const KnownBits XKnown = computeKnownBits(X, /* Depth */ 0, Q);
const unsigned EffWidthX = XKnown.countMaxActiveBits();
const APInt EffBitsY = APInt::getLowBitsSet(Width, EffWidthY);
const APInt EffBitsX = APInt::getLowBitsSet(Width, EffWidthX) << ShftCnt;
// If the mask is extracting all bits from X or Y as is, we can skip
// this AND op.
if (EffBitsY.isSubsetOf(*Mask) && !EffBitsX.intersects(*Mask))
return Y;
if (EffBitsX.isSubsetOf(*Mask) && !EffBitsY.intersects(*Mask))
return XShifted;
}
}
// ((X | Y) ^ X ) & ((X | Y) ^ Y) --> 0
// ((X | Y) ^ Y ) & ((X | Y) ^ X) --> 0
BinaryOperator *Or;
if (match(Op0, m_c_Xor(m_Value(X),
m_CombineAnd(m_BinOp(Or),
m_c_Or(m_Deferred(X), m_Value(Y))))) &&
match(Op1, m_c_Xor(m_Specific(Or), m_Specific(Y))))
return Constant::getNullValue(Op0->getType());
const APInt *C1;
Value *A;
// (A ^ C) & (A ^ ~C) -> 0
if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))
return Constant::getNullValue(Op0->getType());
if (Op0->getType()->isIntOrIntVectorTy(1)) {
if (std::optional<bool> Implied = isImpliedCondition(Op0, Op1, Q.DL)) {
// If Op0 is true implies Op1 is true, then Op0 is a subset of Op1.
if (*Implied == true)
return Op0;
// If Op0 is true implies Op1 is false, then they are not true together.
if (*Implied == false)
return ConstantInt::getFalse(Op0->getType());
}
if (std::optional<bool> Implied = isImpliedCondition(Op1, Op0, Q.DL)) {
// If Op1 is true implies Op0 is true, then Op1 is a subset of Op0.
if (*Implied)
return Op1;
// If Op1 is true implies Op0 is false, then they are not true together.
if (!*Implied)
return ConstantInt::getFalse(Op1->getType());
}
}
if (Value *V = simplifyByDomEq(Instruction::And, Op0, Op1, Q, MaxRecurse))
return V;
return nullptr;
}
Value *llvm::simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
return ::simplifyAndInst(Op0, Op1, Q, RecursionLimit);
}
// TODO: Many of these folds could use LogicalAnd/LogicalOr.
static Value *simplifyOrLogic(Value *X, Value *Y) {
assert(X->getType() == Y->getType() && "Expected same type for 'or' ops");
Type *Ty = X->getType();
// X | ~X --> -1
if (match(Y, m_Not(m_Specific(X))))
return ConstantInt::getAllOnesValue(Ty);
// X | ~(X & ?) = -1
if (match(Y, m_Not(m_c_And(m_Specific(X), m_Value()))))
return ConstantInt::getAllOnesValue(Ty);
// X | (X & ?) --> X
if (match(Y, m_c_And(m_Specific(X), m_Value())))
return X;
Value *A, *B;
// (A ^ B) | (A | B) --> A | B
// (A ^ B) | (B | A) --> B | A
if (match(X, m_Xor(m_Value(A), m_Value(B))) &&
match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
return Y;
// ~(A ^ B) | (A | B) --> -1
// ~(A ^ B) | (B | A) --> -1
if (match(X, m_Not(m_Xor(m_Value(A), m_Value(B)))) &&
match(Y, m_c_Or(m_Specific(A), m_Specific(B))))
return ConstantInt::getAllOnesValue(Ty);
// (A & ~B) | (A ^ B) --> A ^ B
// (~B & A) | (A ^ B) --> A ^ B
// (A & ~B) | (B ^ A) --> B ^ A
// (~B & A) | (B ^ A) --> B ^ A
if (match(X, m_c_And(m_Value(A), m_Not(m_Value(B)))) &&
match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
return Y;
// (~A ^ B) | (A & B) --> ~A ^ B
// (B ^ ~A) | (A & B) --> B ^ ~A
// (~A ^ B) | (B & A) --> ~A ^ B
// (B ^ ~A) | (B & A) --> B ^ ~A
if (match(X, m_c_Xor(m_NotForbidUndef(m_Value(A)), m_Value(B))) &&
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
return X;
// (~A | B) | (A ^ B) --> -1
// (~A | B) | (B ^ A) --> -1
// (B | ~A) | (A ^ B) --> -1
// (B | ~A) | (B ^ A) --> -1
if (match(X, m_c_Or(m_Not(m_Value(A)), m_Value(B))) &&
match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
return ConstantInt::getAllOnesValue(Ty);
// (~A & B) | ~(A | B) --> ~A
// (~A & B) | ~(B | A) --> ~A
// (B & ~A) | ~(A | B) --> ~A
// (B & ~A) | ~(B | A) --> ~A
Value *NotA;
if (match(X,
m_c_And(m_CombineAnd(m_Value(NotA), m_NotForbidUndef(m_Value(A))),
m_Value(B))) &&
match(Y, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
return NotA;
// The same is true of Logical And
// TODO: This could share the logic of the version above if there was a
// version of LogicalAnd that allowed more than just i1 types.
if (match(X, m_c_LogicalAnd(
m_CombineAnd(m_Value(NotA), m_NotForbidUndef(m_Value(A))),
m_Value(B))) &&
match(Y, m_Not(m_c_LogicalOr(m_Specific(A), m_Specific(B)))))
return NotA;
// ~(A ^ B) | (A & B) --> ~(A ^ B)
// ~(A ^ B) | (B & A) --> ~(A ^ B)
Value *NotAB;
if (match(X, m_CombineAnd(m_NotForbidUndef(m_Xor(m_Value(A), m_Value(B))),
m_Value(NotAB))) &&
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
return NotAB;
// ~(A & B) | (A ^ B) --> ~(A & B)
// ~(A & B) | (B ^ A) --> ~(A & B)
if (match(X, m_CombineAnd(m_NotForbidUndef(m_And(m_Value(A), m_Value(B))),
m_Value(NotAB))) &&
match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
return NotAB;
return nullptr;
}
/// Given operands for an Or, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Or, Op0, Op1, Q))
return C;
// X | poison -> poison
if (isa<PoisonValue>(Op1))
return Op1;
// X | undef -> -1
// X | -1 = -1
// Do not return Op1 because it may contain undef elements if it's a vector.
if (Q.isUndefValue(Op1) || match(Op1, m_AllOnes()))
return Constant::getAllOnesValue(Op0->getType());
// X | X = X
// X | 0 = X
if (Op0 == Op1 || match(Op1, m_Zero()))
return Op0;
if (Value *R = simplifyOrLogic(Op0, Op1))
return R;
if (Value *R = simplifyOrLogic(Op1, Op0))
return R;
if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Or))
return V;
// Rotated -1 is still -1:
// (-1 << X) | (-1 >> (C - X)) --> -1
// (-1 >> X) | (-1 << (C - X)) --> -1
// ...with C <= bitwidth (and commuted variants).
Value *X, *Y;
if ((match(Op0, m_Shl(m_AllOnes(), m_Value(X))) &&
match(Op1, m_LShr(m_AllOnes(), m_Value(Y)))) ||
(match(Op1, m_Shl(m_AllOnes(), m_Value(X))) &&
match(Op0, m_LShr(m_AllOnes(), m_Value(Y))))) {
const APInt *C;
if ((match(X, m_Sub(m_APInt(C), m_Specific(Y))) ||
match(Y, m_Sub(m_APInt(C), m_Specific(X)))) &&
C->ule(X->getType()->getScalarSizeInBits())) {
return ConstantInt::getAllOnesValue(X->getType());
}
}
// A funnel shift (rotate) can be decomposed into simpler shifts. See if we
// are mixing in another shift that is redundant with the funnel shift.
// (fshl X, ?, Y) | (shl X, Y) --> fshl X, ?, Y
// (shl X, Y) | (fshl X, ?, Y) --> fshl X, ?, Y
if (match(Op0,
m_Intrinsic<Intrinsic::fshl>(m_Value(X), m_Value(), m_Value(Y))) &&
match(Op1, m_Shl(m_Specific(X), m_Specific(Y))))
return Op0;
if (match(Op1,
m_Intrinsic<Intrinsic::fshl>(m_Value(X), m_Value(), m_Value(Y))) &&
match(Op0, m_Shl(m_Specific(X), m_Specific(Y))))
return Op1;
// (fshr ?, X, Y) | (lshr X, Y) --> fshr ?, X, Y
// (lshr X, Y) | (fshr ?, X, Y) --> fshr ?, X, Y
if (match(Op0,
m_Intrinsic<Intrinsic::fshr>(m_Value(), m_Value(X), m_Value(Y))) &&
match(Op1, m_LShr(m_Specific(X), m_Specific(Y))))
return Op0;
if (match(Op1,
m_Intrinsic<Intrinsic::fshr>(m_Value(), m_Value(X), m_Value(Y))) &&
match(Op0, m_LShr(m_Specific(X), m_Specific(Y))))
return Op1;
if (Value *V =
simplifyAndOrWithICmpEq(Instruction::Or, Op0, Op1, Q, MaxRecurse))
return V;
if (Value *V =
simplifyAndOrWithICmpEq(Instruction::Or, Op1, Op0, Q, MaxRecurse))
return V;
if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
return V;
// If we have a multiplication overflow check that is being 'and'ed with a
// check that one of the multipliers is not zero, we can omit the 'and', and
// only keep the overflow check.
if (isCheckForZeroAndMulWithOverflow(Op0, Op1, false))
return Op1;
if (isCheckForZeroAndMulWithOverflow(Op1, Op0, false))
return Op0;
// Try some generic simplifications for associative operations.
if (Value *V =
simplifyAssociativeBinOp(Instruction::Or, Op0, Op1, Q, MaxRecurse))
return V;
// Or distributes over And. Try some generic simplifications based on this.
if (Value *V = expandCommutativeBinOp(Instruction::Or, Op0, Op1,
Instruction::And, Q, MaxRecurse))
return V;
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
if (Op0->getType()->isIntOrIntVectorTy(1)) {
// A | (A || B) -> A || B
if (match(Op1, m_Select(m_Specific(Op0), m_One(), m_Value())))
return Op1;
else if (match(Op0, m_Select(m_Specific(Op1), m_One(), m_Value())))
return Op0;
}
// If the operation is with the result of a select instruction, check
// whether operating on either branch of the select always yields the same
// value.
if (Value *V =
threadBinOpOverSelect(Instruction::Or, Op0, Op1, Q, MaxRecurse))
return V;
}
// (A & C1)|(B & C2)
Value *A, *B;
const APInt *C1, *C2;
if (match(Op0, m_And(m_Value(A), m_APInt(C1))) &&
match(Op1, m_And(m_Value(B), m_APInt(C2)))) {
if (*C1 == ~*C2) {
// (A & C1)|(B & C2)
// If we have: ((V + N) & C1) | (V & C2)
// .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
// replace with V+N.
Value *N;
if (C2->isMask() && // C2 == 0+1+
match(A, m_c_Add(m_Specific(B), m_Value(N)))) {
// Add commutes, try both ways.
if (MaskedValueIsZero(N, *C2, Q))
return A;
}
// Or commutes, try both ways.
if (C1->isMask() && match(B, m_c_Add(m_Specific(A), m_Value(N)))) {
// Add commutes, try both ways.
if (MaskedValueIsZero(N, *C1, Q))
return B;
}
}
}
// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
if (Value *V = threadBinOpOverPHI(Instruction::Or, Op0, Op1, Q, MaxRecurse))
return V;
// (A ^ C) | (A ^ ~C) -> -1, i.e. all bits set to one.
if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))
return Constant::getAllOnesValue(Op0->getType());
if (Op0->getType()->isIntOrIntVectorTy(1)) {
if (std::optional<bool> Implied =
isImpliedCondition(Op0, Op1, Q.DL, false)) {
// If Op0 is false implies Op1 is false, then Op1 is a subset of Op0.
if (*Implied == false)
return Op0;
// If Op0 is false implies Op1 is true, then at least one is always true.
if (*Implied == true)
return ConstantInt::getTrue(Op0->getType());
}
if (std::optional<bool> Implied =
isImpliedCondition(Op1, Op0, Q.DL, false)) {
// If Op1 is false implies Op0 is false, then Op0 is a subset of Op1.
if (*Implied == false)
return Op1;
// If Op1 is false implies Op0 is true, then at least one is always true.
if (*Implied == true)
return ConstantInt::getTrue(Op1->getType());
}
}
if (Value *V = simplifyByDomEq(Instruction::Or, Op0, Op1, Q, MaxRecurse))
return V;
return nullptr;
}
Value *llvm::simplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
return ::simplifyOrInst(Op0, Op1, Q, RecursionLimit);
}
/// Given operands for a Xor, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
unsigned MaxRecurse) {
if (Constant *C = foldOrCommuteConstant(Instruction::Xor, Op0, Op1, Q))
return C;
// X ^ poison -> poison
if (isa<PoisonValue>(Op1))
return Op1;
// A ^ undef -> undef
if (Q.isUndefValue(Op1))
return Op1;
// A ^ 0 = A
if (match(Op1, m_Zero()))
return Op0;
// A ^ A = 0
if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
// A ^ ~A = ~A ^ A = -1
if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0))))
return Constant::getAllOnesValue(Op0->getType());
auto foldAndOrNot = [](Value *X, Value *Y) -> Value * {
Value *A, *B;