109467b48Spatrick //===- InstCombineAddSub.cpp ------------------------------------*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file implements the visit functions for add, fadd, sub, and fsub. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #include "InstCombineInternal.h" 1409467b48Spatrick #include "llvm/ADT/APFloat.h" 1509467b48Spatrick #include "llvm/ADT/APInt.h" 1609467b48Spatrick #include "llvm/ADT/STLExtras.h" 1709467b48Spatrick #include "llvm/ADT/SmallVector.h" 1809467b48Spatrick #include "llvm/Analysis/InstructionSimplify.h" 1909467b48Spatrick #include "llvm/Analysis/ValueTracking.h" 2009467b48Spatrick #include "llvm/IR/Constant.h" 2109467b48Spatrick #include "llvm/IR/Constants.h" 2209467b48Spatrick #include "llvm/IR/InstrTypes.h" 2309467b48Spatrick #include "llvm/IR/Instruction.h" 2409467b48Spatrick #include "llvm/IR/Instructions.h" 2509467b48Spatrick #include "llvm/IR/Operator.h" 2609467b48Spatrick #include "llvm/IR/PatternMatch.h" 2709467b48Spatrick #include "llvm/IR/Type.h" 2809467b48Spatrick #include "llvm/IR/Value.h" 2909467b48Spatrick #include "llvm/Support/AlignOf.h" 3009467b48Spatrick #include "llvm/Support/Casting.h" 3109467b48Spatrick #include "llvm/Support/KnownBits.h" 3209467b48Spatrick #include <cassert> 3309467b48Spatrick #include <utility> 3409467b48Spatrick 3509467b48Spatrick using namespace llvm; 3609467b48Spatrick using namespace PatternMatch; 3709467b48Spatrick 3809467b48Spatrick #define DEBUG_TYPE "instcombine" 3909467b48Spatrick 4009467b48Spatrick namespace { 4109467b48Spatrick 4209467b48Spatrick /// Class representing coefficient of floating-point addend. 4309467b48Spatrick /// This class needs to be highly efficient, which is especially true for 4409467b48Spatrick /// the constructor. As of I write this comment, the cost of the default 4509467b48Spatrick /// constructor is merely 4-byte-store-zero (Assuming compiler is able to 4609467b48Spatrick /// perform write-merging). 4709467b48Spatrick /// 4809467b48Spatrick class FAddendCoef { 4909467b48Spatrick public: 5009467b48Spatrick // The constructor has to initialize a APFloat, which is unnecessary for 5109467b48Spatrick // most addends which have coefficient either 1 or -1. So, the constructor 5209467b48Spatrick // is expensive. In order to avoid the cost of the constructor, we should 5309467b48Spatrick // reuse some instances whenever possible. The pre-created instances 5409467b48Spatrick // FAddCombine::Add[0-5] embodies this idea. 5509467b48Spatrick FAddendCoef() = default; 5609467b48Spatrick ~FAddendCoef(); 5709467b48Spatrick 5809467b48Spatrick // If possible, don't define operator+/operator- etc because these 5909467b48Spatrick // operators inevitably call FAddendCoef's constructor which is not cheap. 6009467b48Spatrick void operator=(const FAddendCoef &A); 6109467b48Spatrick void operator+=(const FAddendCoef &A); 6209467b48Spatrick void operator*=(const FAddendCoef &S); 6309467b48Spatrick 6409467b48Spatrick void set(short C) { 6509467b48Spatrick assert(!insaneIntVal(C) && "Insane coefficient"); 6609467b48Spatrick IsFp = false; IntVal = C; 6709467b48Spatrick } 6809467b48Spatrick 6909467b48Spatrick void set(const APFloat& C); 7009467b48Spatrick 7109467b48Spatrick void negate(); 7209467b48Spatrick 7309467b48Spatrick bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); } 7409467b48Spatrick Value *getValue(Type *) const; 7509467b48Spatrick 7609467b48Spatrick bool isOne() const { return isInt() && IntVal == 1; } 7709467b48Spatrick bool isTwo() const { return isInt() && IntVal == 2; } 7809467b48Spatrick bool isMinusOne() const { return isInt() && IntVal == -1; } 7909467b48Spatrick bool isMinusTwo() const { return isInt() && IntVal == -2; } 8009467b48Spatrick 8109467b48Spatrick private: 8209467b48Spatrick bool insaneIntVal(int V) { return V > 4 || V < -4; } 8309467b48Spatrick 8409467b48Spatrick APFloat *getFpValPtr() 8509467b48Spatrick { return reinterpret_cast<APFloat *>(&FpValBuf.buffer[0]); } 8609467b48Spatrick 8709467b48Spatrick const APFloat *getFpValPtr() const 8809467b48Spatrick { return reinterpret_cast<const APFloat *>(&FpValBuf.buffer[0]); } 8909467b48Spatrick 9009467b48Spatrick const APFloat &getFpVal() const { 9109467b48Spatrick assert(IsFp && BufHasFpVal && "Incorret state"); 9209467b48Spatrick return *getFpValPtr(); 9309467b48Spatrick } 9409467b48Spatrick 9509467b48Spatrick APFloat &getFpVal() { 9609467b48Spatrick assert(IsFp && BufHasFpVal && "Incorret state"); 9709467b48Spatrick return *getFpValPtr(); 9809467b48Spatrick } 9909467b48Spatrick 10009467b48Spatrick bool isInt() const { return !IsFp; } 10109467b48Spatrick 10209467b48Spatrick // If the coefficient is represented by an integer, promote it to a 10309467b48Spatrick // floating point. 10409467b48Spatrick void convertToFpType(const fltSemantics &Sem); 10509467b48Spatrick 10609467b48Spatrick // Construct an APFloat from a signed integer. 10709467b48Spatrick // TODO: We should get rid of this function when APFloat can be constructed 10809467b48Spatrick // from an *SIGNED* integer. 10909467b48Spatrick APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val); 11009467b48Spatrick 11109467b48Spatrick bool IsFp = false; 11209467b48Spatrick 11309467b48Spatrick // True iff FpValBuf contains an instance of APFloat. 11409467b48Spatrick bool BufHasFpVal = false; 11509467b48Spatrick 11609467b48Spatrick // The integer coefficient of an individual addend is either 1 or -1, 11709467b48Spatrick // and we try to simplify at most 4 addends from neighboring at most 11809467b48Spatrick // two instructions. So the range of <IntVal> falls in [-4, 4]. APInt 11909467b48Spatrick // is overkill of this end. 12009467b48Spatrick short IntVal = 0; 12109467b48Spatrick 12209467b48Spatrick AlignedCharArrayUnion<APFloat> FpValBuf; 12309467b48Spatrick }; 12409467b48Spatrick 12509467b48Spatrick /// FAddend is used to represent floating-point addend. An addend is 12609467b48Spatrick /// represented as <C, V>, where the V is a symbolic value, and C is a 12709467b48Spatrick /// constant coefficient. A constant addend is represented as <C, 0>. 12809467b48Spatrick class FAddend { 12909467b48Spatrick public: 13009467b48Spatrick FAddend() = default; 13109467b48Spatrick 13209467b48Spatrick void operator+=(const FAddend &T) { 13309467b48Spatrick assert((Val == T.Val) && "Symbolic-values disagree"); 13409467b48Spatrick Coeff += T.Coeff; 13509467b48Spatrick } 13609467b48Spatrick 13709467b48Spatrick Value *getSymVal() const { return Val; } 13809467b48Spatrick const FAddendCoef &getCoef() const { return Coeff; } 13909467b48Spatrick 14009467b48Spatrick bool isConstant() const { return Val == nullptr; } 14109467b48Spatrick bool isZero() const { return Coeff.isZero(); } 14209467b48Spatrick 14309467b48Spatrick void set(short Coefficient, Value *V) { 14409467b48Spatrick Coeff.set(Coefficient); 14509467b48Spatrick Val = V; 14609467b48Spatrick } 14709467b48Spatrick void set(const APFloat &Coefficient, Value *V) { 14809467b48Spatrick Coeff.set(Coefficient); 14909467b48Spatrick Val = V; 15009467b48Spatrick } 15109467b48Spatrick void set(const ConstantFP *Coefficient, Value *V) { 15209467b48Spatrick Coeff.set(Coefficient->getValueAPF()); 15309467b48Spatrick Val = V; 15409467b48Spatrick } 15509467b48Spatrick 15609467b48Spatrick void negate() { Coeff.negate(); } 15709467b48Spatrick 15809467b48Spatrick /// Drill down the U-D chain one step to find the definition of V, and 15909467b48Spatrick /// try to break the definition into one or two addends. 16009467b48Spatrick static unsigned drillValueDownOneStep(Value* V, FAddend &A0, FAddend &A1); 16109467b48Spatrick 16209467b48Spatrick /// Similar to FAddend::drillDownOneStep() except that the value being 16309467b48Spatrick /// splitted is the addend itself. 16409467b48Spatrick unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const; 16509467b48Spatrick 16609467b48Spatrick private: 16709467b48Spatrick void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; } 16809467b48Spatrick 16909467b48Spatrick // This addend has the value of "Coeff * Val". 17009467b48Spatrick Value *Val = nullptr; 17109467b48Spatrick FAddendCoef Coeff; 17209467b48Spatrick }; 17309467b48Spatrick 17409467b48Spatrick /// FAddCombine is the class for optimizing an unsafe fadd/fsub along 17509467b48Spatrick /// with its neighboring at most two instructions. 17609467b48Spatrick /// 17709467b48Spatrick class FAddCombine { 17809467b48Spatrick public: 17909467b48Spatrick FAddCombine(InstCombiner::BuilderTy &B) : Builder(B) {} 18009467b48Spatrick 18109467b48Spatrick Value *simplify(Instruction *FAdd); 18209467b48Spatrick 18309467b48Spatrick private: 18409467b48Spatrick using AddendVect = SmallVector<const FAddend *, 4>; 18509467b48Spatrick 18609467b48Spatrick Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota); 18709467b48Spatrick 18809467b48Spatrick /// Convert given addend to a Value 18909467b48Spatrick Value *createAddendVal(const FAddend &A, bool& NeedNeg); 19009467b48Spatrick 19109467b48Spatrick /// Return the number of instructions needed to emit the N-ary addition. 19209467b48Spatrick unsigned calcInstrNumber(const AddendVect& Vect); 19309467b48Spatrick 19409467b48Spatrick Value *createFSub(Value *Opnd0, Value *Opnd1); 19509467b48Spatrick Value *createFAdd(Value *Opnd0, Value *Opnd1); 19609467b48Spatrick Value *createFMul(Value *Opnd0, Value *Opnd1); 19709467b48Spatrick Value *createFNeg(Value *V); 19809467b48Spatrick Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota); 19909467b48Spatrick void createInstPostProc(Instruction *NewInst, bool NoNumber = false); 20009467b48Spatrick 20109467b48Spatrick // Debugging stuff are clustered here. 20209467b48Spatrick #ifndef NDEBUG 20309467b48Spatrick unsigned CreateInstrNum; 20409467b48Spatrick void initCreateInstNum() { CreateInstrNum = 0; } 20509467b48Spatrick void incCreateInstNum() { CreateInstrNum++; } 20609467b48Spatrick #else 20709467b48Spatrick void initCreateInstNum() {} 20809467b48Spatrick void incCreateInstNum() {} 20909467b48Spatrick #endif 21009467b48Spatrick 21109467b48Spatrick InstCombiner::BuilderTy &Builder; 21209467b48Spatrick Instruction *Instr = nullptr; 21309467b48Spatrick }; 21409467b48Spatrick 21509467b48Spatrick } // end anonymous namespace 21609467b48Spatrick 21709467b48Spatrick //===----------------------------------------------------------------------===// 21809467b48Spatrick // 21909467b48Spatrick // Implementation of 22009467b48Spatrick // {FAddendCoef, FAddend, FAddition, FAddCombine}. 22109467b48Spatrick // 22209467b48Spatrick //===----------------------------------------------------------------------===// 22309467b48Spatrick FAddendCoef::~FAddendCoef() { 22409467b48Spatrick if (BufHasFpVal) 22509467b48Spatrick getFpValPtr()->~APFloat(); 22609467b48Spatrick } 22709467b48Spatrick 22809467b48Spatrick void FAddendCoef::set(const APFloat& C) { 22909467b48Spatrick APFloat *P = getFpValPtr(); 23009467b48Spatrick 23109467b48Spatrick if (isInt()) { 23209467b48Spatrick // As the buffer is meanless byte stream, we cannot call 23309467b48Spatrick // APFloat::operator=(). 23409467b48Spatrick new(P) APFloat(C); 23509467b48Spatrick } else 23609467b48Spatrick *P = C; 23709467b48Spatrick 23809467b48Spatrick IsFp = BufHasFpVal = true; 23909467b48Spatrick } 24009467b48Spatrick 24109467b48Spatrick void FAddendCoef::convertToFpType(const fltSemantics &Sem) { 24209467b48Spatrick if (!isInt()) 24309467b48Spatrick return; 24409467b48Spatrick 24509467b48Spatrick APFloat *P = getFpValPtr(); 24609467b48Spatrick if (IntVal > 0) 24709467b48Spatrick new(P) APFloat(Sem, IntVal); 24809467b48Spatrick else { 24909467b48Spatrick new(P) APFloat(Sem, 0 - IntVal); 25009467b48Spatrick P->changeSign(); 25109467b48Spatrick } 25209467b48Spatrick IsFp = BufHasFpVal = true; 25309467b48Spatrick } 25409467b48Spatrick 25509467b48Spatrick APFloat FAddendCoef::createAPFloatFromInt(const fltSemantics &Sem, int Val) { 25609467b48Spatrick if (Val >= 0) 25709467b48Spatrick return APFloat(Sem, Val); 25809467b48Spatrick 25909467b48Spatrick APFloat T(Sem, 0 - Val); 26009467b48Spatrick T.changeSign(); 26109467b48Spatrick 26209467b48Spatrick return T; 26309467b48Spatrick } 26409467b48Spatrick 26509467b48Spatrick void FAddendCoef::operator=(const FAddendCoef &That) { 26609467b48Spatrick if (That.isInt()) 26709467b48Spatrick set(That.IntVal); 26809467b48Spatrick else 26909467b48Spatrick set(That.getFpVal()); 27009467b48Spatrick } 27109467b48Spatrick 27209467b48Spatrick void FAddendCoef::operator+=(const FAddendCoef &That) { 273*097a140dSpatrick RoundingMode RndMode = RoundingMode::NearestTiesToEven; 27409467b48Spatrick if (isInt() == That.isInt()) { 27509467b48Spatrick if (isInt()) 27609467b48Spatrick IntVal += That.IntVal; 27709467b48Spatrick else 27809467b48Spatrick getFpVal().add(That.getFpVal(), RndMode); 27909467b48Spatrick return; 28009467b48Spatrick } 28109467b48Spatrick 28209467b48Spatrick if (isInt()) { 28309467b48Spatrick const APFloat &T = That.getFpVal(); 28409467b48Spatrick convertToFpType(T.getSemantics()); 28509467b48Spatrick getFpVal().add(T, RndMode); 28609467b48Spatrick return; 28709467b48Spatrick } 28809467b48Spatrick 28909467b48Spatrick APFloat &T = getFpVal(); 29009467b48Spatrick T.add(createAPFloatFromInt(T.getSemantics(), That.IntVal), RndMode); 29109467b48Spatrick } 29209467b48Spatrick 29309467b48Spatrick void FAddendCoef::operator*=(const FAddendCoef &That) { 29409467b48Spatrick if (That.isOne()) 29509467b48Spatrick return; 29609467b48Spatrick 29709467b48Spatrick if (That.isMinusOne()) { 29809467b48Spatrick negate(); 29909467b48Spatrick return; 30009467b48Spatrick } 30109467b48Spatrick 30209467b48Spatrick if (isInt() && That.isInt()) { 30309467b48Spatrick int Res = IntVal * (int)That.IntVal; 30409467b48Spatrick assert(!insaneIntVal(Res) && "Insane int value"); 30509467b48Spatrick IntVal = Res; 30609467b48Spatrick return; 30709467b48Spatrick } 30809467b48Spatrick 30909467b48Spatrick const fltSemantics &Semantic = 31009467b48Spatrick isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics(); 31109467b48Spatrick 31209467b48Spatrick if (isInt()) 31309467b48Spatrick convertToFpType(Semantic); 31409467b48Spatrick APFloat &F0 = getFpVal(); 31509467b48Spatrick 31609467b48Spatrick if (That.isInt()) 31709467b48Spatrick F0.multiply(createAPFloatFromInt(Semantic, That.IntVal), 31809467b48Spatrick APFloat::rmNearestTiesToEven); 31909467b48Spatrick else 32009467b48Spatrick F0.multiply(That.getFpVal(), APFloat::rmNearestTiesToEven); 32109467b48Spatrick } 32209467b48Spatrick 32309467b48Spatrick void FAddendCoef::negate() { 32409467b48Spatrick if (isInt()) 32509467b48Spatrick IntVal = 0 - IntVal; 32609467b48Spatrick else 32709467b48Spatrick getFpVal().changeSign(); 32809467b48Spatrick } 32909467b48Spatrick 33009467b48Spatrick Value *FAddendCoef::getValue(Type *Ty) const { 33109467b48Spatrick return isInt() ? 33209467b48Spatrick ConstantFP::get(Ty, float(IntVal)) : 33309467b48Spatrick ConstantFP::get(Ty->getContext(), getFpVal()); 33409467b48Spatrick } 33509467b48Spatrick 33609467b48Spatrick // The definition of <Val> Addends 33709467b48Spatrick // ========================================= 33809467b48Spatrick // A + B <1, A>, <1,B> 33909467b48Spatrick // A - B <1, A>, <1,B> 34009467b48Spatrick // 0 - B <-1, B> 34109467b48Spatrick // C * A, <C, A> 34209467b48Spatrick // A + C <1, A> <C, NULL> 34309467b48Spatrick // 0 +/- 0 <0, NULL> (corner case) 34409467b48Spatrick // 34509467b48Spatrick // Legend: A and B are not constant, C is constant 34609467b48Spatrick unsigned FAddend::drillValueDownOneStep 34709467b48Spatrick (Value *Val, FAddend &Addend0, FAddend &Addend1) { 34809467b48Spatrick Instruction *I = nullptr; 34909467b48Spatrick if (!Val || !(I = dyn_cast<Instruction>(Val))) 35009467b48Spatrick return 0; 35109467b48Spatrick 35209467b48Spatrick unsigned Opcode = I->getOpcode(); 35309467b48Spatrick 35409467b48Spatrick if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) { 35509467b48Spatrick ConstantFP *C0, *C1; 35609467b48Spatrick Value *Opnd0 = I->getOperand(0); 35709467b48Spatrick Value *Opnd1 = I->getOperand(1); 35809467b48Spatrick if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->isZero()) 35909467b48Spatrick Opnd0 = nullptr; 36009467b48Spatrick 36109467b48Spatrick if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->isZero()) 36209467b48Spatrick Opnd1 = nullptr; 36309467b48Spatrick 36409467b48Spatrick if (Opnd0) { 36509467b48Spatrick if (!C0) 36609467b48Spatrick Addend0.set(1, Opnd0); 36709467b48Spatrick else 36809467b48Spatrick Addend0.set(C0, nullptr); 36909467b48Spatrick } 37009467b48Spatrick 37109467b48Spatrick if (Opnd1) { 37209467b48Spatrick FAddend &Addend = Opnd0 ? Addend1 : Addend0; 37309467b48Spatrick if (!C1) 37409467b48Spatrick Addend.set(1, Opnd1); 37509467b48Spatrick else 37609467b48Spatrick Addend.set(C1, nullptr); 37709467b48Spatrick if (Opcode == Instruction::FSub) 37809467b48Spatrick Addend.negate(); 37909467b48Spatrick } 38009467b48Spatrick 38109467b48Spatrick if (Opnd0 || Opnd1) 38209467b48Spatrick return Opnd0 && Opnd1 ? 2 : 1; 38309467b48Spatrick 38409467b48Spatrick // Both operands are zero. Weird! 38509467b48Spatrick Addend0.set(APFloat(C0->getValueAPF().getSemantics()), nullptr); 38609467b48Spatrick return 1; 38709467b48Spatrick } 38809467b48Spatrick 38909467b48Spatrick if (I->getOpcode() == Instruction::FMul) { 39009467b48Spatrick Value *V0 = I->getOperand(0); 39109467b48Spatrick Value *V1 = I->getOperand(1); 39209467b48Spatrick if (ConstantFP *C = dyn_cast<ConstantFP>(V0)) { 39309467b48Spatrick Addend0.set(C, V1); 39409467b48Spatrick return 1; 39509467b48Spatrick } 39609467b48Spatrick 39709467b48Spatrick if (ConstantFP *C = dyn_cast<ConstantFP>(V1)) { 39809467b48Spatrick Addend0.set(C, V0); 39909467b48Spatrick return 1; 40009467b48Spatrick } 40109467b48Spatrick } 40209467b48Spatrick 40309467b48Spatrick return 0; 40409467b48Spatrick } 40509467b48Spatrick 40609467b48Spatrick // Try to break *this* addend into two addends. e.g. Suppose this addend is 40709467b48Spatrick // <2.3, V>, and V = X + Y, by calling this function, we obtain two addends, 40809467b48Spatrick // i.e. <2.3, X> and <2.3, Y>. 40909467b48Spatrick unsigned FAddend::drillAddendDownOneStep 41009467b48Spatrick (FAddend &Addend0, FAddend &Addend1) const { 41109467b48Spatrick if (isConstant()) 41209467b48Spatrick return 0; 41309467b48Spatrick 41409467b48Spatrick unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1); 41509467b48Spatrick if (!BreakNum || Coeff.isOne()) 41609467b48Spatrick return BreakNum; 41709467b48Spatrick 41809467b48Spatrick Addend0.Scale(Coeff); 41909467b48Spatrick 42009467b48Spatrick if (BreakNum == 2) 42109467b48Spatrick Addend1.Scale(Coeff); 42209467b48Spatrick 42309467b48Spatrick return BreakNum; 42409467b48Spatrick } 42509467b48Spatrick 42609467b48Spatrick Value *FAddCombine::simplify(Instruction *I) { 42709467b48Spatrick assert(I->hasAllowReassoc() && I->hasNoSignedZeros() && 42809467b48Spatrick "Expected 'reassoc'+'nsz' instruction"); 42909467b48Spatrick 43009467b48Spatrick // Currently we are not able to handle vector type. 43109467b48Spatrick if (I->getType()->isVectorTy()) 43209467b48Spatrick return nullptr; 43309467b48Spatrick 43409467b48Spatrick assert((I->getOpcode() == Instruction::FAdd || 43509467b48Spatrick I->getOpcode() == Instruction::FSub) && "Expect add/sub"); 43609467b48Spatrick 43709467b48Spatrick // Save the instruction before calling other member-functions. 43809467b48Spatrick Instr = I; 43909467b48Spatrick 44009467b48Spatrick FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1; 44109467b48Spatrick 44209467b48Spatrick unsigned OpndNum = FAddend::drillValueDownOneStep(I, Opnd0, Opnd1); 44309467b48Spatrick 44409467b48Spatrick // Step 1: Expand the 1st addend into Opnd0_0 and Opnd0_1. 44509467b48Spatrick unsigned Opnd0_ExpNum = 0; 44609467b48Spatrick unsigned Opnd1_ExpNum = 0; 44709467b48Spatrick 44809467b48Spatrick if (!Opnd0.isConstant()) 44909467b48Spatrick Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1); 45009467b48Spatrick 45109467b48Spatrick // Step 2: Expand the 2nd addend into Opnd1_0 and Opnd1_1. 45209467b48Spatrick if (OpndNum == 2 && !Opnd1.isConstant()) 45309467b48Spatrick Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1); 45409467b48Spatrick 45509467b48Spatrick // Step 3: Try to optimize Opnd0_0 + Opnd0_1 + Opnd1_0 + Opnd1_1 45609467b48Spatrick if (Opnd0_ExpNum && Opnd1_ExpNum) { 45709467b48Spatrick AddendVect AllOpnds; 45809467b48Spatrick AllOpnds.push_back(&Opnd0_0); 45909467b48Spatrick AllOpnds.push_back(&Opnd1_0); 46009467b48Spatrick if (Opnd0_ExpNum == 2) 46109467b48Spatrick AllOpnds.push_back(&Opnd0_1); 46209467b48Spatrick if (Opnd1_ExpNum == 2) 46309467b48Spatrick AllOpnds.push_back(&Opnd1_1); 46409467b48Spatrick 46509467b48Spatrick // Compute instruction quota. We should save at least one instruction. 46609467b48Spatrick unsigned InstQuota = 0; 46709467b48Spatrick 46809467b48Spatrick Value *V0 = I->getOperand(0); 46909467b48Spatrick Value *V1 = I->getOperand(1); 47009467b48Spatrick InstQuota = ((!isa<Constant>(V0) && V0->hasOneUse()) && 47109467b48Spatrick (!isa<Constant>(V1) && V1->hasOneUse())) ? 2 : 1; 47209467b48Spatrick 47309467b48Spatrick if (Value *R = simplifyFAdd(AllOpnds, InstQuota)) 47409467b48Spatrick return R; 47509467b48Spatrick } 47609467b48Spatrick 47709467b48Spatrick if (OpndNum != 2) { 47809467b48Spatrick // The input instruction is : "I=0.0 +/- V". If the "V" were able to be 47909467b48Spatrick // splitted into two addends, say "V = X - Y", the instruction would have 48009467b48Spatrick // been optimized into "I = Y - X" in the previous steps. 48109467b48Spatrick // 48209467b48Spatrick const FAddendCoef &CE = Opnd0.getCoef(); 48309467b48Spatrick return CE.isOne() ? Opnd0.getSymVal() : nullptr; 48409467b48Spatrick } 48509467b48Spatrick 48609467b48Spatrick // step 4: Try to optimize Opnd0 + Opnd1_0 [+ Opnd1_1] 48709467b48Spatrick if (Opnd1_ExpNum) { 48809467b48Spatrick AddendVect AllOpnds; 48909467b48Spatrick AllOpnds.push_back(&Opnd0); 49009467b48Spatrick AllOpnds.push_back(&Opnd1_0); 49109467b48Spatrick if (Opnd1_ExpNum == 2) 49209467b48Spatrick AllOpnds.push_back(&Opnd1_1); 49309467b48Spatrick 49409467b48Spatrick if (Value *R = simplifyFAdd(AllOpnds, 1)) 49509467b48Spatrick return R; 49609467b48Spatrick } 49709467b48Spatrick 49809467b48Spatrick // step 5: Try to optimize Opnd1 + Opnd0_0 [+ Opnd0_1] 49909467b48Spatrick if (Opnd0_ExpNum) { 50009467b48Spatrick AddendVect AllOpnds; 50109467b48Spatrick AllOpnds.push_back(&Opnd1); 50209467b48Spatrick AllOpnds.push_back(&Opnd0_0); 50309467b48Spatrick if (Opnd0_ExpNum == 2) 50409467b48Spatrick AllOpnds.push_back(&Opnd0_1); 50509467b48Spatrick 50609467b48Spatrick if (Value *R = simplifyFAdd(AllOpnds, 1)) 50709467b48Spatrick return R; 50809467b48Spatrick } 50909467b48Spatrick 51009467b48Spatrick return nullptr; 51109467b48Spatrick } 51209467b48Spatrick 51309467b48Spatrick Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) { 51409467b48Spatrick unsigned AddendNum = Addends.size(); 51509467b48Spatrick assert(AddendNum <= 4 && "Too many addends"); 51609467b48Spatrick 51709467b48Spatrick // For saving intermediate results; 51809467b48Spatrick unsigned NextTmpIdx = 0; 51909467b48Spatrick FAddend TmpResult[3]; 52009467b48Spatrick 52109467b48Spatrick // Points to the constant addend of the resulting simplified expression. 52209467b48Spatrick // If the resulting expr has constant-addend, this constant-addend is 52309467b48Spatrick // desirable to reside at the top of the resulting expression tree. Placing 52409467b48Spatrick // constant close to supper-expr(s) will potentially reveal some optimization 52509467b48Spatrick // opportunities in super-expr(s). 52609467b48Spatrick const FAddend *ConstAdd = nullptr; 52709467b48Spatrick 52809467b48Spatrick // Simplified addends are placed <SimpVect>. 52909467b48Spatrick AddendVect SimpVect; 53009467b48Spatrick 53109467b48Spatrick // The outer loop works on one symbolic-value at a time. Suppose the input 53209467b48Spatrick // addends are : <a1, x>, <b1, y>, <a2, x>, <c1, z>, <b2, y>, ... 53309467b48Spatrick // The symbolic-values will be processed in this order: x, y, z. 53409467b48Spatrick for (unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) { 53509467b48Spatrick 53609467b48Spatrick const FAddend *ThisAddend = Addends[SymIdx]; 53709467b48Spatrick if (!ThisAddend) { 53809467b48Spatrick // This addend was processed before. 53909467b48Spatrick continue; 54009467b48Spatrick } 54109467b48Spatrick 54209467b48Spatrick Value *Val = ThisAddend->getSymVal(); 54309467b48Spatrick unsigned StartIdx = SimpVect.size(); 54409467b48Spatrick SimpVect.push_back(ThisAddend); 54509467b48Spatrick 54609467b48Spatrick // The inner loop collects addends sharing same symbolic-value, and these 54709467b48Spatrick // addends will be later on folded into a single addend. Following above 54809467b48Spatrick // example, if the symbolic value "y" is being processed, the inner loop 54909467b48Spatrick // will collect two addends "<b1,y>" and "<b2,Y>". These two addends will 55009467b48Spatrick // be later on folded into "<b1+b2, y>". 55109467b48Spatrick for (unsigned SameSymIdx = SymIdx + 1; 55209467b48Spatrick SameSymIdx < AddendNum; SameSymIdx++) { 55309467b48Spatrick const FAddend *T = Addends[SameSymIdx]; 55409467b48Spatrick if (T && T->getSymVal() == Val) { 55509467b48Spatrick // Set null such that next iteration of the outer loop will not process 55609467b48Spatrick // this addend again. 55709467b48Spatrick Addends[SameSymIdx] = nullptr; 55809467b48Spatrick SimpVect.push_back(T); 55909467b48Spatrick } 56009467b48Spatrick } 56109467b48Spatrick 56209467b48Spatrick // If multiple addends share same symbolic value, fold them together. 56309467b48Spatrick if (StartIdx + 1 != SimpVect.size()) { 56409467b48Spatrick FAddend &R = TmpResult[NextTmpIdx ++]; 56509467b48Spatrick R = *SimpVect[StartIdx]; 56609467b48Spatrick for (unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++) 56709467b48Spatrick R += *SimpVect[Idx]; 56809467b48Spatrick 56909467b48Spatrick // Pop all addends being folded and push the resulting folded addend. 57009467b48Spatrick SimpVect.resize(StartIdx); 57109467b48Spatrick if (Val) { 57209467b48Spatrick if (!R.isZero()) { 57309467b48Spatrick SimpVect.push_back(&R); 57409467b48Spatrick } 57509467b48Spatrick } else { 57609467b48Spatrick // Don't push constant addend at this time. It will be the last element 57709467b48Spatrick // of <SimpVect>. 57809467b48Spatrick ConstAdd = &R; 57909467b48Spatrick } 58009467b48Spatrick } 58109467b48Spatrick } 58209467b48Spatrick 58309467b48Spatrick assert((NextTmpIdx <= array_lengthof(TmpResult) + 1) && 58409467b48Spatrick "out-of-bound access"); 58509467b48Spatrick 58609467b48Spatrick if (ConstAdd) 58709467b48Spatrick SimpVect.push_back(ConstAdd); 58809467b48Spatrick 58909467b48Spatrick Value *Result; 59009467b48Spatrick if (!SimpVect.empty()) 59109467b48Spatrick Result = createNaryFAdd(SimpVect, InstrQuota); 59209467b48Spatrick else { 59309467b48Spatrick // The addition is folded to 0.0. 59409467b48Spatrick Result = ConstantFP::get(Instr->getType(), 0.0); 59509467b48Spatrick } 59609467b48Spatrick 59709467b48Spatrick return Result; 59809467b48Spatrick } 59909467b48Spatrick 60009467b48Spatrick Value *FAddCombine::createNaryFAdd 60109467b48Spatrick (const AddendVect &Opnds, unsigned InstrQuota) { 60209467b48Spatrick assert(!Opnds.empty() && "Expect at least one addend"); 60309467b48Spatrick 60409467b48Spatrick // Step 1: Check if the # of instructions needed exceeds the quota. 60509467b48Spatrick 60609467b48Spatrick unsigned InstrNeeded = calcInstrNumber(Opnds); 60709467b48Spatrick if (InstrNeeded > InstrQuota) 60809467b48Spatrick return nullptr; 60909467b48Spatrick 61009467b48Spatrick initCreateInstNum(); 61109467b48Spatrick 61209467b48Spatrick // step 2: Emit the N-ary addition. 61309467b48Spatrick // Note that at most three instructions are involved in Fadd-InstCombine: the 61409467b48Spatrick // addition in question, and at most two neighboring instructions. 61509467b48Spatrick // The resulting optimized addition should have at least one less instruction 61609467b48Spatrick // than the original addition expression tree. This implies that the resulting 61709467b48Spatrick // N-ary addition has at most two instructions, and we don't need to worry 61809467b48Spatrick // about tree-height when constructing the N-ary addition. 61909467b48Spatrick 62009467b48Spatrick Value *LastVal = nullptr; 62109467b48Spatrick bool LastValNeedNeg = false; 62209467b48Spatrick 62309467b48Spatrick // Iterate the addends, creating fadd/fsub using adjacent two addends. 62409467b48Spatrick for (const FAddend *Opnd : Opnds) { 62509467b48Spatrick bool NeedNeg; 62609467b48Spatrick Value *V = createAddendVal(*Opnd, NeedNeg); 62709467b48Spatrick if (!LastVal) { 62809467b48Spatrick LastVal = V; 62909467b48Spatrick LastValNeedNeg = NeedNeg; 63009467b48Spatrick continue; 63109467b48Spatrick } 63209467b48Spatrick 63309467b48Spatrick if (LastValNeedNeg == NeedNeg) { 63409467b48Spatrick LastVal = createFAdd(LastVal, V); 63509467b48Spatrick continue; 63609467b48Spatrick } 63709467b48Spatrick 63809467b48Spatrick if (LastValNeedNeg) 63909467b48Spatrick LastVal = createFSub(V, LastVal); 64009467b48Spatrick else 64109467b48Spatrick LastVal = createFSub(LastVal, V); 64209467b48Spatrick 64309467b48Spatrick LastValNeedNeg = false; 64409467b48Spatrick } 64509467b48Spatrick 64609467b48Spatrick if (LastValNeedNeg) { 64709467b48Spatrick LastVal = createFNeg(LastVal); 64809467b48Spatrick } 64909467b48Spatrick 65009467b48Spatrick #ifndef NDEBUG 65109467b48Spatrick assert(CreateInstrNum == InstrNeeded && 65209467b48Spatrick "Inconsistent in instruction numbers"); 65309467b48Spatrick #endif 65409467b48Spatrick 65509467b48Spatrick return LastVal; 65609467b48Spatrick } 65709467b48Spatrick 65809467b48Spatrick Value *FAddCombine::createFSub(Value *Opnd0, Value *Opnd1) { 65909467b48Spatrick Value *V = Builder.CreateFSub(Opnd0, Opnd1); 66009467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(V)) 66109467b48Spatrick createInstPostProc(I); 66209467b48Spatrick return V; 66309467b48Spatrick } 66409467b48Spatrick 66509467b48Spatrick Value *FAddCombine::createFNeg(Value *V) { 666*097a140dSpatrick Value *NewV = Builder.CreateFNeg(V); 66709467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(NewV)) 66809467b48Spatrick createInstPostProc(I, true); // fneg's don't receive instruction numbers. 66909467b48Spatrick return NewV; 67009467b48Spatrick } 67109467b48Spatrick 67209467b48Spatrick Value *FAddCombine::createFAdd(Value *Opnd0, Value *Opnd1) { 67309467b48Spatrick Value *V = Builder.CreateFAdd(Opnd0, Opnd1); 67409467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(V)) 67509467b48Spatrick createInstPostProc(I); 67609467b48Spatrick return V; 67709467b48Spatrick } 67809467b48Spatrick 67909467b48Spatrick Value *FAddCombine::createFMul(Value *Opnd0, Value *Opnd1) { 68009467b48Spatrick Value *V = Builder.CreateFMul(Opnd0, Opnd1); 68109467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(V)) 68209467b48Spatrick createInstPostProc(I); 68309467b48Spatrick return V; 68409467b48Spatrick } 68509467b48Spatrick 68609467b48Spatrick void FAddCombine::createInstPostProc(Instruction *NewInstr, bool NoNumber) { 68709467b48Spatrick NewInstr->setDebugLoc(Instr->getDebugLoc()); 68809467b48Spatrick 68909467b48Spatrick // Keep track of the number of instruction created. 69009467b48Spatrick if (!NoNumber) 69109467b48Spatrick incCreateInstNum(); 69209467b48Spatrick 69309467b48Spatrick // Propagate fast-math flags 69409467b48Spatrick NewInstr->setFastMathFlags(Instr->getFastMathFlags()); 69509467b48Spatrick } 69609467b48Spatrick 69709467b48Spatrick // Return the number of instruction needed to emit the N-ary addition. 69809467b48Spatrick // NOTE: Keep this function in sync with createAddendVal(). 69909467b48Spatrick unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) { 70009467b48Spatrick unsigned OpndNum = Opnds.size(); 70109467b48Spatrick unsigned InstrNeeded = OpndNum - 1; 70209467b48Spatrick 70309467b48Spatrick // The number of addends in the form of "(-1)*x". 70409467b48Spatrick unsigned NegOpndNum = 0; 70509467b48Spatrick 70609467b48Spatrick // Adjust the number of instructions needed to emit the N-ary add. 70709467b48Spatrick for (const FAddend *Opnd : Opnds) { 70809467b48Spatrick if (Opnd->isConstant()) 70909467b48Spatrick continue; 71009467b48Spatrick 71109467b48Spatrick // The constant check above is really for a few special constant 71209467b48Spatrick // coefficients. 71309467b48Spatrick if (isa<UndefValue>(Opnd->getSymVal())) 71409467b48Spatrick continue; 71509467b48Spatrick 71609467b48Spatrick const FAddendCoef &CE = Opnd->getCoef(); 71709467b48Spatrick if (CE.isMinusOne() || CE.isMinusTwo()) 71809467b48Spatrick NegOpndNum++; 71909467b48Spatrick 72009467b48Spatrick // Let the addend be "c * x". If "c == +/-1", the value of the addend 72109467b48Spatrick // is immediately available; otherwise, it needs exactly one instruction 72209467b48Spatrick // to evaluate the value. 72309467b48Spatrick if (!CE.isMinusOne() && !CE.isOne()) 72409467b48Spatrick InstrNeeded++; 72509467b48Spatrick } 72609467b48Spatrick return InstrNeeded; 72709467b48Spatrick } 72809467b48Spatrick 72909467b48Spatrick // Input Addend Value NeedNeg(output) 73009467b48Spatrick // ================================================================ 73109467b48Spatrick // Constant C C false 73209467b48Spatrick // <+/-1, V> V coefficient is -1 73309467b48Spatrick // <2/-2, V> "fadd V, V" coefficient is -2 73409467b48Spatrick // <C, V> "fmul V, C" false 73509467b48Spatrick // 73609467b48Spatrick // NOTE: Keep this function in sync with FAddCombine::calcInstrNumber. 73709467b48Spatrick Value *FAddCombine::createAddendVal(const FAddend &Opnd, bool &NeedNeg) { 73809467b48Spatrick const FAddendCoef &Coeff = Opnd.getCoef(); 73909467b48Spatrick 74009467b48Spatrick if (Opnd.isConstant()) { 74109467b48Spatrick NeedNeg = false; 74209467b48Spatrick return Coeff.getValue(Instr->getType()); 74309467b48Spatrick } 74409467b48Spatrick 74509467b48Spatrick Value *OpndVal = Opnd.getSymVal(); 74609467b48Spatrick 74709467b48Spatrick if (Coeff.isMinusOne() || Coeff.isOne()) { 74809467b48Spatrick NeedNeg = Coeff.isMinusOne(); 74909467b48Spatrick return OpndVal; 75009467b48Spatrick } 75109467b48Spatrick 75209467b48Spatrick if (Coeff.isTwo() || Coeff.isMinusTwo()) { 75309467b48Spatrick NeedNeg = Coeff.isMinusTwo(); 75409467b48Spatrick return createFAdd(OpndVal, OpndVal); 75509467b48Spatrick } 75609467b48Spatrick 75709467b48Spatrick NeedNeg = false; 75809467b48Spatrick return createFMul(OpndVal, Coeff.getValue(Instr->getType())); 75909467b48Spatrick } 76009467b48Spatrick 76109467b48Spatrick // Checks if any operand is negative and we can convert add to sub. 76209467b48Spatrick // This function checks for following negative patterns 76309467b48Spatrick // ADD(XOR(OR(Z, NOT(C)), C)), 1) == NEG(AND(Z, C)) 76409467b48Spatrick // ADD(XOR(AND(Z, C), C), 1) == NEG(OR(Z, ~C)) 76509467b48Spatrick // XOR(AND(Z, C), (C + 1)) == NEG(OR(Z, ~C)) if C is even 76609467b48Spatrick static Value *checkForNegativeOperand(BinaryOperator &I, 76709467b48Spatrick InstCombiner::BuilderTy &Builder) { 76809467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 76909467b48Spatrick 77009467b48Spatrick // This function creates 2 instructions to replace ADD, we need at least one 77109467b48Spatrick // of LHS or RHS to have one use to ensure benefit in transform. 77209467b48Spatrick if (!LHS->hasOneUse() && !RHS->hasOneUse()) 77309467b48Spatrick return nullptr; 77409467b48Spatrick 77509467b48Spatrick Value *X = nullptr, *Y = nullptr, *Z = nullptr; 77609467b48Spatrick const APInt *C1 = nullptr, *C2 = nullptr; 77709467b48Spatrick 77809467b48Spatrick // if ONE is on other side, swap 77909467b48Spatrick if (match(RHS, m_Add(m_Value(X), m_One()))) 78009467b48Spatrick std::swap(LHS, RHS); 78109467b48Spatrick 78209467b48Spatrick if (match(LHS, m_Add(m_Value(X), m_One()))) { 78309467b48Spatrick // if XOR on other side, swap 78409467b48Spatrick if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1)))) 78509467b48Spatrick std::swap(X, RHS); 78609467b48Spatrick 78709467b48Spatrick if (match(X, m_Xor(m_Value(Y), m_APInt(C1)))) { 78809467b48Spatrick // X = XOR(Y, C1), Y = OR(Z, C2), C2 = NOT(C1) ==> X == NOT(AND(Z, C1)) 78909467b48Spatrick // ADD(ADD(X, 1), RHS) == ADD(X, ADD(RHS, 1)) == SUB(RHS, AND(Z, C1)) 79009467b48Spatrick if (match(Y, m_Or(m_Value(Z), m_APInt(C2))) && (*C2 == ~(*C1))) { 79109467b48Spatrick Value *NewAnd = Builder.CreateAnd(Z, *C1); 79209467b48Spatrick return Builder.CreateSub(RHS, NewAnd, "sub"); 79309467b48Spatrick } else if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && (*C1 == *C2)) { 79409467b48Spatrick // X = XOR(Y, C1), Y = AND(Z, C2), C2 == C1 ==> X == NOT(OR(Z, ~C1)) 79509467b48Spatrick // ADD(ADD(X, 1), RHS) == ADD(X, ADD(RHS, 1)) == SUB(RHS, OR(Z, ~C1)) 79609467b48Spatrick Value *NewOr = Builder.CreateOr(Z, ~(*C1)); 79709467b48Spatrick return Builder.CreateSub(RHS, NewOr, "sub"); 79809467b48Spatrick } 79909467b48Spatrick } 80009467b48Spatrick } 80109467b48Spatrick 80209467b48Spatrick // Restore LHS and RHS 80309467b48Spatrick LHS = I.getOperand(0); 80409467b48Spatrick RHS = I.getOperand(1); 80509467b48Spatrick 80609467b48Spatrick // if XOR is on other side, swap 80709467b48Spatrick if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1)))) 80809467b48Spatrick std::swap(LHS, RHS); 80909467b48Spatrick 81009467b48Spatrick // C2 is ODD 81109467b48Spatrick // LHS = XOR(Y, C1), Y = AND(Z, C2), C1 == (C2 + 1) => LHS == NEG(OR(Z, ~C2)) 81209467b48Spatrick // ADD(LHS, RHS) == SUB(RHS, OR(Z, ~C2)) 81309467b48Spatrick if (match(LHS, m_Xor(m_Value(Y), m_APInt(C1)))) 81409467b48Spatrick if (C1->countTrailingZeros() == 0) 81509467b48Spatrick if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && *C1 == (*C2 + 1)) { 81609467b48Spatrick Value *NewOr = Builder.CreateOr(Z, ~(*C2)); 81709467b48Spatrick return Builder.CreateSub(RHS, NewOr, "sub"); 81809467b48Spatrick } 81909467b48Spatrick return nullptr; 82009467b48Spatrick } 82109467b48Spatrick 82209467b48Spatrick /// Wrapping flags may allow combining constants separated by an extend. 82309467b48Spatrick static Instruction *foldNoWrapAdd(BinaryOperator &Add, 82409467b48Spatrick InstCombiner::BuilderTy &Builder) { 82509467b48Spatrick Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1); 82609467b48Spatrick Type *Ty = Add.getType(); 82709467b48Spatrick Constant *Op1C; 82809467b48Spatrick if (!match(Op1, m_Constant(Op1C))) 82909467b48Spatrick return nullptr; 83009467b48Spatrick 83109467b48Spatrick // Try this match first because it results in an add in the narrow type. 83209467b48Spatrick // (zext (X +nuw C2)) + C1 --> zext (X + (C2 + trunc(C1))) 83309467b48Spatrick Value *X; 83409467b48Spatrick const APInt *C1, *C2; 83509467b48Spatrick if (match(Op1, m_APInt(C1)) && 83609467b48Spatrick match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2))))) && 83709467b48Spatrick C1->isNegative() && C1->sge(-C2->sext(C1->getBitWidth()))) { 83809467b48Spatrick Constant *NewC = 83909467b48Spatrick ConstantInt::get(X->getType(), *C2 + C1->trunc(C2->getBitWidth())); 84009467b48Spatrick return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty); 84109467b48Spatrick } 84209467b48Spatrick 84309467b48Spatrick // More general combining of constants in the wide type. 84409467b48Spatrick // (sext (X +nsw NarrowC)) + C --> (sext X) + (sext(NarrowC) + C) 84509467b48Spatrick Constant *NarrowC; 84609467b48Spatrick if (match(Op0, m_OneUse(m_SExt(m_NSWAdd(m_Value(X), m_Constant(NarrowC)))))) { 84709467b48Spatrick Constant *WideC = ConstantExpr::getSExt(NarrowC, Ty); 84809467b48Spatrick Constant *NewC = ConstantExpr::getAdd(WideC, Op1C); 84909467b48Spatrick Value *WideX = Builder.CreateSExt(X, Ty); 85009467b48Spatrick return BinaryOperator::CreateAdd(WideX, NewC); 85109467b48Spatrick } 85209467b48Spatrick // (zext (X +nuw NarrowC)) + C --> (zext X) + (zext(NarrowC) + C) 85309467b48Spatrick if (match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_Constant(NarrowC)))))) { 85409467b48Spatrick Constant *WideC = ConstantExpr::getZExt(NarrowC, Ty); 85509467b48Spatrick Constant *NewC = ConstantExpr::getAdd(WideC, Op1C); 85609467b48Spatrick Value *WideX = Builder.CreateZExt(X, Ty); 85709467b48Spatrick return BinaryOperator::CreateAdd(WideX, NewC); 85809467b48Spatrick } 85909467b48Spatrick 86009467b48Spatrick return nullptr; 86109467b48Spatrick } 86209467b48Spatrick 86309467b48Spatrick Instruction *InstCombiner::foldAddWithConstant(BinaryOperator &Add) { 86409467b48Spatrick Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1); 86509467b48Spatrick Constant *Op1C; 86609467b48Spatrick if (!match(Op1, m_Constant(Op1C))) 86709467b48Spatrick return nullptr; 86809467b48Spatrick 86909467b48Spatrick if (Instruction *NV = foldBinOpIntoSelectOrPhi(Add)) 87009467b48Spatrick return NV; 87109467b48Spatrick 87209467b48Spatrick Value *X; 87309467b48Spatrick Constant *Op00C; 87409467b48Spatrick 87509467b48Spatrick // add (sub C1, X), C2 --> sub (add C1, C2), X 87609467b48Spatrick if (match(Op0, m_Sub(m_Constant(Op00C), m_Value(X)))) 87709467b48Spatrick return BinaryOperator::CreateSub(ConstantExpr::getAdd(Op00C, Op1C), X); 87809467b48Spatrick 87909467b48Spatrick Value *Y; 88009467b48Spatrick 88109467b48Spatrick // add (sub X, Y), -1 --> add (not Y), X 88209467b48Spatrick if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))) && 88309467b48Spatrick match(Op1, m_AllOnes())) 88409467b48Spatrick return BinaryOperator::CreateAdd(Builder.CreateNot(Y), X); 88509467b48Spatrick 88609467b48Spatrick // zext(bool) + C -> bool ? C + 1 : C 88709467b48Spatrick if (match(Op0, m_ZExt(m_Value(X))) && 88809467b48Spatrick X->getType()->getScalarSizeInBits() == 1) 88909467b48Spatrick return SelectInst::Create(X, AddOne(Op1C), Op1); 89009467b48Spatrick // sext(bool) + C -> bool ? C - 1 : C 89109467b48Spatrick if (match(Op0, m_SExt(m_Value(X))) && 89209467b48Spatrick X->getType()->getScalarSizeInBits() == 1) 89309467b48Spatrick return SelectInst::Create(X, SubOne(Op1C), Op1); 89409467b48Spatrick 89509467b48Spatrick // ~X + C --> (C-1) - X 89609467b48Spatrick if (match(Op0, m_Not(m_Value(X)))) 89709467b48Spatrick return BinaryOperator::CreateSub(SubOne(Op1C), X); 89809467b48Spatrick 89909467b48Spatrick const APInt *C; 90009467b48Spatrick if (!match(Op1, m_APInt(C))) 90109467b48Spatrick return nullptr; 90209467b48Spatrick 90309467b48Spatrick // (X | C2) + C --> (X | C2) ^ C2 iff (C2 == -C) 90409467b48Spatrick const APInt *C2; 90509467b48Spatrick if (match(Op0, m_Or(m_Value(), m_APInt(C2))) && *C2 == -*C) 90609467b48Spatrick return BinaryOperator::CreateXor(Op0, ConstantInt::get(Add.getType(), *C2)); 90709467b48Spatrick 90809467b48Spatrick if (C->isSignMask()) { 90909467b48Spatrick // If wrapping is not allowed, then the addition must set the sign bit: 91009467b48Spatrick // X + (signmask) --> X | signmask 91109467b48Spatrick if (Add.hasNoSignedWrap() || Add.hasNoUnsignedWrap()) 91209467b48Spatrick return BinaryOperator::CreateOr(Op0, Op1); 91309467b48Spatrick 91409467b48Spatrick // If wrapping is allowed, then the addition flips the sign bit of LHS: 91509467b48Spatrick // X + (signmask) --> X ^ signmask 91609467b48Spatrick return BinaryOperator::CreateXor(Op0, Op1); 91709467b48Spatrick } 91809467b48Spatrick 91909467b48Spatrick // Is this add the last step in a convoluted sext? 92009467b48Spatrick // add(zext(xor i16 X, -32768), -32768) --> sext X 92109467b48Spatrick Type *Ty = Add.getType(); 92209467b48Spatrick if (match(Op0, m_ZExt(m_Xor(m_Value(X), m_APInt(C2)))) && 92309467b48Spatrick C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C) 92409467b48Spatrick return CastInst::Create(Instruction::SExt, X, Ty); 92509467b48Spatrick 92609467b48Spatrick if (C->isOneValue() && Op0->hasOneUse()) { 92709467b48Spatrick // add (sext i1 X), 1 --> zext (not X) 92809467b48Spatrick // TODO: The smallest IR representation is (select X, 0, 1), and that would 92909467b48Spatrick // not require the one-use check. But we need to remove a transform in 93009467b48Spatrick // visitSelect and make sure that IR value tracking for select is equal or 93109467b48Spatrick // better than for these ops. 93209467b48Spatrick if (match(Op0, m_SExt(m_Value(X))) && 93309467b48Spatrick X->getType()->getScalarSizeInBits() == 1) 93409467b48Spatrick return new ZExtInst(Builder.CreateNot(X), Ty); 93509467b48Spatrick 93609467b48Spatrick // Shifts and add used to flip and mask off the low bit: 93709467b48Spatrick // add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1 93809467b48Spatrick const APInt *C3; 93909467b48Spatrick if (match(Op0, m_AShr(m_Shl(m_Value(X), m_APInt(C2)), m_APInt(C3))) && 94009467b48Spatrick C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) { 94109467b48Spatrick Value *NotX = Builder.CreateNot(X); 94209467b48Spatrick return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1)); 94309467b48Spatrick } 94409467b48Spatrick } 94509467b48Spatrick 94609467b48Spatrick return nullptr; 94709467b48Spatrick } 94809467b48Spatrick 94909467b48Spatrick // Matches multiplication expression Op * C where C is a constant. Returns the 95009467b48Spatrick // constant value in C and the other operand in Op. Returns true if such a 95109467b48Spatrick // match is found. 95209467b48Spatrick static bool MatchMul(Value *E, Value *&Op, APInt &C) { 95309467b48Spatrick const APInt *AI; 95409467b48Spatrick if (match(E, m_Mul(m_Value(Op), m_APInt(AI)))) { 95509467b48Spatrick C = *AI; 95609467b48Spatrick return true; 95709467b48Spatrick } 95809467b48Spatrick if (match(E, m_Shl(m_Value(Op), m_APInt(AI)))) { 95909467b48Spatrick C = APInt(AI->getBitWidth(), 1); 96009467b48Spatrick C <<= *AI; 96109467b48Spatrick return true; 96209467b48Spatrick } 96309467b48Spatrick return false; 96409467b48Spatrick } 96509467b48Spatrick 96609467b48Spatrick // Matches remainder expression Op % C where C is a constant. Returns the 96709467b48Spatrick // constant value in C and the other operand in Op. Returns the signedness of 96809467b48Spatrick // the remainder operation in IsSigned. Returns true if such a match is 96909467b48Spatrick // found. 97009467b48Spatrick static bool MatchRem(Value *E, Value *&Op, APInt &C, bool &IsSigned) { 97109467b48Spatrick const APInt *AI; 97209467b48Spatrick IsSigned = false; 97309467b48Spatrick if (match(E, m_SRem(m_Value(Op), m_APInt(AI)))) { 97409467b48Spatrick IsSigned = true; 97509467b48Spatrick C = *AI; 97609467b48Spatrick return true; 97709467b48Spatrick } 97809467b48Spatrick if (match(E, m_URem(m_Value(Op), m_APInt(AI)))) { 97909467b48Spatrick C = *AI; 98009467b48Spatrick return true; 98109467b48Spatrick } 98209467b48Spatrick if (match(E, m_And(m_Value(Op), m_APInt(AI))) && (*AI + 1).isPowerOf2()) { 98309467b48Spatrick C = *AI + 1; 98409467b48Spatrick return true; 98509467b48Spatrick } 98609467b48Spatrick return false; 98709467b48Spatrick } 98809467b48Spatrick 98909467b48Spatrick // Matches division expression Op / C with the given signedness as indicated 99009467b48Spatrick // by IsSigned, where C is a constant. Returns the constant value in C and the 99109467b48Spatrick // other operand in Op. Returns true if such a match is found. 99209467b48Spatrick static bool MatchDiv(Value *E, Value *&Op, APInt &C, bool IsSigned) { 99309467b48Spatrick const APInt *AI; 99409467b48Spatrick if (IsSigned && match(E, m_SDiv(m_Value(Op), m_APInt(AI)))) { 99509467b48Spatrick C = *AI; 99609467b48Spatrick return true; 99709467b48Spatrick } 99809467b48Spatrick if (!IsSigned) { 99909467b48Spatrick if (match(E, m_UDiv(m_Value(Op), m_APInt(AI)))) { 100009467b48Spatrick C = *AI; 100109467b48Spatrick return true; 100209467b48Spatrick } 100309467b48Spatrick if (match(E, m_LShr(m_Value(Op), m_APInt(AI)))) { 100409467b48Spatrick C = APInt(AI->getBitWidth(), 1); 100509467b48Spatrick C <<= *AI; 100609467b48Spatrick return true; 100709467b48Spatrick } 100809467b48Spatrick } 100909467b48Spatrick return false; 101009467b48Spatrick } 101109467b48Spatrick 101209467b48Spatrick // Returns whether C0 * C1 with the given signedness overflows. 101309467b48Spatrick static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned) { 101409467b48Spatrick bool overflow; 101509467b48Spatrick if (IsSigned) 101609467b48Spatrick (void)C0.smul_ov(C1, overflow); 101709467b48Spatrick else 101809467b48Spatrick (void)C0.umul_ov(C1, overflow); 101909467b48Spatrick return overflow; 102009467b48Spatrick } 102109467b48Spatrick 102209467b48Spatrick // Simplifies X % C0 + (( X / C0 ) % C1) * C0 to X % (C0 * C1), where (C0 * C1) 102309467b48Spatrick // does not overflow. 102409467b48Spatrick Value *InstCombiner::SimplifyAddWithRemainder(BinaryOperator &I) { 102509467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 102609467b48Spatrick Value *X, *MulOpV; 102709467b48Spatrick APInt C0, MulOpC; 102809467b48Spatrick bool IsSigned; 102909467b48Spatrick // Match I = X % C0 + MulOpV * C0 103009467b48Spatrick if (((MatchRem(LHS, X, C0, IsSigned) && MatchMul(RHS, MulOpV, MulOpC)) || 103109467b48Spatrick (MatchRem(RHS, X, C0, IsSigned) && MatchMul(LHS, MulOpV, MulOpC))) && 103209467b48Spatrick C0 == MulOpC) { 103309467b48Spatrick Value *RemOpV; 103409467b48Spatrick APInt C1; 103509467b48Spatrick bool Rem2IsSigned; 103609467b48Spatrick // Match MulOpC = RemOpV % C1 103709467b48Spatrick if (MatchRem(MulOpV, RemOpV, C1, Rem2IsSigned) && 103809467b48Spatrick IsSigned == Rem2IsSigned) { 103909467b48Spatrick Value *DivOpV; 104009467b48Spatrick APInt DivOpC; 104109467b48Spatrick // Match RemOpV = X / C0 104209467b48Spatrick if (MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) && X == DivOpV && 104309467b48Spatrick C0 == DivOpC && !MulWillOverflow(C0, C1, IsSigned)) { 1044*097a140dSpatrick Value *NewDivisor = ConstantInt::get(X->getType(), C0 * C1); 104509467b48Spatrick return IsSigned ? Builder.CreateSRem(X, NewDivisor, "srem") 104609467b48Spatrick : Builder.CreateURem(X, NewDivisor, "urem"); 104709467b48Spatrick } 104809467b48Spatrick } 104909467b48Spatrick } 105009467b48Spatrick 105109467b48Spatrick return nullptr; 105209467b48Spatrick } 105309467b48Spatrick 105409467b48Spatrick /// Fold 105509467b48Spatrick /// (1 << NBits) - 1 105609467b48Spatrick /// Into: 105709467b48Spatrick /// ~(-(1 << NBits)) 105809467b48Spatrick /// Because a 'not' is better for bit-tracking analysis and other transforms 105909467b48Spatrick /// than an 'add'. The new shl is always nsw, and is nuw if old `and` was. 106009467b48Spatrick static Instruction *canonicalizeLowbitMask(BinaryOperator &I, 106109467b48Spatrick InstCombiner::BuilderTy &Builder) { 106209467b48Spatrick Value *NBits; 106309467b48Spatrick if (!match(&I, m_Add(m_OneUse(m_Shl(m_One(), m_Value(NBits))), m_AllOnes()))) 106409467b48Spatrick return nullptr; 106509467b48Spatrick 106609467b48Spatrick Constant *MinusOne = Constant::getAllOnesValue(NBits->getType()); 106709467b48Spatrick Value *NotMask = Builder.CreateShl(MinusOne, NBits, "notmask"); 106809467b48Spatrick // Be wary of constant folding. 106909467b48Spatrick if (auto *BOp = dyn_cast<BinaryOperator>(NotMask)) { 107009467b48Spatrick // Always NSW. But NUW propagates from `add`. 107109467b48Spatrick BOp->setHasNoSignedWrap(); 107209467b48Spatrick BOp->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); 107309467b48Spatrick } 107409467b48Spatrick 107509467b48Spatrick return BinaryOperator::CreateNot(NotMask, I.getName()); 107609467b48Spatrick } 107709467b48Spatrick 107809467b48Spatrick static Instruction *foldToUnsignedSaturatedAdd(BinaryOperator &I) { 107909467b48Spatrick assert(I.getOpcode() == Instruction::Add && "Expecting add instruction"); 108009467b48Spatrick Type *Ty = I.getType(); 108109467b48Spatrick auto getUAddSat = [&]() { 108209467b48Spatrick return Intrinsic::getDeclaration(I.getModule(), Intrinsic::uadd_sat, Ty); 108309467b48Spatrick }; 108409467b48Spatrick 108509467b48Spatrick // add (umin X, ~Y), Y --> uaddsat X, Y 108609467b48Spatrick Value *X, *Y; 108709467b48Spatrick if (match(&I, m_c_Add(m_c_UMin(m_Value(X), m_Not(m_Value(Y))), 108809467b48Spatrick m_Deferred(Y)))) 108909467b48Spatrick return CallInst::Create(getUAddSat(), { X, Y }); 109009467b48Spatrick 109109467b48Spatrick // add (umin X, ~C), C --> uaddsat X, C 109209467b48Spatrick const APInt *C, *NotC; 109309467b48Spatrick if (match(&I, m_Add(m_UMin(m_Value(X), m_APInt(NotC)), m_APInt(C))) && 109409467b48Spatrick *C == ~*NotC) 109509467b48Spatrick return CallInst::Create(getUAddSat(), { X, ConstantInt::get(Ty, *C) }); 109609467b48Spatrick 109709467b48Spatrick return nullptr; 109809467b48Spatrick } 109909467b48Spatrick 110009467b48Spatrick Instruction * 110109467b48Spatrick InstCombiner::canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract( 110209467b48Spatrick BinaryOperator &I) { 110309467b48Spatrick assert((I.getOpcode() == Instruction::Add || 110409467b48Spatrick I.getOpcode() == Instruction::Or || 110509467b48Spatrick I.getOpcode() == Instruction::Sub) && 110609467b48Spatrick "Expecting add/or/sub instruction"); 110709467b48Spatrick 110809467b48Spatrick // We have a subtraction/addition between a (potentially truncated) *logical* 110909467b48Spatrick // right-shift of X and a "select". 111009467b48Spatrick Value *X, *Select; 111109467b48Spatrick Instruction *LowBitsToSkip, *Extract; 111209467b48Spatrick if (!match(&I, m_c_BinOp(m_TruncOrSelf(m_CombineAnd( 111309467b48Spatrick m_LShr(m_Value(X), m_Instruction(LowBitsToSkip)), 111409467b48Spatrick m_Instruction(Extract))), 111509467b48Spatrick m_Value(Select)))) 111609467b48Spatrick return nullptr; 111709467b48Spatrick 111809467b48Spatrick // `add`/`or` is commutative; but for `sub`, "select" *must* be on RHS. 111909467b48Spatrick if (I.getOpcode() == Instruction::Sub && I.getOperand(1) != Select) 112009467b48Spatrick return nullptr; 112109467b48Spatrick 112209467b48Spatrick Type *XTy = X->getType(); 112309467b48Spatrick bool HadTrunc = I.getType() != XTy; 112409467b48Spatrick 112509467b48Spatrick // If there was a truncation of extracted value, then we'll need to produce 112609467b48Spatrick // one extra instruction, so we need to ensure one instruction will go away. 112709467b48Spatrick if (HadTrunc && !match(&I, m_c_BinOp(m_OneUse(m_Value()), m_Value()))) 112809467b48Spatrick return nullptr; 112909467b48Spatrick 113009467b48Spatrick // Extraction should extract high NBits bits, with shift amount calculated as: 113109467b48Spatrick // low bits to skip = shift bitwidth - high bits to extract 113209467b48Spatrick // The shift amount itself may be extended, and we need to look past zero-ext 113309467b48Spatrick // when matching NBits, that will matter for matching later. 113409467b48Spatrick Constant *C; 113509467b48Spatrick Value *NBits; 113609467b48Spatrick if (!match( 113709467b48Spatrick LowBitsToSkip, 113809467b48Spatrick m_ZExtOrSelf(m_Sub(m_Constant(C), m_ZExtOrSelf(m_Value(NBits))))) || 113909467b48Spatrick !match(C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, 114009467b48Spatrick APInt(C->getType()->getScalarSizeInBits(), 114109467b48Spatrick X->getType()->getScalarSizeInBits())))) 114209467b48Spatrick return nullptr; 114309467b48Spatrick 114409467b48Spatrick // Sign-extending value can be zero-extended if we `sub`tract it, 114509467b48Spatrick // or sign-extended otherwise. 114609467b48Spatrick auto SkipExtInMagic = [&I](Value *&V) { 114709467b48Spatrick if (I.getOpcode() == Instruction::Sub) 114809467b48Spatrick match(V, m_ZExtOrSelf(m_Value(V))); 114909467b48Spatrick else 115009467b48Spatrick match(V, m_SExtOrSelf(m_Value(V))); 115109467b48Spatrick }; 115209467b48Spatrick 115309467b48Spatrick // Now, finally validate the sign-extending magic. 115409467b48Spatrick // `select` itself may be appropriately extended, look past that. 115509467b48Spatrick SkipExtInMagic(Select); 115609467b48Spatrick 115709467b48Spatrick ICmpInst::Predicate Pred; 115809467b48Spatrick const APInt *Thr; 115909467b48Spatrick Value *SignExtendingValue, *Zero; 116009467b48Spatrick bool ShouldSignext; 116109467b48Spatrick // It must be a select between two values we will later establish to be a 116209467b48Spatrick // sign-extending value and a zero constant. The condition guarding the 116309467b48Spatrick // sign-extension must be based on a sign bit of the same X we had in `lshr`. 116409467b48Spatrick if (!match(Select, m_Select(m_ICmp(Pred, m_Specific(X), m_APInt(Thr)), 116509467b48Spatrick m_Value(SignExtendingValue), m_Value(Zero))) || 116609467b48Spatrick !isSignBitCheck(Pred, *Thr, ShouldSignext)) 116709467b48Spatrick return nullptr; 116809467b48Spatrick 116909467b48Spatrick // icmp-select pair is commutative. 117009467b48Spatrick if (!ShouldSignext) 117109467b48Spatrick std::swap(SignExtendingValue, Zero); 117209467b48Spatrick 117309467b48Spatrick // If we should not perform sign-extension then we must add/or/subtract zero. 117409467b48Spatrick if (!match(Zero, m_Zero())) 117509467b48Spatrick return nullptr; 117609467b48Spatrick // Otherwise, it should be some constant, left-shifted by the same NBits we 117709467b48Spatrick // had in `lshr`. Said left-shift can also be appropriately extended. 117809467b48Spatrick // Again, we must look past zero-ext when looking for NBits. 117909467b48Spatrick SkipExtInMagic(SignExtendingValue); 118009467b48Spatrick Constant *SignExtendingValueBaseConstant; 118109467b48Spatrick if (!match(SignExtendingValue, 118209467b48Spatrick m_Shl(m_Constant(SignExtendingValueBaseConstant), 118309467b48Spatrick m_ZExtOrSelf(m_Specific(NBits))))) 118409467b48Spatrick return nullptr; 118509467b48Spatrick // If we `sub`, then the constant should be one, else it should be all-ones. 118609467b48Spatrick if (I.getOpcode() == Instruction::Sub 118709467b48Spatrick ? !match(SignExtendingValueBaseConstant, m_One()) 118809467b48Spatrick : !match(SignExtendingValueBaseConstant, m_AllOnes())) 118909467b48Spatrick return nullptr; 119009467b48Spatrick 119109467b48Spatrick auto *NewAShr = BinaryOperator::CreateAShr(X, LowBitsToSkip, 119209467b48Spatrick Extract->getName() + ".sext"); 119309467b48Spatrick NewAShr->copyIRFlags(Extract); // Preserve `exact`-ness. 119409467b48Spatrick if (!HadTrunc) 119509467b48Spatrick return NewAShr; 119609467b48Spatrick 119709467b48Spatrick Builder.Insert(NewAShr); 119809467b48Spatrick return TruncInst::CreateTruncOrBitCast(NewAShr, I.getType()); 119909467b48Spatrick } 120009467b48Spatrick 120109467b48Spatrick Instruction *InstCombiner::visitAdd(BinaryOperator &I) { 120209467b48Spatrick if (Value *V = SimplifyAddInst(I.getOperand(0), I.getOperand(1), 120309467b48Spatrick I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), 120409467b48Spatrick SQ.getWithInstruction(&I))) 120509467b48Spatrick return replaceInstUsesWith(I, V); 120609467b48Spatrick 120709467b48Spatrick if (SimplifyAssociativeOrCommutative(I)) 120809467b48Spatrick return &I; 120909467b48Spatrick 121009467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 121109467b48Spatrick return X; 121209467b48Spatrick 121309467b48Spatrick // (A*B)+(A*C) -> A*(B+C) etc 121409467b48Spatrick if (Value *V = SimplifyUsingDistributiveLaws(I)) 121509467b48Spatrick return replaceInstUsesWith(I, V); 121609467b48Spatrick 121709467b48Spatrick if (Instruction *X = foldAddWithConstant(I)) 121809467b48Spatrick return X; 121909467b48Spatrick 122009467b48Spatrick if (Instruction *X = foldNoWrapAdd(I, Builder)) 122109467b48Spatrick return X; 122209467b48Spatrick 122309467b48Spatrick // FIXME: This should be moved into the above helper function to allow these 122409467b48Spatrick // transforms for general constant or constant splat vectors. 122509467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 122609467b48Spatrick Type *Ty = I.getType(); 122709467b48Spatrick if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { 122809467b48Spatrick Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr; 122909467b48Spatrick if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { 123009467b48Spatrick unsigned TySizeBits = Ty->getScalarSizeInBits(); 123109467b48Spatrick const APInt &RHSVal = CI->getValue(); 123209467b48Spatrick unsigned ExtendAmt = 0; 123309467b48Spatrick // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. 123409467b48Spatrick // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. 123509467b48Spatrick if (XorRHS->getValue() == -RHSVal) { 123609467b48Spatrick if (RHSVal.isPowerOf2()) 123709467b48Spatrick ExtendAmt = TySizeBits - RHSVal.logBase2() - 1; 123809467b48Spatrick else if (XorRHS->getValue().isPowerOf2()) 123909467b48Spatrick ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1; 124009467b48Spatrick } 124109467b48Spatrick 124209467b48Spatrick if (ExtendAmt) { 124309467b48Spatrick APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt); 124409467b48Spatrick if (!MaskedValueIsZero(XorLHS, Mask, 0, &I)) 124509467b48Spatrick ExtendAmt = 0; 124609467b48Spatrick } 124709467b48Spatrick 124809467b48Spatrick if (ExtendAmt) { 124909467b48Spatrick Constant *ShAmt = ConstantInt::get(Ty, ExtendAmt); 125009467b48Spatrick Value *NewShl = Builder.CreateShl(XorLHS, ShAmt, "sext"); 125109467b48Spatrick return BinaryOperator::CreateAShr(NewShl, ShAmt); 125209467b48Spatrick } 125309467b48Spatrick 125409467b48Spatrick // If this is a xor that was canonicalized from a sub, turn it back into 125509467b48Spatrick // a sub and fuse this add with it. 125609467b48Spatrick if (LHS->hasOneUse() && (XorRHS->getValue()+1).isPowerOf2()) { 125709467b48Spatrick KnownBits LHSKnown = computeKnownBits(XorLHS, 0, &I); 125809467b48Spatrick if ((XorRHS->getValue() | LHSKnown.Zero).isAllOnesValue()) 125909467b48Spatrick return BinaryOperator::CreateSub(ConstantExpr::getAdd(XorRHS, CI), 126009467b48Spatrick XorLHS); 126109467b48Spatrick } 126209467b48Spatrick // (X + signmask) + C could have gotten canonicalized to (X^signmask) + C, 126309467b48Spatrick // transform them into (X + (signmask ^ C)) 126409467b48Spatrick if (XorRHS->getValue().isSignMask()) 126509467b48Spatrick return BinaryOperator::CreateAdd(XorLHS, 126609467b48Spatrick ConstantExpr::getXor(XorRHS, CI)); 126709467b48Spatrick } 126809467b48Spatrick } 126909467b48Spatrick 127009467b48Spatrick if (Ty->isIntOrIntVectorTy(1)) 127109467b48Spatrick return BinaryOperator::CreateXor(LHS, RHS); 127209467b48Spatrick 127309467b48Spatrick // X + X --> X << 1 127409467b48Spatrick if (LHS == RHS) { 127509467b48Spatrick auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1)); 127609467b48Spatrick Shl->setHasNoSignedWrap(I.hasNoSignedWrap()); 127709467b48Spatrick Shl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); 127809467b48Spatrick return Shl; 127909467b48Spatrick } 128009467b48Spatrick 128109467b48Spatrick Value *A, *B; 128209467b48Spatrick if (match(LHS, m_Neg(m_Value(A)))) { 128309467b48Spatrick // -A + -B --> -(A + B) 128409467b48Spatrick if (match(RHS, m_Neg(m_Value(B)))) 128509467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateAdd(A, B)); 128609467b48Spatrick 128709467b48Spatrick // -A + B --> B - A 128809467b48Spatrick return BinaryOperator::CreateSub(RHS, A); 128909467b48Spatrick } 129009467b48Spatrick 129109467b48Spatrick // A + -B --> A - B 129209467b48Spatrick if (match(RHS, m_Neg(m_Value(B)))) 129309467b48Spatrick return BinaryOperator::CreateSub(LHS, B); 129409467b48Spatrick 129509467b48Spatrick if (Value *V = checkForNegativeOperand(I, Builder)) 129609467b48Spatrick return replaceInstUsesWith(I, V); 129709467b48Spatrick 129809467b48Spatrick // (A + 1) + ~B --> A - B 129909467b48Spatrick // ~B + (A + 1) --> A - B 130009467b48Spatrick // (~B + A) + 1 --> A - B 130109467b48Spatrick // (A + ~B) + 1 --> A - B 130209467b48Spatrick if (match(&I, m_c_BinOp(m_Add(m_Value(A), m_One()), m_Not(m_Value(B)))) || 130309467b48Spatrick match(&I, m_BinOp(m_c_Add(m_Not(m_Value(B)), m_Value(A)), m_One()))) 130409467b48Spatrick return BinaryOperator::CreateSub(A, B); 130509467b48Spatrick 1306*097a140dSpatrick // (A + RHS) + RHS --> A + (RHS << 1) 1307*097a140dSpatrick if (match(LHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(RHS))))) 1308*097a140dSpatrick return BinaryOperator::CreateAdd(A, Builder.CreateShl(RHS, 1, "reass.add")); 1309*097a140dSpatrick 1310*097a140dSpatrick // LHS + (A + LHS) --> A + (LHS << 1) 1311*097a140dSpatrick if (match(RHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(LHS))))) 1312*097a140dSpatrick return BinaryOperator::CreateAdd(A, Builder.CreateShl(LHS, 1, "reass.add")); 1313*097a140dSpatrick 131409467b48Spatrick // X % C0 + (( X / C0 ) % C1) * C0 => X % (C0 * C1) 131509467b48Spatrick if (Value *V = SimplifyAddWithRemainder(I)) return replaceInstUsesWith(I, V); 131609467b48Spatrick 1317*097a140dSpatrick // ((X s/ C1) << C2) + X => X s% -C1 where -C1 is 1 << C2 1318*097a140dSpatrick const APInt *C1, *C2; 1319*097a140dSpatrick if (match(LHS, m_Shl(m_SDiv(m_Specific(RHS), m_APInt(C1)), m_APInt(C2)))) { 1320*097a140dSpatrick APInt one(C2->getBitWidth(), 1); 1321*097a140dSpatrick APInt minusC1 = -(*C1); 1322*097a140dSpatrick if (minusC1 == (one << *C2)) { 1323*097a140dSpatrick Constant *NewRHS = ConstantInt::get(RHS->getType(), minusC1); 1324*097a140dSpatrick return BinaryOperator::CreateSRem(RHS, NewRHS); 1325*097a140dSpatrick } 1326*097a140dSpatrick } 1327*097a140dSpatrick 132809467b48Spatrick // A+B --> A|B iff A and B have no bits set in common. 132909467b48Spatrick if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT)) 133009467b48Spatrick return BinaryOperator::CreateOr(LHS, RHS); 133109467b48Spatrick 133209467b48Spatrick // FIXME: We already did a check for ConstantInt RHS above this. 133309467b48Spatrick // FIXME: Is this pattern covered by another fold? No regression tests fail on 133409467b48Spatrick // removal. 133509467b48Spatrick if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) { 133609467b48Spatrick // (X & FF00) + xx00 -> (X+xx00) & FF00 133709467b48Spatrick Value *X; 133809467b48Spatrick ConstantInt *C2; 133909467b48Spatrick if (LHS->hasOneUse() && 134009467b48Spatrick match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) && 134109467b48Spatrick CRHS->getValue() == (CRHS->getValue() & C2->getValue())) { 134209467b48Spatrick // See if all bits from the first bit set in the Add RHS up are included 134309467b48Spatrick // in the mask. First, get the rightmost bit. 134409467b48Spatrick const APInt &AddRHSV = CRHS->getValue(); 134509467b48Spatrick 134609467b48Spatrick // Form a mask of all bits from the lowest bit added through the top. 134709467b48Spatrick APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1)); 134809467b48Spatrick 134909467b48Spatrick // See if the and mask includes all of these bits. 135009467b48Spatrick APInt AddRHSHighBitsAnd(AddRHSHighBits & C2->getValue()); 135109467b48Spatrick 135209467b48Spatrick if (AddRHSHighBits == AddRHSHighBitsAnd) { 135309467b48Spatrick // Okay, the xform is safe. Insert the new add pronto. 135409467b48Spatrick Value *NewAdd = Builder.CreateAdd(X, CRHS, LHS->getName()); 135509467b48Spatrick return BinaryOperator::CreateAnd(NewAdd, C2); 135609467b48Spatrick } 135709467b48Spatrick } 135809467b48Spatrick } 135909467b48Spatrick 136009467b48Spatrick // add (select X 0 (sub n A)) A --> select X A n 136109467b48Spatrick { 136209467b48Spatrick SelectInst *SI = dyn_cast<SelectInst>(LHS); 136309467b48Spatrick Value *A = RHS; 136409467b48Spatrick if (!SI) { 136509467b48Spatrick SI = dyn_cast<SelectInst>(RHS); 136609467b48Spatrick A = LHS; 136709467b48Spatrick } 136809467b48Spatrick if (SI && SI->hasOneUse()) { 136909467b48Spatrick Value *TV = SI->getTrueValue(); 137009467b48Spatrick Value *FV = SI->getFalseValue(); 137109467b48Spatrick Value *N; 137209467b48Spatrick 137309467b48Spatrick // Can we fold the add into the argument of the select? 137409467b48Spatrick // We check both true and false select arguments for a matching subtract. 137509467b48Spatrick if (match(FV, m_Zero()) && match(TV, m_Sub(m_Value(N), m_Specific(A)))) 137609467b48Spatrick // Fold the add into the true select value. 137709467b48Spatrick return SelectInst::Create(SI->getCondition(), N, A); 137809467b48Spatrick 137909467b48Spatrick if (match(TV, m_Zero()) && match(FV, m_Sub(m_Value(N), m_Specific(A)))) 138009467b48Spatrick // Fold the add into the false select value. 138109467b48Spatrick return SelectInst::Create(SI->getCondition(), A, N); 138209467b48Spatrick } 138309467b48Spatrick } 138409467b48Spatrick 138509467b48Spatrick if (Instruction *Ext = narrowMathIfNoOverflow(I)) 138609467b48Spatrick return Ext; 138709467b48Spatrick 138809467b48Spatrick // (add (xor A, B) (and A, B)) --> (or A, B) 138909467b48Spatrick // (add (and A, B) (xor A, B)) --> (or A, B) 139009467b48Spatrick if (match(&I, m_c_BinOp(m_Xor(m_Value(A), m_Value(B)), 139109467b48Spatrick m_c_And(m_Deferred(A), m_Deferred(B))))) 139209467b48Spatrick return BinaryOperator::CreateOr(A, B); 139309467b48Spatrick 139409467b48Spatrick // (add (or A, B) (and A, B)) --> (add A, B) 139509467b48Spatrick // (add (and A, B) (or A, B)) --> (add A, B) 139609467b48Spatrick if (match(&I, m_c_BinOp(m_Or(m_Value(A), m_Value(B)), 139709467b48Spatrick m_c_And(m_Deferred(A), m_Deferred(B))))) { 1398*097a140dSpatrick // Replacing operands in-place to preserve nuw/nsw flags. 1399*097a140dSpatrick replaceOperand(I, 0, A); 1400*097a140dSpatrick replaceOperand(I, 1, B); 140109467b48Spatrick return &I; 140209467b48Spatrick } 140309467b48Spatrick 140409467b48Spatrick // TODO(jingyue): Consider willNotOverflowSignedAdd and 140509467b48Spatrick // willNotOverflowUnsignedAdd to reduce the number of invocations of 140609467b48Spatrick // computeKnownBits. 140709467b48Spatrick bool Changed = false; 140809467b48Spatrick if (!I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHS, RHS, I)) { 140909467b48Spatrick Changed = true; 141009467b48Spatrick I.setHasNoSignedWrap(true); 141109467b48Spatrick } 141209467b48Spatrick if (!I.hasNoUnsignedWrap() && willNotOverflowUnsignedAdd(LHS, RHS, I)) { 141309467b48Spatrick Changed = true; 141409467b48Spatrick I.setHasNoUnsignedWrap(true); 141509467b48Spatrick } 141609467b48Spatrick 141709467b48Spatrick if (Instruction *V = canonicalizeLowbitMask(I, Builder)) 141809467b48Spatrick return V; 141909467b48Spatrick 142009467b48Spatrick if (Instruction *V = 142109467b48Spatrick canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I)) 142209467b48Spatrick return V; 142309467b48Spatrick 142409467b48Spatrick if (Instruction *SatAdd = foldToUnsignedSaturatedAdd(I)) 142509467b48Spatrick return SatAdd; 142609467b48Spatrick 142709467b48Spatrick return Changed ? &I : nullptr; 142809467b48Spatrick } 142909467b48Spatrick 143009467b48Spatrick /// Eliminate an op from a linear interpolation (lerp) pattern. 143109467b48Spatrick static Instruction *factorizeLerp(BinaryOperator &I, 143209467b48Spatrick InstCombiner::BuilderTy &Builder) { 143309467b48Spatrick Value *X, *Y, *Z; 143409467b48Spatrick if (!match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_Value(Y), 143509467b48Spatrick m_OneUse(m_FSub(m_FPOne(), 143609467b48Spatrick m_Value(Z))))), 143709467b48Spatrick m_OneUse(m_c_FMul(m_Value(X), m_Deferred(Z)))))) 143809467b48Spatrick return nullptr; 143909467b48Spatrick 144009467b48Spatrick // (Y * (1.0 - Z)) + (X * Z) --> Y + Z * (X - Y) [8 commuted variants] 144109467b48Spatrick Value *XY = Builder.CreateFSubFMF(X, Y, &I); 144209467b48Spatrick Value *MulZ = Builder.CreateFMulFMF(Z, XY, &I); 144309467b48Spatrick return BinaryOperator::CreateFAddFMF(Y, MulZ, &I); 144409467b48Spatrick } 144509467b48Spatrick 144609467b48Spatrick /// Factor a common operand out of fadd/fsub of fmul/fdiv. 144709467b48Spatrick static Instruction *factorizeFAddFSub(BinaryOperator &I, 144809467b48Spatrick InstCombiner::BuilderTy &Builder) { 144909467b48Spatrick assert((I.getOpcode() == Instruction::FAdd || 145009467b48Spatrick I.getOpcode() == Instruction::FSub) && "Expecting fadd/fsub"); 145109467b48Spatrick assert(I.hasAllowReassoc() && I.hasNoSignedZeros() && 145209467b48Spatrick "FP factorization requires FMF"); 145309467b48Spatrick 145409467b48Spatrick if (Instruction *Lerp = factorizeLerp(I, Builder)) 145509467b48Spatrick return Lerp; 145609467b48Spatrick 145709467b48Spatrick Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 145809467b48Spatrick Value *X, *Y, *Z; 145909467b48Spatrick bool IsFMul; 146009467b48Spatrick if ((match(Op0, m_OneUse(m_FMul(m_Value(X), m_Value(Z)))) && 146109467b48Spatrick match(Op1, m_OneUse(m_c_FMul(m_Value(Y), m_Specific(Z))))) || 146209467b48Spatrick (match(Op0, m_OneUse(m_FMul(m_Value(Z), m_Value(X)))) && 146309467b48Spatrick match(Op1, m_OneUse(m_c_FMul(m_Value(Y), m_Specific(Z)))))) 146409467b48Spatrick IsFMul = true; 146509467b48Spatrick else if (match(Op0, m_OneUse(m_FDiv(m_Value(X), m_Value(Z)))) && 146609467b48Spatrick match(Op1, m_OneUse(m_FDiv(m_Value(Y), m_Specific(Z))))) 146709467b48Spatrick IsFMul = false; 146809467b48Spatrick else 146909467b48Spatrick return nullptr; 147009467b48Spatrick 147109467b48Spatrick // (X * Z) + (Y * Z) --> (X + Y) * Z 147209467b48Spatrick // (X * Z) - (Y * Z) --> (X - Y) * Z 147309467b48Spatrick // (X / Z) + (Y / Z) --> (X + Y) / Z 147409467b48Spatrick // (X / Z) - (Y / Z) --> (X - Y) / Z 147509467b48Spatrick bool IsFAdd = I.getOpcode() == Instruction::FAdd; 147609467b48Spatrick Value *XY = IsFAdd ? Builder.CreateFAddFMF(X, Y, &I) 147709467b48Spatrick : Builder.CreateFSubFMF(X, Y, &I); 147809467b48Spatrick 147909467b48Spatrick // Bail out if we just created a denormal constant. 148009467b48Spatrick // TODO: This is copied from a previous implementation. Is it necessary? 148109467b48Spatrick const APFloat *C; 148209467b48Spatrick if (match(XY, m_APFloat(C)) && !C->isNormal()) 148309467b48Spatrick return nullptr; 148409467b48Spatrick 148509467b48Spatrick return IsFMul ? BinaryOperator::CreateFMulFMF(XY, Z, &I) 148609467b48Spatrick : BinaryOperator::CreateFDivFMF(XY, Z, &I); 148709467b48Spatrick } 148809467b48Spatrick 148909467b48Spatrick Instruction *InstCombiner::visitFAdd(BinaryOperator &I) { 149009467b48Spatrick if (Value *V = SimplifyFAddInst(I.getOperand(0), I.getOperand(1), 149109467b48Spatrick I.getFastMathFlags(), 149209467b48Spatrick SQ.getWithInstruction(&I))) 149309467b48Spatrick return replaceInstUsesWith(I, V); 149409467b48Spatrick 149509467b48Spatrick if (SimplifyAssociativeOrCommutative(I)) 149609467b48Spatrick return &I; 149709467b48Spatrick 149809467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 149909467b48Spatrick return X; 150009467b48Spatrick 150109467b48Spatrick if (Instruction *FoldedFAdd = foldBinOpIntoSelectOrPhi(I)) 150209467b48Spatrick return FoldedFAdd; 150309467b48Spatrick 150409467b48Spatrick // (-X) + Y --> Y - X 150509467b48Spatrick Value *X, *Y; 150609467b48Spatrick if (match(&I, m_c_FAdd(m_FNeg(m_Value(X)), m_Value(Y)))) 150709467b48Spatrick return BinaryOperator::CreateFSubFMF(Y, X, &I); 150809467b48Spatrick 150909467b48Spatrick // Similar to above, but look through fmul/fdiv for the negated term. 151009467b48Spatrick // (-X * Y) + Z --> Z - (X * Y) [4 commuted variants] 151109467b48Spatrick Value *Z; 151209467b48Spatrick if (match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))), 151309467b48Spatrick m_Value(Z)))) { 151409467b48Spatrick Value *XY = Builder.CreateFMulFMF(X, Y, &I); 151509467b48Spatrick return BinaryOperator::CreateFSubFMF(Z, XY, &I); 151609467b48Spatrick } 151709467b48Spatrick // (-X / Y) + Z --> Z - (X / Y) [2 commuted variants] 151809467b48Spatrick // (X / -Y) + Z --> Z - (X / Y) [2 commuted variants] 151909467b48Spatrick if (match(&I, m_c_FAdd(m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y))), 152009467b48Spatrick m_Value(Z))) || 152109467b48Spatrick match(&I, m_c_FAdd(m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))), 152209467b48Spatrick m_Value(Z)))) { 152309467b48Spatrick Value *XY = Builder.CreateFDivFMF(X, Y, &I); 152409467b48Spatrick return BinaryOperator::CreateFSubFMF(Z, XY, &I); 152509467b48Spatrick } 152609467b48Spatrick 152709467b48Spatrick // Check for (fadd double (sitofp x), y), see if we can merge this into an 152809467b48Spatrick // integer add followed by a promotion. 152909467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 153009467b48Spatrick if (SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) { 153109467b48Spatrick Value *LHSIntVal = LHSConv->getOperand(0); 153209467b48Spatrick Type *FPType = LHSConv->getType(); 153309467b48Spatrick 153409467b48Spatrick // TODO: This check is overly conservative. In many cases known bits 153509467b48Spatrick // analysis can tell us that the result of the addition has less significant 153609467b48Spatrick // bits than the integer type can hold. 153709467b48Spatrick auto IsValidPromotion = [](Type *FTy, Type *ITy) { 153809467b48Spatrick Type *FScalarTy = FTy->getScalarType(); 153909467b48Spatrick Type *IScalarTy = ITy->getScalarType(); 154009467b48Spatrick 154109467b48Spatrick // Do we have enough bits in the significand to represent the result of 154209467b48Spatrick // the integer addition? 154309467b48Spatrick unsigned MaxRepresentableBits = 154409467b48Spatrick APFloat::semanticsPrecision(FScalarTy->getFltSemantics()); 154509467b48Spatrick return IScalarTy->getIntegerBitWidth() <= MaxRepresentableBits; 154609467b48Spatrick }; 154709467b48Spatrick 154809467b48Spatrick // (fadd double (sitofp x), fpcst) --> (sitofp (add int x, intcst)) 154909467b48Spatrick // ... if the constant fits in the integer value. This is useful for things 155009467b48Spatrick // like (double)(x & 1234) + 4.0 -> (double)((X & 1234)+4) which no longer 155109467b48Spatrick // requires a constant pool load, and generally allows the add to be better 155209467b48Spatrick // instcombined. 155309467b48Spatrick if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHS)) 155409467b48Spatrick if (IsValidPromotion(FPType, LHSIntVal->getType())) { 155509467b48Spatrick Constant *CI = 155609467b48Spatrick ConstantExpr::getFPToSI(CFP, LHSIntVal->getType()); 155709467b48Spatrick if (LHSConv->hasOneUse() && 155809467b48Spatrick ConstantExpr::getSIToFP(CI, I.getType()) == CFP && 155909467b48Spatrick willNotOverflowSignedAdd(LHSIntVal, CI, I)) { 156009467b48Spatrick // Insert the new integer add. 156109467b48Spatrick Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, CI, "addconv"); 156209467b48Spatrick return new SIToFPInst(NewAdd, I.getType()); 156309467b48Spatrick } 156409467b48Spatrick } 156509467b48Spatrick 156609467b48Spatrick // (fadd double (sitofp x), (sitofp y)) --> (sitofp (add int x, y)) 156709467b48Spatrick if (SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) { 156809467b48Spatrick Value *RHSIntVal = RHSConv->getOperand(0); 156909467b48Spatrick // It's enough to check LHS types only because we require int types to 157009467b48Spatrick // be the same for this transform. 157109467b48Spatrick if (IsValidPromotion(FPType, LHSIntVal->getType())) { 157209467b48Spatrick // Only do this if x/y have the same type, if at least one of them has a 157309467b48Spatrick // single use (so we don't increase the number of int->fp conversions), 157409467b48Spatrick // and if the integer add will not overflow. 157509467b48Spatrick if (LHSIntVal->getType() == RHSIntVal->getType() && 157609467b48Spatrick (LHSConv->hasOneUse() || RHSConv->hasOneUse()) && 157709467b48Spatrick willNotOverflowSignedAdd(LHSIntVal, RHSIntVal, I)) { 157809467b48Spatrick // Insert the new integer add. 157909467b48Spatrick Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, RHSIntVal, "addconv"); 158009467b48Spatrick return new SIToFPInst(NewAdd, I.getType()); 158109467b48Spatrick } 158209467b48Spatrick } 158309467b48Spatrick } 158409467b48Spatrick } 158509467b48Spatrick 158609467b48Spatrick // Handle specials cases for FAdd with selects feeding the operation 158709467b48Spatrick if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS)) 158809467b48Spatrick return replaceInstUsesWith(I, V); 158909467b48Spatrick 159009467b48Spatrick if (I.hasAllowReassoc() && I.hasNoSignedZeros()) { 159109467b48Spatrick if (Instruction *F = factorizeFAddFSub(I, Builder)) 159209467b48Spatrick return F; 159309467b48Spatrick if (Value *V = FAddCombine(Builder).simplify(&I)) 159409467b48Spatrick return replaceInstUsesWith(I, V); 159509467b48Spatrick } 159609467b48Spatrick 159709467b48Spatrick return nullptr; 159809467b48Spatrick } 159909467b48Spatrick 160009467b48Spatrick /// Optimize pointer differences into the same array into a size. Consider: 160109467b48Spatrick /// &A[10] - &A[0]: we should compile this to "10". LHS/RHS are the pointer 160209467b48Spatrick /// operands to the ptrtoint instructions for the LHS/RHS of the subtract. 160309467b48Spatrick Value *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS, 160409467b48Spatrick Type *Ty, bool IsNUW) { 160509467b48Spatrick // If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize 160609467b48Spatrick // this. 160709467b48Spatrick bool Swapped = false; 160809467b48Spatrick GEPOperator *GEP1 = nullptr, *GEP2 = nullptr; 160909467b48Spatrick 161009467b48Spatrick // For now we require one side to be the base pointer "A" or a constant 161109467b48Spatrick // GEP derived from it. 161209467b48Spatrick if (GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) { 161309467b48Spatrick // (gep X, ...) - X 161409467b48Spatrick if (LHSGEP->getOperand(0) == RHS) { 161509467b48Spatrick GEP1 = LHSGEP; 161609467b48Spatrick Swapped = false; 161709467b48Spatrick } else if (GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) { 161809467b48Spatrick // (gep X, ...) - (gep X, ...) 161909467b48Spatrick if (LHSGEP->getOperand(0)->stripPointerCasts() == 162009467b48Spatrick RHSGEP->getOperand(0)->stripPointerCasts()) { 162109467b48Spatrick GEP2 = RHSGEP; 162209467b48Spatrick GEP1 = LHSGEP; 162309467b48Spatrick Swapped = false; 162409467b48Spatrick } 162509467b48Spatrick } 162609467b48Spatrick } 162709467b48Spatrick 162809467b48Spatrick if (GEPOperator *RHSGEP = dyn_cast<GEPOperator>(RHS)) { 162909467b48Spatrick // X - (gep X, ...) 163009467b48Spatrick if (RHSGEP->getOperand(0) == LHS) { 163109467b48Spatrick GEP1 = RHSGEP; 163209467b48Spatrick Swapped = true; 163309467b48Spatrick } else if (GEPOperator *LHSGEP = dyn_cast<GEPOperator>(LHS)) { 163409467b48Spatrick // (gep X, ...) - (gep X, ...) 163509467b48Spatrick if (RHSGEP->getOperand(0)->stripPointerCasts() == 163609467b48Spatrick LHSGEP->getOperand(0)->stripPointerCasts()) { 163709467b48Spatrick GEP2 = LHSGEP; 163809467b48Spatrick GEP1 = RHSGEP; 163909467b48Spatrick Swapped = true; 164009467b48Spatrick } 164109467b48Spatrick } 164209467b48Spatrick } 164309467b48Spatrick 164409467b48Spatrick if (!GEP1) 164509467b48Spatrick // No GEP found. 164609467b48Spatrick return nullptr; 164709467b48Spatrick 164809467b48Spatrick if (GEP2) { 164909467b48Spatrick // (gep X, ...) - (gep X, ...) 165009467b48Spatrick // 165109467b48Spatrick // Avoid duplicating the arithmetic if there are more than one non-constant 165209467b48Spatrick // indices between the two GEPs and either GEP has a non-constant index and 165309467b48Spatrick // multiple users. If zero non-constant index, the result is a constant and 165409467b48Spatrick // there is no duplication. If one non-constant index, the result is an add 165509467b48Spatrick // or sub with a constant, which is no larger than the original code, and 165609467b48Spatrick // there's no duplicated arithmetic, even if either GEP has multiple 165709467b48Spatrick // users. If more than one non-constant indices combined, as long as the GEP 165809467b48Spatrick // with at least one non-constant index doesn't have multiple users, there 165909467b48Spatrick // is no duplication. 166009467b48Spatrick unsigned NumNonConstantIndices1 = GEP1->countNonConstantIndices(); 166109467b48Spatrick unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices(); 166209467b48Spatrick if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 && 166309467b48Spatrick ((NumNonConstantIndices1 > 0 && !GEP1->hasOneUse()) || 166409467b48Spatrick (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) { 166509467b48Spatrick return nullptr; 166609467b48Spatrick } 166709467b48Spatrick } 166809467b48Spatrick 166909467b48Spatrick // Emit the offset of the GEP and an intptr_t. 167009467b48Spatrick Value *Result = EmitGEPOffset(GEP1); 167109467b48Spatrick 167209467b48Spatrick // If this is a single inbounds GEP and the original sub was nuw, 167309467b48Spatrick // then the final multiplication is also nuw. We match an extra add zero 167409467b48Spatrick // here, because that's what EmitGEPOffset() generates. 167509467b48Spatrick Instruction *I; 167609467b48Spatrick if (IsNUW && !GEP2 && !Swapped && GEP1->isInBounds() && 167709467b48Spatrick match(Result, m_Add(m_Instruction(I), m_Zero())) && 167809467b48Spatrick I->getOpcode() == Instruction::Mul) 167909467b48Spatrick I->setHasNoUnsignedWrap(); 168009467b48Spatrick 168109467b48Spatrick // If we had a constant expression GEP on the other side offsetting the 168209467b48Spatrick // pointer, subtract it from the offset we have. 168309467b48Spatrick if (GEP2) { 168409467b48Spatrick Value *Offset = EmitGEPOffset(GEP2); 168509467b48Spatrick Result = Builder.CreateSub(Result, Offset); 168609467b48Spatrick } 168709467b48Spatrick 168809467b48Spatrick // If we have p - gep(p, ...) then we have to negate the result. 168909467b48Spatrick if (Swapped) 169009467b48Spatrick Result = Builder.CreateNeg(Result, "diff.neg"); 169109467b48Spatrick 169209467b48Spatrick return Builder.CreateIntCast(Result, Ty, true); 169309467b48Spatrick } 169409467b48Spatrick 169509467b48Spatrick Instruction *InstCombiner::visitSub(BinaryOperator &I) { 169609467b48Spatrick if (Value *V = SimplifySubInst(I.getOperand(0), I.getOperand(1), 169709467b48Spatrick I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), 169809467b48Spatrick SQ.getWithInstruction(&I))) 169909467b48Spatrick return replaceInstUsesWith(I, V); 170009467b48Spatrick 170109467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 170209467b48Spatrick return X; 170309467b48Spatrick 1704*097a140dSpatrick Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 170509467b48Spatrick 170609467b48Spatrick // If this is a 'B = x-(-A)', change to B = x+A. 1707*097a140dSpatrick // We deal with this without involving Negator to preserve NSW flag. 170809467b48Spatrick if (Value *V = dyn_castNegVal(Op1)) { 170909467b48Spatrick BinaryOperator *Res = BinaryOperator::CreateAdd(Op0, V); 171009467b48Spatrick 171109467b48Spatrick if (const auto *BO = dyn_cast<BinaryOperator>(Op1)) { 171209467b48Spatrick assert(BO->getOpcode() == Instruction::Sub && 171309467b48Spatrick "Expected a subtraction operator!"); 171409467b48Spatrick if (BO->hasNoSignedWrap() && I.hasNoSignedWrap()) 171509467b48Spatrick Res->setHasNoSignedWrap(true); 171609467b48Spatrick } else { 171709467b48Spatrick if (cast<Constant>(Op1)->isNotMinSignedValue() && I.hasNoSignedWrap()) 171809467b48Spatrick Res->setHasNoSignedWrap(true); 171909467b48Spatrick } 172009467b48Spatrick 172109467b48Spatrick return Res; 172209467b48Spatrick } 172309467b48Spatrick 1724*097a140dSpatrick auto TryToNarrowDeduceFlags = [this, &I, &Op0, &Op1]() -> Instruction * { 1725*097a140dSpatrick if (Instruction *Ext = narrowMathIfNoOverflow(I)) 1726*097a140dSpatrick return Ext; 1727*097a140dSpatrick 1728*097a140dSpatrick bool Changed = false; 1729*097a140dSpatrick if (!I.hasNoSignedWrap() && willNotOverflowSignedSub(Op0, Op1, I)) { 1730*097a140dSpatrick Changed = true; 1731*097a140dSpatrick I.setHasNoSignedWrap(true); 1732*097a140dSpatrick } 1733*097a140dSpatrick if (!I.hasNoUnsignedWrap() && willNotOverflowUnsignedSub(Op0, Op1, I)) { 1734*097a140dSpatrick Changed = true; 1735*097a140dSpatrick I.setHasNoUnsignedWrap(true); 1736*097a140dSpatrick } 1737*097a140dSpatrick 1738*097a140dSpatrick return Changed ? &I : nullptr; 1739*097a140dSpatrick }; 1740*097a140dSpatrick 1741*097a140dSpatrick // First, let's try to interpret `sub a, b` as `add a, (sub 0, b)`, 1742*097a140dSpatrick // and let's try to sink `(sub 0, b)` into `b` itself. But only if this isn't 1743*097a140dSpatrick // a pure negation used by a select that looks like abs/nabs. 1744*097a140dSpatrick bool IsNegation = match(Op0, m_ZeroInt()); 1745*097a140dSpatrick if (!IsNegation || none_of(I.users(), [&I, Op1](const User *U) { 1746*097a140dSpatrick const Instruction *UI = dyn_cast<Instruction>(U); 1747*097a140dSpatrick if (!UI) 1748*097a140dSpatrick return false; 1749*097a140dSpatrick return match(UI, 1750*097a140dSpatrick m_Select(m_Value(), m_Specific(Op1), m_Specific(&I))) || 1751*097a140dSpatrick match(UI, m_Select(m_Value(), m_Specific(&I), m_Specific(Op1))); 1752*097a140dSpatrick })) { 1753*097a140dSpatrick if (Value *NegOp1 = Negator::Negate(IsNegation, Op1, *this)) 1754*097a140dSpatrick return BinaryOperator::CreateAdd(NegOp1, Op0); 1755*097a140dSpatrick } 1756*097a140dSpatrick if (IsNegation) 1757*097a140dSpatrick return TryToNarrowDeduceFlags(); // Should have been handled in Negator! 1758*097a140dSpatrick 1759*097a140dSpatrick // (A*B)-(A*C) -> A*(B-C) etc 1760*097a140dSpatrick if (Value *V = SimplifyUsingDistributiveLaws(I)) 1761*097a140dSpatrick return replaceInstUsesWith(I, V); 1762*097a140dSpatrick 176309467b48Spatrick if (I.getType()->isIntOrIntVectorTy(1)) 176409467b48Spatrick return BinaryOperator::CreateXor(Op0, Op1); 176509467b48Spatrick 176609467b48Spatrick // Replace (-1 - A) with (~A). 176709467b48Spatrick if (match(Op0, m_AllOnes())) 176809467b48Spatrick return BinaryOperator::CreateNot(Op1); 176909467b48Spatrick 177009467b48Spatrick // (~X) - (~Y) --> Y - X 177109467b48Spatrick Value *X, *Y; 177209467b48Spatrick if (match(Op0, m_Not(m_Value(X))) && match(Op1, m_Not(m_Value(Y)))) 177309467b48Spatrick return BinaryOperator::CreateSub(Y, X); 177409467b48Spatrick 177509467b48Spatrick // (X + -1) - Y --> ~Y + X 177609467b48Spatrick if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes())))) 177709467b48Spatrick return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X); 177809467b48Spatrick 1779*097a140dSpatrick // Reassociate sub/add sequences to create more add instructions and 1780*097a140dSpatrick // reduce dependency chains: 1781*097a140dSpatrick // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1) 1782*097a140dSpatrick Value *Z; 1783*097a140dSpatrick if (match(Op0, m_OneUse(m_c_Add(m_OneUse(m_Sub(m_Value(X), m_Value(Y))), 1784*097a140dSpatrick m_Value(Z))))) { 1785*097a140dSpatrick Value *XZ = Builder.CreateAdd(X, Z); 1786*097a140dSpatrick Value *YW = Builder.CreateAdd(Y, Op1); 1787*097a140dSpatrick return BinaryOperator::CreateSub(XZ, YW); 1788*097a140dSpatrick } 178909467b48Spatrick 1790*097a140dSpatrick auto m_AddRdx = [](Value *&Vec) { 1791*097a140dSpatrick return m_OneUse( 1792*097a140dSpatrick m_Intrinsic<Intrinsic::experimental_vector_reduce_add>(m_Value(Vec))); 1793*097a140dSpatrick }; 1794*097a140dSpatrick Value *V0, *V1; 1795*097a140dSpatrick if (match(Op0, m_AddRdx(V0)) && match(Op1, m_AddRdx(V1)) && 1796*097a140dSpatrick V0->getType() == V1->getType()) { 1797*097a140dSpatrick // Difference of sums is sum of differences: 1798*097a140dSpatrick // add_rdx(V0) - add_rdx(V1) --> add_rdx(V0 - V1) 1799*097a140dSpatrick Value *Sub = Builder.CreateSub(V0, V1); 1800*097a140dSpatrick Value *Rdx = Builder.CreateIntrinsic( 1801*097a140dSpatrick Intrinsic::experimental_vector_reduce_add, {Sub->getType()}, {Sub}); 1802*097a140dSpatrick return replaceInstUsesWith(I, Rdx); 180309467b48Spatrick } 180409467b48Spatrick 180509467b48Spatrick if (Constant *C = dyn_cast<Constant>(Op0)) { 180609467b48Spatrick Value *X; 1807*097a140dSpatrick if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) 180809467b48Spatrick // C - (zext bool) --> bool ? C - 1 : C 180909467b48Spatrick return SelectInst::Create(X, SubOne(C), C); 1810*097a140dSpatrick if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) 181109467b48Spatrick // C - (sext bool) --> bool ? C + 1 : C 181209467b48Spatrick return SelectInst::Create(X, AddOne(C), C); 181309467b48Spatrick 181409467b48Spatrick // C - ~X == X + (1+C) 181509467b48Spatrick if (match(Op1, m_Not(m_Value(X)))) 181609467b48Spatrick return BinaryOperator::CreateAdd(X, AddOne(C)); 181709467b48Spatrick 181809467b48Spatrick // Try to fold constant sub into select arguments. 181909467b48Spatrick if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) 182009467b48Spatrick if (Instruction *R = FoldOpIntoSelect(I, SI)) 182109467b48Spatrick return R; 182209467b48Spatrick 182309467b48Spatrick // Try to fold constant sub into PHI values. 182409467b48Spatrick if (PHINode *PN = dyn_cast<PHINode>(Op1)) 182509467b48Spatrick if (Instruction *R = foldOpIntoPhi(I, PN)) 182609467b48Spatrick return R; 182709467b48Spatrick 182809467b48Spatrick Constant *C2; 182909467b48Spatrick 183009467b48Spatrick // C-(C2-X) --> X+(C-C2) 18317299aa8dSpatrick if (match(Op1, m_Sub(m_Constant(C2), m_Value(X))) && !isa<ConstantExpr>(C2)) 183209467b48Spatrick return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2)); 183309467b48Spatrick 183409467b48Spatrick // C-(X+C2) --> (C-C2)-X 183509467b48Spatrick if (match(Op1, m_Add(m_Value(X), m_Constant(C2)))) 183609467b48Spatrick return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X); 183709467b48Spatrick } 183809467b48Spatrick 183909467b48Spatrick const APInt *Op0C; 1840*097a140dSpatrick if (match(Op0, m_APInt(Op0C)) && Op0C->isMask()) { 184109467b48Spatrick // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known 184209467b48Spatrick // zero. 184309467b48Spatrick KnownBits RHSKnown = computeKnownBits(Op1, 0, &I); 184409467b48Spatrick if ((*Op0C | RHSKnown.Zero).isAllOnesValue()) 184509467b48Spatrick return BinaryOperator::CreateXor(Op1, Op0); 184609467b48Spatrick } 184709467b48Spatrick 184809467b48Spatrick { 184909467b48Spatrick Value *Y; 185009467b48Spatrick // X-(X+Y) == -Y X-(Y+X) == -Y 185109467b48Spatrick if (match(Op1, m_c_Add(m_Specific(Op0), m_Value(Y)))) 185209467b48Spatrick return BinaryOperator::CreateNeg(Y); 185309467b48Spatrick 185409467b48Spatrick // (X-Y)-X == -Y 185509467b48Spatrick if (match(Op0, m_Sub(m_Specific(Op1), m_Value(Y)))) 185609467b48Spatrick return BinaryOperator::CreateNeg(Y); 185709467b48Spatrick } 185809467b48Spatrick 185909467b48Spatrick // (sub (or A, B) (and A, B)) --> (xor A, B) 186009467b48Spatrick { 186109467b48Spatrick Value *A, *B; 186209467b48Spatrick if (match(Op1, m_And(m_Value(A), m_Value(B))) && 186309467b48Spatrick match(Op0, m_c_Or(m_Specific(A), m_Specific(B)))) 186409467b48Spatrick return BinaryOperator::CreateXor(A, B); 186509467b48Spatrick } 186609467b48Spatrick 186709467b48Spatrick // (sub (and A, B) (or A, B)) --> neg (xor A, B) 186809467b48Spatrick { 186909467b48Spatrick Value *A, *B; 187009467b48Spatrick if (match(Op0, m_And(m_Value(A), m_Value(B))) && 187109467b48Spatrick match(Op1, m_c_Or(m_Specific(A), m_Specific(B))) && 187209467b48Spatrick (Op0->hasOneUse() || Op1->hasOneUse())) 187309467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateXor(A, B)); 187409467b48Spatrick } 187509467b48Spatrick 187609467b48Spatrick // (sub (or A, B), (xor A, B)) --> (and A, B) 187709467b48Spatrick { 187809467b48Spatrick Value *A, *B; 187909467b48Spatrick if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && 188009467b48Spatrick match(Op0, m_c_Or(m_Specific(A), m_Specific(B)))) 188109467b48Spatrick return BinaryOperator::CreateAnd(A, B); 188209467b48Spatrick } 188309467b48Spatrick 188409467b48Spatrick // (sub (xor A, B) (or A, B)) --> neg (and A, B) 188509467b48Spatrick { 188609467b48Spatrick Value *A, *B; 188709467b48Spatrick if (match(Op0, m_Xor(m_Value(A), m_Value(B))) && 188809467b48Spatrick match(Op1, m_c_Or(m_Specific(A), m_Specific(B))) && 188909467b48Spatrick (Op0->hasOneUse() || Op1->hasOneUse())) 189009467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateAnd(A, B)); 189109467b48Spatrick } 189209467b48Spatrick 189309467b48Spatrick { 189409467b48Spatrick Value *Y; 189509467b48Spatrick // ((X | Y) - X) --> (~X & Y) 189609467b48Spatrick if (match(Op0, m_OneUse(m_c_Or(m_Value(Y), m_Specific(Op1))))) 189709467b48Spatrick return BinaryOperator::CreateAnd( 189809467b48Spatrick Y, Builder.CreateNot(Op1, Op1->getName() + ".not")); 189909467b48Spatrick } 190009467b48Spatrick 190109467b48Spatrick { 190209467b48Spatrick // (sub (and Op1, (neg X)), Op1) --> neg (and Op1, (add X, -1)) 190309467b48Spatrick Value *X; 190409467b48Spatrick if (match(Op0, m_OneUse(m_c_And(m_Specific(Op1), 190509467b48Spatrick m_OneUse(m_Neg(m_Value(X))))))) { 190609467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateAnd( 190709467b48Spatrick Op1, Builder.CreateAdd(X, Constant::getAllOnesValue(I.getType())))); 190809467b48Spatrick } 190909467b48Spatrick } 191009467b48Spatrick 191109467b48Spatrick { 191209467b48Spatrick // (sub (and Op1, C), Op1) --> neg (and Op1, ~C) 191309467b48Spatrick Constant *C; 191409467b48Spatrick if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_Constant(C))))) { 191509467b48Spatrick return BinaryOperator::CreateNeg( 191609467b48Spatrick Builder.CreateAnd(Op1, Builder.CreateNot(C))); 191709467b48Spatrick } 191809467b48Spatrick } 191909467b48Spatrick 192009467b48Spatrick { 192109467b48Spatrick // If we have a subtraction between some value and a select between 192209467b48Spatrick // said value and something else, sink subtraction into select hands, i.e.: 192309467b48Spatrick // sub (select %Cond, %TrueVal, %FalseVal), %Op1 192409467b48Spatrick // -> 192509467b48Spatrick // select %Cond, (sub %TrueVal, %Op1), (sub %FalseVal, %Op1) 192609467b48Spatrick // or 192709467b48Spatrick // sub %Op0, (select %Cond, %TrueVal, %FalseVal) 192809467b48Spatrick // -> 192909467b48Spatrick // select %Cond, (sub %Op0, %TrueVal), (sub %Op0, %FalseVal) 193009467b48Spatrick // This will result in select between new subtraction and 0. 193109467b48Spatrick auto SinkSubIntoSelect = 193209467b48Spatrick [Ty = I.getType()](Value *Select, Value *OtherHandOfSub, 193309467b48Spatrick auto SubBuilder) -> Instruction * { 193409467b48Spatrick Value *Cond, *TrueVal, *FalseVal; 193509467b48Spatrick if (!match(Select, m_OneUse(m_Select(m_Value(Cond), m_Value(TrueVal), 193609467b48Spatrick m_Value(FalseVal))))) 193709467b48Spatrick return nullptr; 193809467b48Spatrick if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal) 193909467b48Spatrick return nullptr; 194009467b48Spatrick // While it is really tempting to just create two subtractions and let 194109467b48Spatrick // InstCombine fold one of those to 0, it isn't possible to do so 194209467b48Spatrick // because of worklist visitation order. So ugly it is. 194309467b48Spatrick bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal; 194409467b48Spatrick Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal); 194509467b48Spatrick Constant *Zero = Constant::getNullValue(Ty); 194609467b48Spatrick SelectInst *NewSel = 194709467b48Spatrick SelectInst::Create(Cond, OtherHandOfSubIsTrueVal ? Zero : NewSub, 194809467b48Spatrick OtherHandOfSubIsTrueVal ? NewSub : Zero); 194909467b48Spatrick // Preserve prof metadata if any. 195009467b48Spatrick NewSel->copyMetadata(cast<Instruction>(*Select)); 195109467b48Spatrick return NewSel; 195209467b48Spatrick }; 195309467b48Spatrick if (Instruction *NewSel = SinkSubIntoSelect( 195409467b48Spatrick /*Select=*/Op0, /*OtherHandOfSub=*/Op1, 195509467b48Spatrick [Builder = &Builder, Op1](Value *OtherHandOfSelect) { 195609467b48Spatrick return Builder->CreateSub(OtherHandOfSelect, 195709467b48Spatrick /*OtherHandOfSub=*/Op1); 195809467b48Spatrick })) 195909467b48Spatrick return NewSel; 196009467b48Spatrick if (Instruction *NewSel = SinkSubIntoSelect( 196109467b48Spatrick /*Select=*/Op1, /*OtherHandOfSub=*/Op0, 196209467b48Spatrick [Builder = &Builder, Op0](Value *OtherHandOfSelect) { 196309467b48Spatrick return Builder->CreateSub(/*OtherHandOfSub=*/Op0, 196409467b48Spatrick OtherHandOfSelect); 196509467b48Spatrick })) 196609467b48Spatrick return NewSel; 196709467b48Spatrick } 196809467b48Spatrick 196909467b48Spatrick // (X - (X & Y)) --> (X & ~Y) 1970*097a140dSpatrick if (match(Op1, m_c_And(m_Specific(Op0), m_Value(Y))) && 1971*097a140dSpatrick (Op1->hasOneUse() || isa<Constant>(Y))) 1972*097a140dSpatrick return BinaryOperator::CreateAnd( 1973*097a140dSpatrick Op0, Builder.CreateNot(Y, Y->getName() + ".not")); 197409467b48Spatrick 197509467b48Spatrick { 197609467b48Spatrick // ~A - Min/Max(~A, O) -> Max/Min(A, ~O) - A 197709467b48Spatrick // ~A - Min/Max(O, ~A) -> Max/Min(A, ~O) - A 197809467b48Spatrick // Min/Max(~A, O) - ~A -> A - Max/Min(A, ~O) 197909467b48Spatrick // Min/Max(O, ~A) - ~A -> A - Max/Min(A, ~O) 198009467b48Spatrick // So long as O here is freely invertible, this will be neutral or a win. 198109467b48Spatrick Value *LHS, *RHS, *A; 198209467b48Spatrick Value *NotA = Op0, *MinMax = Op1; 198309467b48Spatrick SelectPatternFlavor SPF = matchSelectPattern(MinMax, LHS, RHS).Flavor; 198409467b48Spatrick if (!SelectPatternResult::isMinOrMax(SPF)) { 198509467b48Spatrick NotA = Op1; 198609467b48Spatrick MinMax = Op0; 198709467b48Spatrick SPF = matchSelectPattern(MinMax, LHS, RHS).Flavor; 198809467b48Spatrick } 198909467b48Spatrick if (SelectPatternResult::isMinOrMax(SPF) && 199009467b48Spatrick match(NotA, m_Not(m_Value(A))) && (NotA == LHS || NotA == RHS)) { 199109467b48Spatrick if (NotA == LHS) 199209467b48Spatrick std::swap(LHS, RHS); 199309467b48Spatrick // LHS is now O above and expected to have at least 2 uses (the min/max) 199409467b48Spatrick // NotA is epected to have 2 uses from the min/max and 1 from the sub. 199509467b48Spatrick if (isFreeToInvert(LHS, !LHS->hasNUsesOrMore(3)) && 199609467b48Spatrick !NotA->hasNUsesOrMore(4)) { 199709467b48Spatrick // Note: We don't generate the inverse max/min, just create the not of 199809467b48Spatrick // it and let other folds do the rest. 199909467b48Spatrick Value *Not = Builder.CreateNot(MinMax); 200009467b48Spatrick if (NotA == Op0) 200109467b48Spatrick return BinaryOperator::CreateSub(Not, A); 200209467b48Spatrick else 200309467b48Spatrick return BinaryOperator::CreateSub(A, Not); 200409467b48Spatrick } 200509467b48Spatrick } 200609467b48Spatrick } 200709467b48Spatrick 200809467b48Spatrick // Optimize pointer differences into the same array into a size. Consider: 200909467b48Spatrick // &A[10] - &A[0]: we should compile this to "10". 201009467b48Spatrick Value *LHSOp, *RHSOp; 201109467b48Spatrick if (match(Op0, m_PtrToInt(m_Value(LHSOp))) && 201209467b48Spatrick match(Op1, m_PtrToInt(m_Value(RHSOp)))) 201309467b48Spatrick if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(), 201409467b48Spatrick I.hasNoUnsignedWrap())) 201509467b48Spatrick return replaceInstUsesWith(I, Res); 201609467b48Spatrick 201709467b48Spatrick // trunc(p)-trunc(q) -> trunc(p-q) 201809467b48Spatrick if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) && 201909467b48Spatrick match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp))))) 202009467b48Spatrick if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(), 202109467b48Spatrick /* IsNUW */ false)) 202209467b48Spatrick return replaceInstUsesWith(I, Res); 202309467b48Spatrick 202409467b48Spatrick // Canonicalize a shifty way to code absolute value to the common pattern. 202509467b48Spatrick // There are 2 potential commuted variants. 202609467b48Spatrick // We're relying on the fact that we only do this transform when the shift has 202709467b48Spatrick // exactly 2 uses and the xor has exactly 1 use (otherwise, we might increase 202809467b48Spatrick // instructions). 202909467b48Spatrick Value *A; 203009467b48Spatrick const APInt *ShAmt; 203109467b48Spatrick Type *Ty = I.getType(); 203209467b48Spatrick if (match(Op1, m_AShr(m_Value(A), m_APInt(ShAmt))) && 203309467b48Spatrick Op1->hasNUses(2) && *ShAmt == Ty->getScalarSizeInBits() - 1 && 203409467b48Spatrick match(Op0, m_OneUse(m_c_Xor(m_Specific(A), m_Specific(Op1))))) { 203509467b48Spatrick // B = ashr i32 A, 31 ; smear the sign bit 203609467b48Spatrick // sub (xor A, B), B ; flip bits if negative and subtract -1 (add 1) 203709467b48Spatrick // --> (A < 0) ? -A : A 203809467b48Spatrick Value *Cmp = Builder.CreateICmpSLT(A, ConstantInt::getNullValue(Ty)); 203909467b48Spatrick // Copy the nuw/nsw flags from the sub to the negate. 204009467b48Spatrick Value *Neg = Builder.CreateNeg(A, "", I.hasNoUnsignedWrap(), 204109467b48Spatrick I.hasNoSignedWrap()); 204209467b48Spatrick return SelectInst::Create(Cmp, Neg, A); 204309467b48Spatrick } 204409467b48Spatrick 204509467b48Spatrick if (Instruction *V = 204609467b48Spatrick canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I)) 204709467b48Spatrick return V; 204809467b48Spatrick 2049*097a140dSpatrick return TryToNarrowDeduceFlags(); 205009467b48Spatrick } 205109467b48Spatrick 205209467b48Spatrick /// This eliminates floating-point negation in either 'fneg(X)' or 205309467b48Spatrick /// 'fsub(-0.0, X)' form by combining into a constant operand. 205409467b48Spatrick static Instruction *foldFNegIntoConstant(Instruction &I) { 205509467b48Spatrick Value *X; 205609467b48Spatrick Constant *C; 205709467b48Spatrick 205809467b48Spatrick // Fold negation into constant operand. This is limited with one-use because 205909467b48Spatrick // fneg is assumed better for analysis and cheaper in codegen than fmul/fdiv. 206009467b48Spatrick // -(X * C) --> X * (-C) 206109467b48Spatrick // FIXME: It's arguable whether these should be m_OneUse or not. The current 206209467b48Spatrick // belief is that the FNeg allows for better reassociation opportunities. 206309467b48Spatrick if (match(&I, m_FNeg(m_OneUse(m_FMul(m_Value(X), m_Constant(C)))))) 206409467b48Spatrick return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I); 206509467b48Spatrick // -(X / C) --> X / (-C) 206609467b48Spatrick if (match(&I, m_FNeg(m_OneUse(m_FDiv(m_Value(X), m_Constant(C)))))) 206709467b48Spatrick return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I); 206809467b48Spatrick // -(C / X) --> (-C) / X 206909467b48Spatrick if (match(&I, m_FNeg(m_OneUse(m_FDiv(m_Constant(C), m_Value(X)))))) 207009467b48Spatrick return BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I); 207109467b48Spatrick 2072*097a140dSpatrick // With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]: 2073*097a140dSpatrick // -(X + C) --> -X + -C --> -C - X 2074*097a140dSpatrick if (I.hasNoSignedZeros() && 2075*097a140dSpatrick match(&I, m_FNeg(m_OneUse(m_FAdd(m_Value(X), m_Constant(C)))))) 2076*097a140dSpatrick return BinaryOperator::CreateFSubFMF(ConstantExpr::getFNeg(C), X, &I); 2077*097a140dSpatrick 207809467b48Spatrick return nullptr; 207909467b48Spatrick } 208009467b48Spatrick 208109467b48Spatrick static Instruction *hoistFNegAboveFMulFDiv(Instruction &I, 208209467b48Spatrick InstCombiner::BuilderTy &Builder) { 208309467b48Spatrick Value *FNeg; 208409467b48Spatrick if (!match(&I, m_FNeg(m_Value(FNeg)))) 208509467b48Spatrick return nullptr; 208609467b48Spatrick 208709467b48Spatrick Value *X, *Y; 208809467b48Spatrick if (match(FNeg, m_OneUse(m_FMul(m_Value(X), m_Value(Y))))) 208909467b48Spatrick return BinaryOperator::CreateFMulFMF(Builder.CreateFNegFMF(X, &I), Y, &I); 209009467b48Spatrick 209109467b48Spatrick if (match(FNeg, m_OneUse(m_FDiv(m_Value(X), m_Value(Y))))) 209209467b48Spatrick return BinaryOperator::CreateFDivFMF(Builder.CreateFNegFMF(X, &I), Y, &I); 209309467b48Spatrick 209409467b48Spatrick return nullptr; 209509467b48Spatrick } 209609467b48Spatrick 209709467b48Spatrick Instruction *InstCombiner::visitFNeg(UnaryOperator &I) { 209809467b48Spatrick Value *Op = I.getOperand(0); 209909467b48Spatrick 210009467b48Spatrick if (Value *V = SimplifyFNegInst(Op, I.getFastMathFlags(), 210109467b48Spatrick SQ.getWithInstruction(&I))) 210209467b48Spatrick return replaceInstUsesWith(I, V); 210309467b48Spatrick 210409467b48Spatrick if (Instruction *X = foldFNegIntoConstant(I)) 210509467b48Spatrick return X; 210609467b48Spatrick 210709467b48Spatrick Value *X, *Y; 210809467b48Spatrick 210909467b48Spatrick // If we can ignore the sign of zeros: -(X - Y) --> (Y - X) 211009467b48Spatrick if (I.hasNoSignedZeros() && 211109467b48Spatrick match(Op, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) 211209467b48Spatrick return BinaryOperator::CreateFSubFMF(Y, X, &I); 211309467b48Spatrick 211409467b48Spatrick if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder)) 211509467b48Spatrick return R; 211609467b48Spatrick 211709467b48Spatrick return nullptr; 211809467b48Spatrick } 211909467b48Spatrick 212009467b48Spatrick Instruction *InstCombiner::visitFSub(BinaryOperator &I) { 212109467b48Spatrick if (Value *V = SimplifyFSubInst(I.getOperand(0), I.getOperand(1), 212209467b48Spatrick I.getFastMathFlags(), 212309467b48Spatrick SQ.getWithInstruction(&I))) 212409467b48Spatrick return replaceInstUsesWith(I, V); 212509467b48Spatrick 212609467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 212709467b48Spatrick return X; 212809467b48Spatrick 212909467b48Spatrick // Subtraction from -0.0 is the canonical form of fneg. 2130*097a140dSpatrick // fsub -0.0, X ==> fneg X 2131*097a140dSpatrick // fsub nsz 0.0, X ==> fneg nsz X 2132*097a140dSpatrick // 2133*097a140dSpatrick // FIXME This matcher does not respect FTZ or DAZ yet: 2134*097a140dSpatrick // fsub -0.0, Denorm ==> +-0 2135*097a140dSpatrick // fneg Denorm ==> -Denorm 2136*097a140dSpatrick Value *Op; 2137*097a140dSpatrick if (match(&I, m_FNeg(m_Value(Op)))) 2138*097a140dSpatrick return UnaryOperator::CreateFNegFMF(Op, &I); 213909467b48Spatrick 214009467b48Spatrick if (Instruction *X = foldFNegIntoConstant(I)) 214109467b48Spatrick return X; 214209467b48Spatrick 214309467b48Spatrick if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder)) 214409467b48Spatrick return R; 214509467b48Spatrick 214609467b48Spatrick Value *X, *Y; 214709467b48Spatrick Constant *C; 214809467b48Spatrick 2149*097a140dSpatrick Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 215009467b48Spatrick // If Op0 is not -0.0 or we can ignore -0.0: Z - (X - Y) --> Z + (Y - X) 215109467b48Spatrick // Canonicalize to fadd to make analysis easier. 215209467b48Spatrick // This can also help codegen because fadd is commutative. 215309467b48Spatrick // Note that if this fsub was really an fneg, the fadd with -0.0 will get 215409467b48Spatrick // killed later. We still limit that particular transform with 'hasOneUse' 215509467b48Spatrick // because an fneg is assumed better/cheaper than a generic fsub. 215609467b48Spatrick if (I.hasNoSignedZeros() || CannotBeNegativeZero(Op0, SQ.TLI)) { 215709467b48Spatrick if (match(Op1, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) { 215809467b48Spatrick Value *NewSub = Builder.CreateFSubFMF(Y, X, &I); 215909467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, NewSub, &I); 216009467b48Spatrick } 216109467b48Spatrick } 216209467b48Spatrick 2163*097a140dSpatrick // (-X) - Op1 --> -(X + Op1) 2164*097a140dSpatrick if (I.hasNoSignedZeros() && !isa<ConstantExpr>(Op0) && 2165*097a140dSpatrick match(Op0, m_OneUse(m_FNeg(m_Value(X))))) { 2166*097a140dSpatrick Value *FAdd = Builder.CreateFAddFMF(X, Op1, &I); 2167*097a140dSpatrick return UnaryOperator::CreateFNegFMF(FAdd, &I); 2168*097a140dSpatrick } 2169*097a140dSpatrick 217009467b48Spatrick if (isa<Constant>(Op0)) 217109467b48Spatrick if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) 217209467b48Spatrick if (Instruction *NV = FoldOpIntoSelect(I, SI)) 217309467b48Spatrick return NV; 217409467b48Spatrick 217509467b48Spatrick // X - C --> X + (-C) 217609467b48Spatrick // But don't transform constant expressions because there's an inverse fold 217709467b48Spatrick // for X + (-Y) --> X - Y. 217809467b48Spatrick if (match(Op1, m_Constant(C)) && !isa<ConstantExpr>(Op1)) 217909467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I); 218009467b48Spatrick 218109467b48Spatrick // X - (-Y) --> X + Y 218209467b48Spatrick if (match(Op1, m_FNeg(m_Value(Y)))) 218309467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, Y, &I); 218409467b48Spatrick 218509467b48Spatrick // Similar to above, but look through a cast of the negated value: 218609467b48Spatrick // X - (fptrunc(-Y)) --> X + fptrunc(Y) 218709467b48Spatrick Type *Ty = I.getType(); 218809467b48Spatrick if (match(Op1, m_OneUse(m_FPTrunc(m_FNeg(m_Value(Y)))))) 218909467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPTrunc(Y, Ty), &I); 219009467b48Spatrick 219109467b48Spatrick // X - (fpext(-Y)) --> X + fpext(Y) 219209467b48Spatrick if (match(Op1, m_OneUse(m_FPExt(m_FNeg(m_Value(Y)))))) 219309467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPExt(Y, Ty), &I); 219409467b48Spatrick 219509467b48Spatrick // Similar to above, but look through fmul/fdiv of the negated value: 219609467b48Spatrick // Op0 - (-X * Y) --> Op0 + (X * Y) 219709467b48Spatrick // Op0 - (Y * -X) --> Op0 + (X * Y) 219809467b48Spatrick if (match(Op1, m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))))) { 219909467b48Spatrick Value *FMul = Builder.CreateFMulFMF(X, Y, &I); 220009467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, FMul, &I); 220109467b48Spatrick } 220209467b48Spatrick // Op0 - (-X / Y) --> Op0 + (X / Y) 220309467b48Spatrick // Op0 - (X / -Y) --> Op0 + (X / Y) 220409467b48Spatrick if (match(Op1, m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y)))) || 220509467b48Spatrick match(Op1, m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))))) { 220609467b48Spatrick Value *FDiv = Builder.CreateFDivFMF(X, Y, &I); 220709467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, FDiv, &I); 220809467b48Spatrick } 220909467b48Spatrick 221009467b48Spatrick // Handle special cases for FSub with selects feeding the operation 221109467b48Spatrick if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) 221209467b48Spatrick return replaceInstUsesWith(I, V); 221309467b48Spatrick 221409467b48Spatrick if (I.hasAllowReassoc() && I.hasNoSignedZeros()) { 221509467b48Spatrick // (Y - X) - Y --> -X 221609467b48Spatrick if (match(Op0, m_FSub(m_Specific(Op1), m_Value(X)))) 2217*097a140dSpatrick return UnaryOperator::CreateFNegFMF(X, &I); 221809467b48Spatrick 221909467b48Spatrick // Y - (X + Y) --> -X 222009467b48Spatrick // Y - (Y + X) --> -X 222109467b48Spatrick if (match(Op1, m_c_FAdd(m_Specific(Op0), m_Value(X)))) 2222*097a140dSpatrick return UnaryOperator::CreateFNegFMF(X, &I); 222309467b48Spatrick 222409467b48Spatrick // (X * C) - X --> X * (C - 1.0) 222509467b48Spatrick if (match(Op0, m_FMul(m_Specific(Op1), m_Constant(C)))) { 222609467b48Spatrick Constant *CSubOne = ConstantExpr::getFSub(C, ConstantFP::get(Ty, 1.0)); 222709467b48Spatrick return BinaryOperator::CreateFMulFMF(Op1, CSubOne, &I); 222809467b48Spatrick } 222909467b48Spatrick // X - (X * C) --> X * (1.0 - C) 223009467b48Spatrick if (match(Op1, m_FMul(m_Specific(Op0), m_Constant(C)))) { 223109467b48Spatrick Constant *OneSubC = ConstantExpr::getFSub(ConstantFP::get(Ty, 1.0), C); 223209467b48Spatrick return BinaryOperator::CreateFMulFMF(Op0, OneSubC, &I); 223309467b48Spatrick } 223409467b48Spatrick 2235*097a140dSpatrick // Reassociate fsub/fadd sequences to create more fadd instructions and 2236*097a140dSpatrick // reduce dependency chains: 2237*097a140dSpatrick // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1) 2238*097a140dSpatrick Value *Z; 2239*097a140dSpatrick if (match(Op0, m_OneUse(m_c_FAdd(m_OneUse(m_FSub(m_Value(X), m_Value(Y))), 2240*097a140dSpatrick m_Value(Z))))) { 2241*097a140dSpatrick Value *XZ = Builder.CreateFAddFMF(X, Z, &I); 2242*097a140dSpatrick Value *YW = Builder.CreateFAddFMF(Y, Op1, &I); 2243*097a140dSpatrick return BinaryOperator::CreateFSubFMF(XZ, YW, &I); 2244*097a140dSpatrick } 2245*097a140dSpatrick 2246*097a140dSpatrick auto m_FaddRdx = [](Value *&Sum, Value *&Vec) { 2247*097a140dSpatrick return m_OneUse( 2248*097a140dSpatrick m_Intrinsic<Intrinsic::experimental_vector_reduce_v2_fadd>( 2249*097a140dSpatrick m_Value(Sum), m_Value(Vec))); 2250*097a140dSpatrick }; 2251*097a140dSpatrick Value *A0, *A1, *V0, *V1; 2252*097a140dSpatrick if (match(Op0, m_FaddRdx(A0, V0)) && match(Op1, m_FaddRdx(A1, V1)) && 2253*097a140dSpatrick V0->getType() == V1->getType()) { 2254*097a140dSpatrick // Difference of sums is sum of differences: 2255*097a140dSpatrick // add_rdx(A0, V0) - add_rdx(A1, V1) --> add_rdx(A0, V0 - V1) - A1 2256*097a140dSpatrick Value *Sub = Builder.CreateFSubFMF(V0, V1, &I); 2257*097a140dSpatrick Value *Rdx = Builder.CreateIntrinsic( 2258*097a140dSpatrick Intrinsic::experimental_vector_reduce_v2_fadd, 2259*097a140dSpatrick {A0->getType(), Sub->getType()}, {A0, Sub}, &I); 2260*097a140dSpatrick return BinaryOperator::CreateFSubFMF(Rdx, A1, &I); 2261*097a140dSpatrick } 2262*097a140dSpatrick 226309467b48Spatrick if (Instruction *F = factorizeFAddFSub(I, Builder)) 226409467b48Spatrick return F; 226509467b48Spatrick 226609467b48Spatrick // TODO: This performs reassociative folds for FP ops. Some fraction of the 226709467b48Spatrick // functionality has been subsumed by simple pattern matching here and in 226809467b48Spatrick // InstSimplify. We should let a dedicated reassociation pass handle more 226909467b48Spatrick // complex pattern matching and remove this from InstCombine. 227009467b48Spatrick if (Value *V = FAddCombine(Builder).simplify(&I)) 227109467b48Spatrick return replaceInstUsesWith(I, V); 2272*097a140dSpatrick 2273*097a140dSpatrick // (X - Y) - Op1 --> X - (Y + Op1) 2274*097a140dSpatrick if (match(Op0, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) { 2275*097a140dSpatrick Value *FAdd = Builder.CreateFAddFMF(Y, Op1, &I); 2276*097a140dSpatrick return BinaryOperator::CreateFSubFMF(X, FAdd, &I); 2277*097a140dSpatrick } 227809467b48Spatrick } 227909467b48Spatrick 228009467b48Spatrick return nullptr; 228109467b48Spatrick } 2282