summaryrefslogtreecommitdiff
path: root/lib/Transforms/InstCombine/InstCombineAddSub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r--lib/Transforms/InstCombine/InstCombineAddSub.cpp320
1 files changed, 160 insertions, 160 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 809471cfd74f..688897644848 100644
--- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -12,12 +12,26 @@
//===----------------------------------------------------------------------===//
#include "InstCombineInternal.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/KnownBits.h"
+#include <cassert>
+#include <utility>
using namespace llvm;
using namespace PatternMatch;
@@ -39,10 +53,15 @@ namespace {
// is expensive. In order to avoid the cost of the constructor, we should
// reuse some instances whenever possible. The pre-created instances
// FAddCombine::Add[0-5] embodies this idea.
- //
- FAddendCoef() : IsFp(false), BufHasFpVal(false), IntVal(0) {}
+ FAddendCoef() = default;
~FAddendCoef();
+ // If possible, don't define operator+/operator- etc because these
+ // operators inevitably call FAddendCoef's constructor which is not cheap.
+ void operator=(const FAddendCoef &A);
+ void operator+=(const FAddendCoef &A);
+ void operator*=(const FAddendCoef &S);
+
void set(short C) {
assert(!insaneIntVal(C) && "Insane coefficient");
IsFp = false; IntVal = C;
@@ -55,12 +74,6 @@ namespace {
bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); }
Value *getValue(Type *) const;
- // If possible, don't define operator+/operator- etc because these
- // operators inevitably call FAddendCoef's constructor which is not cheap.
- void operator=(const FAddendCoef &A);
- void operator+=(const FAddendCoef &A);
- void operator*=(const FAddendCoef &S);
-
bool isOne() const { return isInt() && IntVal == 1; }
bool isTwo() const { return isInt() && IntVal == 2; }
bool isMinusOne() const { return isInt() && IntVal == -1; }
@@ -68,10 +81,12 @@ namespace {
private:
bool insaneIntVal(int V) { return V > 4 || V < -4; }
+
APFloat *getFpValPtr()
- { return reinterpret_cast<APFloat*>(&FpValBuf.buffer[0]); }
+ { return reinterpret_cast<APFloat *>(&FpValBuf.buffer[0]); }
+
const APFloat *getFpValPtr() const
- { return reinterpret_cast<const APFloat*>(&FpValBuf.buffer[0]); }
+ { return reinterpret_cast<const APFloat *>(&FpValBuf.buffer[0]); }
const APFloat &getFpVal() const {
assert(IsFp && BufHasFpVal && "Incorret state");
@@ -94,17 +109,16 @@ namespace {
// from an *SIGNED* integer.
APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val);
- private:
- bool IsFp;
+ bool IsFp = false;
// True iff FpValBuf contains an instance of APFloat.
- bool BufHasFpVal;
+ bool BufHasFpVal = false;
// The integer coefficient of an individual addend is either 1 or -1,
// and we try to simplify at most 4 addends from neighboring at most
// two instructions. So the range of <IntVal> falls in [-4, 4]. APInt
// is overkill of this end.
- short IntVal;
+ short IntVal = 0;
AlignedCharArrayUnion<APFloat> FpValBuf;
};
@@ -112,10 +126,14 @@ namespace {
/// FAddend is used to represent floating-point addend. An addend is
/// represented as <C, V>, where the V is a symbolic value, and C is a
/// constant coefficient. A constant addend is represented as <C, 0>.
- ///
class FAddend {
public:
- FAddend() : Val(nullptr) {}
+ FAddend() = default;
+
+ void operator+=(const FAddend &T) {
+ assert((Val == T.Val) && "Symbolic-values disagree");
+ Coeff += T.Coeff;
+ }
Value *getSymVal() const { return Val; }
const FAddendCoef &getCoef() const { return Coeff; }
@@ -146,16 +164,11 @@ namespace {
/// splitted is the addend itself.
unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const;
- void operator+=(const FAddend &T) {
- assert((Val == T.Val) && "Symbolic-values disagree");
- Coeff += T.Coeff;
- }
-
private:
void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
// This addend has the value of "Coeff * Val".
- Value *Val;
+ Value *Val = nullptr;
FAddendCoef Coeff;
};
@@ -164,11 +177,12 @@ namespace {
///
class FAddCombine {
public:
- FAddCombine(InstCombiner::BuilderTy &B) : Builder(B), Instr(nullptr) {}
+ FAddCombine(InstCombiner::BuilderTy &B) : Builder(B) {}
+
Value *simplify(Instruction *FAdd);
private:
- typedef SmallVector<const FAddend*, 4> AddendVect;
+ using AddendVect = SmallVector<const FAddend *, 4>;
Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota);
@@ -179,6 +193,7 @@ namespace {
/// Return the number of instructions needed to emit the N-ary addition.
unsigned calcInstrNumber(const AddendVect& Vect);
+
Value *createFSub(Value *Opnd0, Value *Opnd1);
Value *createFAdd(Value *Opnd0, Value *Opnd1);
Value *createFMul(Value *Opnd0, Value *Opnd1);
@@ -187,9 +202,6 @@ namespace {
Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota);
void createInstPostProc(Instruction *NewInst, bool NoNumber = false);
- InstCombiner::BuilderTy &Builder;
- Instruction *Instr;
-
// Debugging stuff are clustered here.
#ifndef NDEBUG
unsigned CreateInstrNum;
@@ -199,9 +211,12 @@ namespace {
void initCreateInstNum() {}
void incCreateInstNum() {}
#endif
+
+ InstCombiner::BuilderTy &Builder;
+ Instruction *Instr = nullptr;
};
-} // anonymous namespace
+} // end anonymous namespace
//===----------------------------------------------------------------------===//
//
@@ -332,7 +347,6 @@ Value *FAddendCoef::getValue(Type *Ty) const {
// 0 +/- 0 <0, NULL> (corner case)
//
// Legend: A and B are not constant, C is constant
-//
unsigned FAddend::drillValueDownOneStep
(Value *Val, FAddend &Addend0, FAddend &Addend1) {
Instruction *I = nullptr;
@@ -396,7 +410,6 @@ unsigned FAddend::drillValueDownOneStep
// Try to break *this* addend into two addends. e.g. Suppose this addend is
// <2.3, V>, and V = X + Y, by calling this function, we obtain two addends,
// i.e. <2.3, X> and <2.3, Y>.
-//
unsigned FAddend::drillAddendDownOneStep
(FAddend &Addend0, FAddend &Addend1) const {
if (isConstant())
@@ -421,7 +434,6 @@ unsigned FAddend::drillAddendDownOneStep
// -------------------------------------------------------
// (x * y) +/- (x * z) x * (y +/- z)
// (y / x) +/- (z / x) (y +/- z) / x
-//
Value *FAddCombine::performFactorization(Instruction *I) {
assert((I->getOpcode() == Instruction::FAdd ||
I->getOpcode() == Instruction::FSub) && "Expect add/sub");
@@ -447,7 +459,6 @@ Value *FAddCombine::performFactorization(Instruction *I) {
// ----------------------------------------------
// (x*y) +/- (x*z) x y z
// (y/x) +/- (z/x) x y z
- //
Value *Factor = nullptr;
Value *AddSub0 = nullptr, *AddSub1 = nullptr;
@@ -471,7 +482,7 @@ Value *FAddCombine::performFactorization(Instruction *I) {
return nullptr;
FastMathFlags Flags;
- Flags.setUnsafeAlgebra();
+ Flags.setFast();
if (I0) Flags &= I->getFastMathFlags();
if (I1) Flags &= I->getFastMathFlags();
@@ -500,7 +511,7 @@ Value *FAddCombine::performFactorization(Instruction *I) {
}
Value *FAddCombine::simplify(Instruction *I) {
- assert(I->hasUnsafeAlgebra() && "Should be in unsafe mode");
+ assert(I->isFast() && "Expected 'fast' instruction");
// Currently we are not able to handle vector type.
if (I->getType()->isVectorTy())
@@ -599,7 +610,6 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
// desirable to reside at the top of the resulting expression tree. Placing
// constant close to supper-expr(s) will potentially reveal some optimization
// opportunities in super-expr(s).
- //
const FAddend *ConstAdd = nullptr;
// Simplified addends are placed <SimpVect>.
@@ -608,7 +618,6 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
// The outer loop works on one symbolic-value at a time. Suppose the input
// addends are : <a1, x>, <b1, y>, <a2, x>, <c1, z>, <b2, y>, ...
// The symbolic-values will be processed in this order: x, y, z.
- //
for (unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
const FAddend *ThisAddend = Addends[SymIdx];
@@ -626,7 +635,6 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
// example, if the symbolic value "y" is being processed, the inner loop
// will collect two addends "<b1,y>" and "<b2,Y>". These two addends will
// be later on folded into "<b1+b2, y>".
- //
for (unsigned SameSymIdx = SymIdx + 1;
SameSymIdx < AddendNum; SameSymIdx++) {
const FAddend *T = Addends[SameSymIdx];
@@ -681,7 +689,7 @@ Value *FAddCombine::createNaryFAdd
assert(!Opnds.empty() && "Expect at least one addend");
// Step 1: Check if the # of instructions needed exceeds the quota.
- //
+
unsigned InstrNeeded = calcInstrNumber(Opnds);
if (InstrNeeded > InstrQuota)
return nullptr;
@@ -726,10 +734,10 @@ Value *FAddCombine::createNaryFAdd
LastVal = createFNeg(LastVal);
}
- #ifndef NDEBUG
- assert(CreateInstrNum == InstrNeeded &&
- "Inconsistent in instruction numbers");
- #endif
+#ifndef NDEBUG
+ assert(CreateInstrNum == InstrNeeded &&
+ "Inconsistent in instruction numbers");
+#endif
return LastVal;
}
@@ -950,9 +958,25 @@ static Value *checkForNegativeOperand(BinaryOperator &I,
return nullptr;
}
-static Instruction *foldAddWithConstant(BinaryOperator &Add,
- InstCombiner::BuilderTy &Builder) {
+Instruction *InstCombiner::foldAddWithConstant(BinaryOperator &Add) {
Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1);
+ Constant *Op1C;
+ if (!match(Op1, m_Constant(Op1C)))
+ return nullptr;
+
+ if (Instruction *NV = foldOpWithConstantIntoOperand(Add))
+ return NV;
+
+ Value *X;
+ // zext(bool) + C -> bool ? C + 1 : C
+ if (match(Op0, m_ZExt(m_Value(X))) &&
+ X->getType()->getScalarSizeInBits() == 1)
+ return SelectInst::Create(X, AddOne(Op1C), Op1);
+
+ // ~X + C --> (C-1) - X
+ if (match(Op0, m_Not(m_Value(X))))
+ return BinaryOperator::CreateSub(SubOne(Op1C), X);
+
const APInt *C;
if (!match(Op1, m_APInt(C)))
return nullptr;
@@ -968,21 +992,17 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add,
return BinaryOperator::CreateXor(Op0, Op1);
}
- Value *X;
- const APInt *C2;
- Type *Ty = Add.getType();
-
// Is this add the last step in a convoluted sext?
// add(zext(xor i16 X, -32768), -32768) --> sext X
+ Type *Ty = Add.getType();
+ const APInt *C2;
if (match(Op0, m_ZExt(m_Xor(m_Value(X), m_APInt(C2)))) &&
C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C)
return CastInst::Create(Instruction::SExt, X, Ty);
// (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
- // FIXME: This should check hasOneUse to not increase the instruction count?
- if (C->isNegative() &&
- match(Op0, m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2)))) &&
- C->sge(-C2->sext(C->getBitWidth()))) {
+ if (match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2))))) &&
+ C->isNegative() && C->sge(-C2->sext(C->getBitWidth()))) {
Constant *NewC =
ConstantInt::get(X->getType(), *C2 + C->trunc(C2->getBitWidth()));
return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty);
@@ -1013,34 +1033,29 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add,
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
bool Changed = SimplifyAssociativeOrCommutative(I);
- Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
-
if (Value *V = SimplifyVectorOp(I))
return replaceInstUsesWith(I, V);
+ Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
if (Value *V =
SimplifyAddInst(LHS, RHS, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),
SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
- // (A*B)+(A*C) -> A*(B+C) etc
+ // (A*B)+(A*C) -> A*(B+C) etc
if (Value *V = SimplifyUsingDistributiveLaws(I))
return replaceInstUsesWith(I, V);
- if (Instruction *X = foldAddWithConstant(I, Builder))
+ if (Instruction *X = foldAddWithConstant(I))
return X;
// FIXME: This should be moved into the above helper function to allow these
- // transforms for splat vectors.
+ // transforms for general constant or constant splat vectors.
+ Type *Ty = I.getType();
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
- // zext(bool) + C -> bool ? C + 1 : C
- if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS))
- if (ZI->getSrcTy()->isIntegerTy(1))
- return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI);
-
Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr;
if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {
- uint32_t TySizeBits = I.getType()->getScalarSizeInBits();
+ unsigned TySizeBits = Ty->getScalarSizeInBits();
const APInt &RHSVal = CI->getValue();
unsigned ExtendAmt = 0;
// If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
@@ -1059,7 +1074,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
if (ExtendAmt) {
- Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt);
+ Constant *ShAmt = ConstantInt::get(Ty, ExtendAmt);
Value *NewShl = Builder.CreateShl(XorLHS, ShAmt, "sext");
return BinaryOperator::CreateAShr(NewShl, ShAmt);
}
@@ -1080,38 +1095,30 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
}
- if (isa<Constant>(RHS))
- if (Instruction *NV = foldOpWithConstantIntoOperand(I))
- return NV;
-
- if (I.getType()->isIntOrIntVectorTy(1))
+ if (Ty->isIntOrIntVectorTy(1))
return BinaryOperator::CreateXor(LHS, RHS);
// X + X --> X << 1
if (LHS == RHS) {
- BinaryOperator *New =
- BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1));
- New->setHasNoSignedWrap(I.hasNoSignedWrap());
- New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
- return New;
+ auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1));
+ Shl->setHasNoSignedWrap(I.hasNoSignedWrap());
+ Shl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
+ return Shl;
}
- // -A + B --> B - A
- // -A + -B --> -(A + B)
- if (Value *LHSV = dyn_castNegVal(LHS)) {
- if (!isa<Constant>(RHS))
- if (Value *RHSV = dyn_castNegVal(RHS)) {
- Value *NewAdd = Builder.CreateAdd(LHSV, RHSV, "sum");
- return BinaryOperator::CreateNeg(NewAdd);
- }
+ Value *A, *B;
+ if (match(LHS, m_Neg(m_Value(A)))) {
+ // -A + -B --> -(A + B)
+ if (match(RHS, m_Neg(m_Value(B))))
+ return BinaryOperator::CreateNeg(Builder.CreateAdd(A, B));
- return BinaryOperator::CreateSub(RHS, LHSV);
+ // -A + B --> B - A
+ return BinaryOperator::CreateSub(RHS, A);
}
// A + -B --> A - B
- if (!isa<Constant>(RHS))
- if (Value *V = dyn_castNegVal(RHS))
- return BinaryOperator::CreateSub(LHS, V);
+ if (match(RHS, m_Neg(m_Value(B))))
+ return BinaryOperator::CreateSub(LHS, B);
if (Value *V = checkForNegativeOperand(I, Builder))
return replaceInstUsesWith(I, V);
@@ -1120,12 +1127,6 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT))
return BinaryOperator::CreateOr(LHS, RHS);
- if (Constant *CRHS = dyn_cast<Constant>(RHS)) {
- Value *X;
- if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X
- return BinaryOperator::CreateSub(SubOne(CRHS), X);
- }
-
// FIXME: We already did a check for ConstantInt RHS above this.
// FIXME: Is this pattern covered by another fold? No regression tests fail on
// removal.
@@ -1187,12 +1188,12 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (LHSConv->hasOneUse()) {
Constant *CI =
ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType());
- if (ConstantExpr::getSExt(CI, I.getType()) == RHSC &&
+ if (ConstantExpr::getSExt(CI, Ty) == RHSC &&
willNotOverflowSignedAdd(LHSConv->getOperand(0), CI, I)) {
// Insert the new, smaller add.
Value *NewAdd =
Builder.CreateNSWAdd(LHSConv->getOperand(0), CI, "addconv");
- return new SExtInst(NewAdd, I.getType());
+ return new SExtInst(NewAdd, Ty);
}
}
}
@@ -1210,7 +1211,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
// Insert the new integer add.
Value *NewAdd = Builder.CreateNSWAdd(LHSConv->getOperand(0),
RHSConv->getOperand(0), "addconv");
- return new SExtInst(NewAdd, I.getType());
+ return new SExtInst(NewAdd, Ty);
}
}
}
@@ -1223,12 +1224,12 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (LHSConv->hasOneUse()) {
Constant *CI =
ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType());
- if (ConstantExpr::getZExt(CI, I.getType()) == RHSC &&
+ if (ConstantExpr::getZExt(CI, Ty) == RHSC &&
willNotOverflowUnsignedAdd(LHSConv->getOperand(0), CI, I)) {
// Insert the new, smaller add.
Value *NewAdd =
Builder.CreateNUWAdd(LHSConv->getOperand(0), CI, "addconv");
- return new ZExtInst(NewAdd, I.getType());
+ return new ZExtInst(NewAdd, Ty);
}
}
}
@@ -1246,41 +1247,35 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
// Insert the new integer add.
Value *NewAdd = Builder.CreateNUWAdd(
LHSConv->getOperand(0), RHSConv->getOperand(0), "addconv");
- return new ZExtInst(NewAdd, I.getType());
+ return new ZExtInst(NewAdd, Ty);
}
}
}
// (add (xor A, B) (and A, B)) --> (or A, B)
- {
- Value *A = nullptr, *B = nullptr;
- if (match(RHS, m_Xor(m_Value(A), m_Value(B))) &&
- match(LHS, m_c_And(m_Specific(A), m_Specific(B))))
- return BinaryOperator::CreateOr(A, B);
-
- if (match(LHS, m_Xor(m_Value(A), m_Value(B))) &&
- match(RHS, m_c_And(m_Specific(A), m_Specific(B))))
- return BinaryOperator::CreateOr(A, B);
- }
+ if (match(LHS, m_Xor(m_Value(A), m_Value(B))) &&
+ match(RHS, m_c_And(m_Specific(A), m_Specific(B))))
+ return BinaryOperator::CreateOr(A, B);
+
+ // (add (and A, B) (xor A, B)) --> (or A, B)
+ if (match(RHS, m_Xor(m_Value(A), m_Value(B))) &&
+ match(LHS, m_c_And(m_Specific(A), m_Specific(B))))
+ return BinaryOperator::CreateOr(A, B);
// (add (or A, B) (and A, B)) --> (add A, B)
- {
- Value *A = nullptr, *B = nullptr;
- if (match(RHS, m_Or(m_Value(A), m_Value(B))) &&
- match(LHS, m_c_And(m_Specific(A), m_Specific(B)))) {
- auto *New = BinaryOperator::CreateAdd(A, B);
- New->setHasNoSignedWrap(I.hasNoSignedWrap());
- New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
- return New;
- }
+ if (match(LHS, m_Or(m_Value(A), m_Value(B))) &&
+ match(RHS, m_c_And(m_Specific(A), m_Specific(B)))) {
+ I.setOperand(0, A);
+ I.setOperand(1, B);
+ return &I;
+ }
- if (match(LHS, m_Or(m_Value(A), m_Value(B))) &&
- match(RHS, m_c_And(m_Specific(A), m_Specific(B)))) {
- auto *New = BinaryOperator::CreateAdd(A, B);
- New->setHasNoSignedWrap(I.hasNoSignedWrap());
- New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
- return New;
- }
+ // (add (and A, B) (or A, B)) --> (add A, B)
+ if (match(RHS, m_Or(m_Value(A), m_Value(B))) &&
+ match(LHS, m_c_And(m_Specific(A), m_Specific(B)))) {
+ I.setOperand(0, A);
+ I.setOperand(1, B);
+ return &I;
}
// TODO(jingyue): Consider willNotOverflowSignedAdd and
@@ -1387,32 +1382,11 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {
}
}
- // select C, 0, B + select C, A, 0 -> select C, A, B
- {
- Value *A1, *B1, *C1, *A2, *B2, *C2;
- if (match(LHS, m_Select(m_Value(C1), m_Value(A1), m_Value(B1))) &&
- match(RHS, m_Select(m_Value(C2), m_Value(A2), m_Value(B2)))) {
- if (C1 == C2) {
- Constant *Z1=nullptr, *Z2=nullptr;
- Value *A, *B, *C=C1;
- if (match(A1, m_AnyZero()) && match(B2, m_AnyZero())) {
- Z1 = dyn_cast<Constant>(A1); A = A2;
- Z2 = dyn_cast<Constant>(B2); B = B1;
- } else if (match(B1, m_AnyZero()) && match(A2, m_AnyZero())) {
- Z1 = dyn_cast<Constant>(B1); B = B2;
- Z2 = dyn_cast<Constant>(A2); A = A1;
- }
-
- if (Z1 && Z2 &&
- (I.hasNoSignedZeros() ||
- (Z1->isNegativeZeroValue() && Z2->isNegativeZeroValue()))) {
- return SelectInst::Create(C, A, B);
- }
- }
- }
- }
+ // Handle specials cases for FAdd with selects feeding the operation
+ if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS))
+ return replaceInstUsesWith(I, V);
- if (I.hasUnsafeAlgebra()) {
+ if (I.isFast()) {
if (Value *V = FAddCombine(Builder).simplify(&I))
return replaceInstUsesWith(I, V);
}
@@ -1423,7 +1397,6 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {
/// Optimize pointer differences into the same array into a size. Consider:
/// &A[10] - &A[0]: we should compile this to "10". LHS/RHS are the pointer
/// operands to the ptrtoint instructions for the LHS/RHS of the subtract.
-///
Value *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS,
Type *Ty) {
// If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize
@@ -1465,12 +1438,31 @@ Value *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS,
}
}
- // Avoid duplicating the arithmetic if GEP2 has non-constant indices and
- // multiple users.
- if (!GEP1 ||
- (GEP2 && !GEP2->hasAllConstantIndices() && !GEP2->hasOneUse()))
+ if (!GEP1)
+ // No GEP found.
return nullptr;
+ if (GEP2) {
+ // (gep X, ...) - (gep X, ...)
+ //
+ // Avoid duplicating the arithmetic if there are more than one non-constant
+ // indices between the two GEPs and either GEP has a non-constant index and
+ // multiple users. If zero non-constant index, the result is a constant and
+ // there is no duplication. If one non-constant index, the result is an add
+ // or sub with a constant, which is no larger than the original code, and
+ // there's no duplicated arithmetic, even if either GEP has multiple
+ // users. If more than one non-constant indices combined, as long as the GEP
+ // with at least one non-constant index doesn't have multiple users, there
+ // is no duplication.
+ unsigned NumNonConstantIndices1 = GEP1->countNonConstantIndices();
+ unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices();
+ if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 &&
+ ((NumNonConstantIndices1 > 0 && !GEP1->hasOneUse()) ||
+ (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) {
+ return nullptr;
+ }
+ }
+
// Emit the offset of the GEP and an intptr_t.
Value *Result = EmitGEPOffset(GEP1);
@@ -1528,8 +1520,13 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateNot(Op1);
if (Constant *C = dyn_cast<Constant>(Op0)) {
+ Value *X;
+ // C - zext(bool) -> bool ? C - 1 : C
+ if (match(Op1, m_ZExt(m_Value(X))) &&
+ X->getType()->getScalarSizeInBits() == 1)
+ return SelectInst::Create(X, SubOne(C), C);
+
// C - ~X == X + (1+C)
- Value *X = nullptr;
if (match(Op1, m_Not(m_Value(X))))
return BinaryOperator::CreateAdd(X, AddOne(C));
@@ -1600,7 +1597,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateNeg(Y);
}
- // (sub (or A, B) (xor A, B)) --> (and A, B)
+ // (sub (or A, B), (xor A, B)) --> (and A, B)
{
Value *A, *B;
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
@@ -1626,7 +1623,6 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Builder.CreateSub(Z, Y, Op1->getName()));
// (X - (X & Y)) --> (X & ~Y)
- //
if (match(Op1, m_c_And(m_Value(Y), m_Specific(Op0))))
return BinaryOperator::CreateAnd(Op0,
Builder.CreateNot(Y, Y->getName() + ".not"));
@@ -1741,7 +1737,11 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {
}
}
- if (I.hasUnsafeAlgebra()) {
+ // Handle specials cases for FSub with selects feeding the operation
+ if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
+ return replaceInstUsesWith(I, V);
+
+ if (I.isFast()) {
if (Value *V = FAddCombine(Builder).simplify(&I))
return replaceInstUsesWith(I, V);
}