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" 32*73471bf0Spatrick #include "llvm/Transforms/InstCombine/InstCombiner.h" 3309467b48Spatrick #include <cassert> 3409467b48Spatrick #include <utility> 3509467b48Spatrick 3609467b48Spatrick using namespace llvm; 3709467b48Spatrick using namespace PatternMatch; 3809467b48Spatrick 3909467b48Spatrick #define DEBUG_TYPE "instcombine" 4009467b48Spatrick 4109467b48Spatrick namespace { 4209467b48Spatrick 4309467b48Spatrick /// Class representing coefficient of floating-point addend. 4409467b48Spatrick /// This class needs to be highly efficient, which is especially true for 4509467b48Spatrick /// the constructor. As of I write this comment, the cost of the default 4609467b48Spatrick /// constructor is merely 4-byte-store-zero (Assuming compiler is able to 4709467b48Spatrick /// perform write-merging). 4809467b48Spatrick /// 4909467b48Spatrick class FAddendCoef { 5009467b48Spatrick public: 5109467b48Spatrick // The constructor has to initialize a APFloat, which is unnecessary for 5209467b48Spatrick // most addends which have coefficient either 1 or -1. So, the constructor 5309467b48Spatrick // is expensive. In order to avoid the cost of the constructor, we should 5409467b48Spatrick // reuse some instances whenever possible. The pre-created instances 5509467b48Spatrick // FAddCombine::Add[0-5] embodies this idea. 5609467b48Spatrick FAddendCoef() = default; 5709467b48Spatrick ~FAddendCoef(); 5809467b48Spatrick 5909467b48Spatrick // If possible, don't define operator+/operator- etc because these 6009467b48Spatrick // operators inevitably call FAddendCoef's constructor which is not cheap. 6109467b48Spatrick void operator=(const FAddendCoef &A); 6209467b48Spatrick void operator+=(const FAddendCoef &A); 6309467b48Spatrick void operator*=(const FAddendCoef &S); 6409467b48Spatrick 6509467b48Spatrick void set(short C) { 6609467b48Spatrick assert(!insaneIntVal(C) && "Insane coefficient"); 6709467b48Spatrick IsFp = false; IntVal = C; 6809467b48Spatrick } 6909467b48Spatrick 7009467b48Spatrick void set(const APFloat& C); 7109467b48Spatrick 7209467b48Spatrick void negate(); 7309467b48Spatrick 7409467b48Spatrick bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); } 7509467b48Spatrick Value *getValue(Type *) const; 7609467b48Spatrick 7709467b48Spatrick bool isOne() const { return isInt() && IntVal == 1; } 7809467b48Spatrick bool isTwo() const { return isInt() && IntVal == 2; } 7909467b48Spatrick bool isMinusOne() const { return isInt() && IntVal == -1; } 8009467b48Spatrick bool isMinusTwo() const { return isInt() && IntVal == -2; } 8109467b48Spatrick 8209467b48Spatrick private: 8309467b48Spatrick bool insaneIntVal(int V) { return V > 4 || V < -4; } 8409467b48Spatrick 85*73471bf0Spatrick APFloat *getFpValPtr() { return reinterpret_cast<APFloat *>(&FpValBuf); } 8609467b48Spatrick 87*73471bf0Spatrick const APFloat *getFpValPtr() const { 88*73471bf0Spatrick return reinterpret_cast<const APFloat *>(&FpValBuf); 89*73471bf0Spatrick } 9009467b48Spatrick 9109467b48Spatrick const APFloat &getFpVal() const { 9209467b48Spatrick assert(IsFp && BufHasFpVal && "Incorret state"); 9309467b48Spatrick return *getFpValPtr(); 9409467b48Spatrick } 9509467b48Spatrick 9609467b48Spatrick APFloat &getFpVal() { 9709467b48Spatrick assert(IsFp && BufHasFpVal && "Incorret state"); 9809467b48Spatrick return *getFpValPtr(); 9909467b48Spatrick } 10009467b48Spatrick 10109467b48Spatrick bool isInt() const { return !IsFp; } 10209467b48Spatrick 10309467b48Spatrick // If the coefficient is represented by an integer, promote it to a 10409467b48Spatrick // floating point. 10509467b48Spatrick void convertToFpType(const fltSemantics &Sem); 10609467b48Spatrick 10709467b48Spatrick // Construct an APFloat from a signed integer. 10809467b48Spatrick // TODO: We should get rid of this function when APFloat can be constructed 10909467b48Spatrick // from an *SIGNED* integer. 11009467b48Spatrick APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val); 11109467b48Spatrick 11209467b48Spatrick bool IsFp = false; 11309467b48Spatrick 11409467b48Spatrick // True iff FpValBuf contains an instance of APFloat. 11509467b48Spatrick bool BufHasFpVal = false; 11609467b48Spatrick 11709467b48Spatrick // The integer coefficient of an individual addend is either 1 or -1, 11809467b48Spatrick // and we try to simplify at most 4 addends from neighboring at most 11909467b48Spatrick // two instructions. So the range of <IntVal> falls in [-4, 4]. APInt 12009467b48Spatrick // is overkill of this end. 12109467b48Spatrick short IntVal = 0; 12209467b48Spatrick 12309467b48Spatrick AlignedCharArrayUnion<APFloat> FpValBuf; 12409467b48Spatrick }; 12509467b48Spatrick 12609467b48Spatrick /// FAddend is used to represent floating-point addend. An addend is 12709467b48Spatrick /// represented as <C, V>, where the V is a symbolic value, and C is a 12809467b48Spatrick /// constant coefficient. A constant addend is represented as <C, 0>. 12909467b48Spatrick class FAddend { 13009467b48Spatrick public: 13109467b48Spatrick FAddend() = default; 13209467b48Spatrick 13309467b48Spatrick void operator+=(const FAddend &T) { 13409467b48Spatrick assert((Val == T.Val) && "Symbolic-values disagree"); 13509467b48Spatrick Coeff += T.Coeff; 13609467b48Spatrick } 13709467b48Spatrick 13809467b48Spatrick Value *getSymVal() const { return Val; } 13909467b48Spatrick const FAddendCoef &getCoef() const { return Coeff; } 14009467b48Spatrick 14109467b48Spatrick bool isConstant() const { return Val == nullptr; } 14209467b48Spatrick bool isZero() const { return Coeff.isZero(); } 14309467b48Spatrick 14409467b48Spatrick void set(short Coefficient, Value *V) { 14509467b48Spatrick Coeff.set(Coefficient); 14609467b48Spatrick Val = V; 14709467b48Spatrick } 14809467b48Spatrick void set(const APFloat &Coefficient, Value *V) { 14909467b48Spatrick Coeff.set(Coefficient); 15009467b48Spatrick Val = V; 15109467b48Spatrick } 15209467b48Spatrick void set(const ConstantFP *Coefficient, Value *V) { 15309467b48Spatrick Coeff.set(Coefficient->getValueAPF()); 15409467b48Spatrick Val = V; 15509467b48Spatrick } 15609467b48Spatrick 15709467b48Spatrick void negate() { Coeff.negate(); } 15809467b48Spatrick 15909467b48Spatrick /// Drill down the U-D chain one step to find the definition of V, and 16009467b48Spatrick /// try to break the definition into one or two addends. 16109467b48Spatrick static unsigned drillValueDownOneStep(Value* V, FAddend &A0, FAddend &A1); 16209467b48Spatrick 16309467b48Spatrick /// Similar to FAddend::drillDownOneStep() except that the value being 16409467b48Spatrick /// splitted is the addend itself. 16509467b48Spatrick unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const; 16609467b48Spatrick 16709467b48Spatrick private: 16809467b48Spatrick void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; } 16909467b48Spatrick 17009467b48Spatrick // This addend has the value of "Coeff * Val". 17109467b48Spatrick Value *Val = nullptr; 17209467b48Spatrick FAddendCoef Coeff; 17309467b48Spatrick }; 17409467b48Spatrick 17509467b48Spatrick /// FAddCombine is the class for optimizing an unsafe fadd/fsub along 17609467b48Spatrick /// with its neighboring at most two instructions. 17709467b48Spatrick /// 17809467b48Spatrick class FAddCombine { 17909467b48Spatrick public: 18009467b48Spatrick FAddCombine(InstCombiner::BuilderTy &B) : Builder(B) {} 18109467b48Spatrick 18209467b48Spatrick Value *simplify(Instruction *FAdd); 18309467b48Spatrick 18409467b48Spatrick private: 18509467b48Spatrick using AddendVect = SmallVector<const FAddend *, 4>; 18609467b48Spatrick 18709467b48Spatrick Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota); 18809467b48Spatrick 18909467b48Spatrick /// Convert given addend to a Value 19009467b48Spatrick Value *createAddendVal(const FAddend &A, bool& NeedNeg); 19109467b48Spatrick 19209467b48Spatrick /// Return the number of instructions needed to emit the N-ary addition. 19309467b48Spatrick unsigned calcInstrNumber(const AddendVect& Vect); 19409467b48Spatrick 19509467b48Spatrick Value *createFSub(Value *Opnd0, Value *Opnd1); 19609467b48Spatrick Value *createFAdd(Value *Opnd0, Value *Opnd1); 19709467b48Spatrick Value *createFMul(Value *Opnd0, Value *Opnd1); 19809467b48Spatrick Value *createFNeg(Value *V); 19909467b48Spatrick Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota); 20009467b48Spatrick void createInstPostProc(Instruction *NewInst, bool NoNumber = false); 20109467b48Spatrick 20209467b48Spatrick // Debugging stuff are clustered here. 20309467b48Spatrick #ifndef NDEBUG 20409467b48Spatrick unsigned CreateInstrNum; 20509467b48Spatrick void initCreateInstNum() { CreateInstrNum = 0; } 20609467b48Spatrick void incCreateInstNum() { CreateInstrNum++; } 20709467b48Spatrick #else 20809467b48Spatrick void initCreateInstNum() {} 20909467b48Spatrick void incCreateInstNum() {} 21009467b48Spatrick #endif 21109467b48Spatrick 21209467b48Spatrick InstCombiner::BuilderTy &Builder; 21309467b48Spatrick Instruction *Instr = nullptr; 21409467b48Spatrick }; 21509467b48Spatrick 21609467b48Spatrick } // end anonymous namespace 21709467b48Spatrick 21809467b48Spatrick //===----------------------------------------------------------------------===// 21909467b48Spatrick // 22009467b48Spatrick // Implementation of 22109467b48Spatrick // {FAddendCoef, FAddend, FAddition, FAddCombine}. 22209467b48Spatrick // 22309467b48Spatrick //===----------------------------------------------------------------------===// 22409467b48Spatrick FAddendCoef::~FAddendCoef() { 22509467b48Spatrick if (BufHasFpVal) 22609467b48Spatrick getFpValPtr()->~APFloat(); 22709467b48Spatrick } 22809467b48Spatrick 22909467b48Spatrick void FAddendCoef::set(const APFloat& C) { 23009467b48Spatrick APFloat *P = getFpValPtr(); 23109467b48Spatrick 23209467b48Spatrick if (isInt()) { 23309467b48Spatrick // As the buffer is meanless byte stream, we cannot call 23409467b48Spatrick // APFloat::operator=(). 23509467b48Spatrick new(P) APFloat(C); 23609467b48Spatrick } else 23709467b48Spatrick *P = C; 23809467b48Spatrick 23909467b48Spatrick IsFp = BufHasFpVal = true; 24009467b48Spatrick } 24109467b48Spatrick 24209467b48Spatrick void FAddendCoef::convertToFpType(const fltSemantics &Sem) { 24309467b48Spatrick if (!isInt()) 24409467b48Spatrick return; 24509467b48Spatrick 24609467b48Spatrick APFloat *P = getFpValPtr(); 24709467b48Spatrick if (IntVal > 0) 24809467b48Spatrick new(P) APFloat(Sem, IntVal); 24909467b48Spatrick else { 25009467b48Spatrick new(P) APFloat(Sem, 0 - IntVal); 25109467b48Spatrick P->changeSign(); 25209467b48Spatrick } 25309467b48Spatrick IsFp = BufHasFpVal = true; 25409467b48Spatrick } 25509467b48Spatrick 25609467b48Spatrick APFloat FAddendCoef::createAPFloatFromInt(const fltSemantics &Sem, int Val) { 25709467b48Spatrick if (Val >= 0) 25809467b48Spatrick return APFloat(Sem, Val); 25909467b48Spatrick 26009467b48Spatrick APFloat T(Sem, 0 - Val); 26109467b48Spatrick T.changeSign(); 26209467b48Spatrick 26309467b48Spatrick return T; 26409467b48Spatrick } 26509467b48Spatrick 26609467b48Spatrick void FAddendCoef::operator=(const FAddendCoef &That) { 26709467b48Spatrick if (That.isInt()) 26809467b48Spatrick set(That.IntVal); 26909467b48Spatrick else 27009467b48Spatrick set(That.getFpVal()); 27109467b48Spatrick } 27209467b48Spatrick 27309467b48Spatrick void FAddendCoef::operator+=(const FAddendCoef &That) { 274097a140dSpatrick RoundingMode RndMode = RoundingMode::NearestTiesToEven; 27509467b48Spatrick if (isInt() == That.isInt()) { 27609467b48Spatrick if (isInt()) 27709467b48Spatrick IntVal += That.IntVal; 27809467b48Spatrick else 27909467b48Spatrick getFpVal().add(That.getFpVal(), RndMode); 28009467b48Spatrick return; 28109467b48Spatrick } 28209467b48Spatrick 28309467b48Spatrick if (isInt()) { 28409467b48Spatrick const APFloat &T = That.getFpVal(); 28509467b48Spatrick convertToFpType(T.getSemantics()); 28609467b48Spatrick getFpVal().add(T, RndMode); 28709467b48Spatrick return; 28809467b48Spatrick } 28909467b48Spatrick 29009467b48Spatrick APFloat &T = getFpVal(); 29109467b48Spatrick T.add(createAPFloatFromInt(T.getSemantics(), That.IntVal), RndMode); 29209467b48Spatrick } 29309467b48Spatrick 29409467b48Spatrick void FAddendCoef::operator*=(const FAddendCoef &That) { 29509467b48Spatrick if (That.isOne()) 29609467b48Spatrick return; 29709467b48Spatrick 29809467b48Spatrick if (That.isMinusOne()) { 29909467b48Spatrick negate(); 30009467b48Spatrick return; 30109467b48Spatrick } 30209467b48Spatrick 30309467b48Spatrick if (isInt() && That.isInt()) { 30409467b48Spatrick int Res = IntVal * (int)That.IntVal; 30509467b48Spatrick assert(!insaneIntVal(Res) && "Insane int value"); 30609467b48Spatrick IntVal = Res; 30709467b48Spatrick return; 30809467b48Spatrick } 30909467b48Spatrick 31009467b48Spatrick const fltSemantics &Semantic = 31109467b48Spatrick isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics(); 31209467b48Spatrick 31309467b48Spatrick if (isInt()) 31409467b48Spatrick convertToFpType(Semantic); 31509467b48Spatrick APFloat &F0 = getFpVal(); 31609467b48Spatrick 31709467b48Spatrick if (That.isInt()) 31809467b48Spatrick F0.multiply(createAPFloatFromInt(Semantic, That.IntVal), 31909467b48Spatrick APFloat::rmNearestTiesToEven); 32009467b48Spatrick else 32109467b48Spatrick F0.multiply(That.getFpVal(), APFloat::rmNearestTiesToEven); 32209467b48Spatrick } 32309467b48Spatrick 32409467b48Spatrick void FAddendCoef::negate() { 32509467b48Spatrick if (isInt()) 32609467b48Spatrick IntVal = 0 - IntVal; 32709467b48Spatrick else 32809467b48Spatrick getFpVal().changeSign(); 32909467b48Spatrick } 33009467b48Spatrick 33109467b48Spatrick Value *FAddendCoef::getValue(Type *Ty) const { 33209467b48Spatrick return isInt() ? 33309467b48Spatrick ConstantFP::get(Ty, float(IntVal)) : 33409467b48Spatrick ConstantFP::get(Ty->getContext(), getFpVal()); 33509467b48Spatrick } 33609467b48Spatrick 33709467b48Spatrick // The definition of <Val> Addends 33809467b48Spatrick // ========================================= 33909467b48Spatrick // A + B <1, A>, <1,B> 34009467b48Spatrick // A - B <1, A>, <1,B> 34109467b48Spatrick // 0 - B <-1, B> 34209467b48Spatrick // C * A, <C, A> 34309467b48Spatrick // A + C <1, A> <C, NULL> 34409467b48Spatrick // 0 +/- 0 <0, NULL> (corner case) 34509467b48Spatrick // 34609467b48Spatrick // Legend: A and B are not constant, C is constant 34709467b48Spatrick unsigned FAddend::drillValueDownOneStep 34809467b48Spatrick (Value *Val, FAddend &Addend0, FAddend &Addend1) { 34909467b48Spatrick Instruction *I = nullptr; 35009467b48Spatrick if (!Val || !(I = dyn_cast<Instruction>(Val))) 35109467b48Spatrick return 0; 35209467b48Spatrick 35309467b48Spatrick unsigned Opcode = I->getOpcode(); 35409467b48Spatrick 35509467b48Spatrick if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) { 35609467b48Spatrick ConstantFP *C0, *C1; 35709467b48Spatrick Value *Opnd0 = I->getOperand(0); 35809467b48Spatrick Value *Opnd1 = I->getOperand(1); 35909467b48Spatrick if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->isZero()) 36009467b48Spatrick Opnd0 = nullptr; 36109467b48Spatrick 36209467b48Spatrick if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->isZero()) 36309467b48Spatrick Opnd1 = nullptr; 36409467b48Spatrick 36509467b48Spatrick if (Opnd0) { 36609467b48Spatrick if (!C0) 36709467b48Spatrick Addend0.set(1, Opnd0); 36809467b48Spatrick else 36909467b48Spatrick Addend0.set(C0, nullptr); 37009467b48Spatrick } 37109467b48Spatrick 37209467b48Spatrick if (Opnd1) { 37309467b48Spatrick FAddend &Addend = Opnd0 ? Addend1 : Addend0; 37409467b48Spatrick if (!C1) 37509467b48Spatrick Addend.set(1, Opnd1); 37609467b48Spatrick else 37709467b48Spatrick Addend.set(C1, nullptr); 37809467b48Spatrick if (Opcode == Instruction::FSub) 37909467b48Spatrick Addend.negate(); 38009467b48Spatrick } 38109467b48Spatrick 38209467b48Spatrick if (Opnd0 || Opnd1) 38309467b48Spatrick return Opnd0 && Opnd1 ? 2 : 1; 38409467b48Spatrick 38509467b48Spatrick // Both operands are zero. Weird! 38609467b48Spatrick Addend0.set(APFloat(C0->getValueAPF().getSemantics()), nullptr); 38709467b48Spatrick return 1; 38809467b48Spatrick } 38909467b48Spatrick 39009467b48Spatrick if (I->getOpcode() == Instruction::FMul) { 39109467b48Spatrick Value *V0 = I->getOperand(0); 39209467b48Spatrick Value *V1 = I->getOperand(1); 39309467b48Spatrick if (ConstantFP *C = dyn_cast<ConstantFP>(V0)) { 39409467b48Spatrick Addend0.set(C, V1); 39509467b48Spatrick return 1; 39609467b48Spatrick } 39709467b48Spatrick 39809467b48Spatrick if (ConstantFP *C = dyn_cast<ConstantFP>(V1)) { 39909467b48Spatrick Addend0.set(C, V0); 40009467b48Spatrick return 1; 40109467b48Spatrick } 40209467b48Spatrick } 40309467b48Spatrick 40409467b48Spatrick return 0; 40509467b48Spatrick } 40609467b48Spatrick 40709467b48Spatrick // Try to break *this* addend into two addends. e.g. Suppose this addend is 40809467b48Spatrick // <2.3, V>, and V = X + Y, by calling this function, we obtain two addends, 40909467b48Spatrick // i.e. <2.3, X> and <2.3, Y>. 41009467b48Spatrick unsigned FAddend::drillAddendDownOneStep 41109467b48Spatrick (FAddend &Addend0, FAddend &Addend1) const { 41209467b48Spatrick if (isConstant()) 41309467b48Spatrick return 0; 41409467b48Spatrick 41509467b48Spatrick unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1); 41609467b48Spatrick if (!BreakNum || Coeff.isOne()) 41709467b48Spatrick return BreakNum; 41809467b48Spatrick 41909467b48Spatrick Addend0.Scale(Coeff); 42009467b48Spatrick 42109467b48Spatrick if (BreakNum == 2) 42209467b48Spatrick Addend1.Scale(Coeff); 42309467b48Spatrick 42409467b48Spatrick return BreakNum; 42509467b48Spatrick } 42609467b48Spatrick 42709467b48Spatrick Value *FAddCombine::simplify(Instruction *I) { 42809467b48Spatrick assert(I->hasAllowReassoc() && I->hasNoSignedZeros() && 42909467b48Spatrick "Expected 'reassoc'+'nsz' instruction"); 43009467b48Spatrick 43109467b48Spatrick // Currently we are not able to handle vector type. 43209467b48Spatrick if (I->getType()->isVectorTy()) 43309467b48Spatrick return nullptr; 43409467b48Spatrick 43509467b48Spatrick assert((I->getOpcode() == Instruction::FAdd || 43609467b48Spatrick I->getOpcode() == Instruction::FSub) && "Expect add/sub"); 43709467b48Spatrick 43809467b48Spatrick // Save the instruction before calling other member-functions. 43909467b48Spatrick Instr = I; 44009467b48Spatrick 44109467b48Spatrick FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1; 44209467b48Spatrick 44309467b48Spatrick unsigned OpndNum = FAddend::drillValueDownOneStep(I, Opnd0, Opnd1); 44409467b48Spatrick 44509467b48Spatrick // Step 1: Expand the 1st addend into Opnd0_0 and Opnd0_1. 44609467b48Spatrick unsigned Opnd0_ExpNum = 0; 44709467b48Spatrick unsigned Opnd1_ExpNum = 0; 44809467b48Spatrick 44909467b48Spatrick if (!Opnd0.isConstant()) 45009467b48Spatrick Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1); 45109467b48Spatrick 45209467b48Spatrick // Step 2: Expand the 2nd addend into Opnd1_0 and Opnd1_1. 45309467b48Spatrick if (OpndNum == 2 && !Opnd1.isConstant()) 45409467b48Spatrick Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1); 45509467b48Spatrick 45609467b48Spatrick // Step 3: Try to optimize Opnd0_0 + Opnd0_1 + Opnd1_0 + Opnd1_1 45709467b48Spatrick if (Opnd0_ExpNum && Opnd1_ExpNum) { 45809467b48Spatrick AddendVect AllOpnds; 45909467b48Spatrick AllOpnds.push_back(&Opnd0_0); 46009467b48Spatrick AllOpnds.push_back(&Opnd1_0); 46109467b48Spatrick if (Opnd0_ExpNum == 2) 46209467b48Spatrick AllOpnds.push_back(&Opnd0_1); 46309467b48Spatrick if (Opnd1_ExpNum == 2) 46409467b48Spatrick AllOpnds.push_back(&Opnd1_1); 46509467b48Spatrick 46609467b48Spatrick // Compute instruction quota. We should save at least one instruction. 46709467b48Spatrick unsigned InstQuota = 0; 46809467b48Spatrick 46909467b48Spatrick Value *V0 = I->getOperand(0); 47009467b48Spatrick Value *V1 = I->getOperand(1); 47109467b48Spatrick InstQuota = ((!isa<Constant>(V0) && V0->hasOneUse()) && 47209467b48Spatrick (!isa<Constant>(V1) && V1->hasOneUse())) ? 2 : 1; 47309467b48Spatrick 47409467b48Spatrick if (Value *R = simplifyFAdd(AllOpnds, InstQuota)) 47509467b48Spatrick return R; 47609467b48Spatrick } 47709467b48Spatrick 47809467b48Spatrick if (OpndNum != 2) { 47909467b48Spatrick // The input instruction is : "I=0.0 +/- V". If the "V" were able to be 48009467b48Spatrick // splitted into two addends, say "V = X - Y", the instruction would have 48109467b48Spatrick // been optimized into "I = Y - X" in the previous steps. 48209467b48Spatrick // 48309467b48Spatrick const FAddendCoef &CE = Opnd0.getCoef(); 48409467b48Spatrick return CE.isOne() ? Opnd0.getSymVal() : nullptr; 48509467b48Spatrick } 48609467b48Spatrick 48709467b48Spatrick // step 4: Try to optimize Opnd0 + Opnd1_0 [+ Opnd1_1] 48809467b48Spatrick if (Opnd1_ExpNum) { 48909467b48Spatrick AddendVect AllOpnds; 49009467b48Spatrick AllOpnds.push_back(&Opnd0); 49109467b48Spatrick AllOpnds.push_back(&Opnd1_0); 49209467b48Spatrick if (Opnd1_ExpNum == 2) 49309467b48Spatrick AllOpnds.push_back(&Opnd1_1); 49409467b48Spatrick 49509467b48Spatrick if (Value *R = simplifyFAdd(AllOpnds, 1)) 49609467b48Spatrick return R; 49709467b48Spatrick } 49809467b48Spatrick 49909467b48Spatrick // step 5: Try to optimize Opnd1 + Opnd0_0 [+ Opnd0_1] 50009467b48Spatrick if (Opnd0_ExpNum) { 50109467b48Spatrick AddendVect AllOpnds; 50209467b48Spatrick AllOpnds.push_back(&Opnd1); 50309467b48Spatrick AllOpnds.push_back(&Opnd0_0); 50409467b48Spatrick if (Opnd0_ExpNum == 2) 50509467b48Spatrick AllOpnds.push_back(&Opnd0_1); 50609467b48Spatrick 50709467b48Spatrick if (Value *R = simplifyFAdd(AllOpnds, 1)) 50809467b48Spatrick return R; 50909467b48Spatrick } 51009467b48Spatrick 51109467b48Spatrick return nullptr; 51209467b48Spatrick } 51309467b48Spatrick 51409467b48Spatrick Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) { 51509467b48Spatrick unsigned AddendNum = Addends.size(); 51609467b48Spatrick assert(AddendNum <= 4 && "Too many addends"); 51709467b48Spatrick 51809467b48Spatrick // For saving intermediate results; 51909467b48Spatrick unsigned NextTmpIdx = 0; 52009467b48Spatrick FAddend TmpResult[3]; 52109467b48Spatrick 52209467b48Spatrick // Points to the constant addend of the resulting simplified expression. 52309467b48Spatrick // If the resulting expr has constant-addend, this constant-addend is 52409467b48Spatrick // desirable to reside at the top of the resulting expression tree. Placing 52509467b48Spatrick // constant close to supper-expr(s) will potentially reveal some optimization 52609467b48Spatrick // opportunities in super-expr(s). 52709467b48Spatrick const FAddend *ConstAdd = nullptr; 52809467b48Spatrick 52909467b48Spatrick // Simplified addends are placed <SimpVect>. 53009467b48Spatrick AddendVect SimpVect; 53109467b48Spatrick 53209467b48Spatrick // The outer loop works on one symbolic-value at a time. Suppose the input 53309467b48Spatrick // addends are : <a1, x>, <b1, y>, <a2, x>, <c1, z>, <b2, y>, ... 53409467b48Spatrick // The symbolic-values will be processed in this order: x, y, z. 53509467b48Spatrick for (unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) { 53609467b48Spatrick 53709467b48Spatrick const FAddend *ThisAddend = Addends[SymIdx]; 53809467b48Spatrick if (!ThisAddend) { 53909467b48Spatrick // This addend was processed before. 54009467b48Spatrick continue; 54109467b48Spatrick } 54209467b48Spatrick 54309467b48Spatrick Value *Val = ThisAddend->getSymVal(); 54409467b48Spatrick unsigned StartIdx = SimpVect.size(); 54509467b48Spatrick SimpVect.push_back(ThisAddend); 54609467b48Spatrick 54709467b48Spatrick // The inner loop collects addends sharing same symbolic-value, and these 54809467b48Spatrick // addends will be later on folded into a single addend. Following above 54909467b48Spatrick // example, if the symbolic value "y" is being processed, the inner loop 55009467b48Spatrick // will collect two addends "<b1,y>" and "<b2,Y>". These two addends will 55109467b48Spatrick // be later on folded into "<b1+b2, y>". 55209467b48Spatrick for (unsigned SameSymIdx = SymIdx + 1; 55309467b48Spatrick SameSymIdx < AddendNum; SameSymIdx++) { 55409467b48Spatrick const FAddend *T = Addends[SameSymIdx]; 55509467b48Spatrick if (T && T->getSymVal() == Val) { 55609467b48Spatrick // Set null such that next iteration of the outer loop will not process 55709467b48Spatrick // this addend again. 55809467b48Spatrick Addends[SameSymIdx] = nullptr; 55909467b48Spatrick SimpVect.push_back(T); 56009467b48Spatrick } 56109467b48Spatrick } 56209467b48Spatrick 56309467b48Spatrick // If multiple addends share same symbolic value, fold them together. 56409467b48Spatrick if (StartIdx + 1 != SimpVect.size()) { 56509467b48Spatrick FAddend &R = TmpResult[NextTmpIdx ++]; 56609467b48Spatrick R = *SimpVect[StartIdx]; 56709467b48Spatrick for (unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++) 56809467b48Spatrick R += *SimpVect[Idx]; 56909467b48Spatrick 57009467b48Spatrick // Pop all addends being folded and push the resulting folded addend. 57109467b48Spatrick SimpVect.resize(StartIdx); 57209467b48Spatrick if (Val) { 57309467b48Spatrick if (!R.isZero()) { 57409467b48Spatrick SimpVect.push_back(&R); 57509467b48Spatrick } 57609467b48Spatrick } else { 57709467b48Spatrick // Don't push constant addend at this time. It will be the last element 57809467b48Spatrick // of <SimpVect>. 57909467b48Spatrick ConstAdd = &R; 58009467b48Spatrick } 58109467b48Spatrick } 58209467b48Spatrick } 58309467b48Spatrick 58409467b48Spatrick assert((NextTmpIdx <= array_lengthof(TmpResult) + 1) && 58509467b48Spatrick "out-of-bound access"); 58609467b48Spatrick 58709467b48Spatrick if (ConstAdd) 58809467b48Spatrick SimpVect.push_back(ConstAdd); 58909467b48Spatrick 59009467b48Spatrick Value *Result; 59109467b48Spatrick if (!SimpVect.empty()) 59209467b48Spatrick Result = createNaryFAdd(SimpVect, InstrQuota); 59309467b48Spatrick else { 59409467b48Spatrick // The addition is folded to 0.0. 59509467b48Spatrick Result = ConstantFP::get(Instr->getType(), 0.0); 59609467b48Spatrick } 59709467b48Spatrick 59809467b48Spatrick return Result; 59909467b48Spatrick } 60009467b48Spatrick 60109467b48Spatrick Value *FAddCombine::createNaryFAdd 60209467b48Spatrick (const AddendVect &Opnds, unsigned InstrQuota) { 60309467b48Spatrick assert(!Opnds.empty() && "Expect at least one addend"); 60409467b48Spatrick 60509467b48Spatrick // Step 1: Check if the # of instructions needed exceeds the quota. 60609467b48Spatrick 60709467b48Spatrick unsigned InstrNeeded = calcInstrNumber(Opnds); 60809467b48Spatrick if (InstrNeeded > InstrQuota) 60909467b48Spatrick return nullptr; 61009467b48Spatrick 61109467b48Spatrick initCreateInstNum(); 61209467b48Spatrick 61309467b48Spatrick // step 2: Emit the N-ary addition. 61409467b48Spatrick // Note that at most three instructions are involved in Fadd-InstCombine: the 61509467b48Spatrick // addition in question, and at most two neighboring instructions. 61609467b48Spatrick // The resulting optimized addition should have at least one less instruction 61709467b48Spatrick // than the original addition expression tree. This implies that the resulting 61809467b48Spatrick // N-ary addition has at most two instructions, and we don't need to worry 61909467b48Spatrick // about tree-height when constructing the N-ary addition. 62009467b48Spatrick 62109467b48Spatrick Value *LastVal = nullptr; 62209467b48Spatrick bool LastValNeedNeg = false; 62309467b48Spatrick 62409467b48Spatrick // Iterate the addends, creating fadd/fsub using adjacent two addends. 62509467b48Spatrick for (const FAddend *Opnd : Opnds) { 62609467b48Spatrick bool NeedNeg; 62709467b48Spatrick Value *V = createAddendVal(*Opnd, NeedNeg); 62809467b48Spatrick if (!LastVal) { 62909467b48Spatrick LastVal = V; 63009467b48Spatrick LastValNeedNeg = NeedNeg; 63109467b48Spatrick continue; 63209467b48Spatrick } 63309467b48Spatrick 63409467b48Spatrick if (LastValNeedNeg == NeedNeg) { 63509467b48Spatrick LastVal = createFAdd(LastVal, V); 63609467b48Spatrick continue; 63709467b48Spatrick } 63809467b48Spatrick 63909467b48Spatrick if (LastValNeedNeg) 64009467b48Spatrick LastVal = createFSub(V, LastVal); 64109467b48Spatrick else 64209467b48Spatrick LastVal = createFSub(LastVal, V); 64309467b48Spatrick 64409467b48Spatrick LastValNeedNeg = false; 64509467b48Spatrick } 64609467b48Spatrick 64709467b48Spatrick if (LastValNeedNeg) { 64809467b48Spatrick LastVal = createFNeg(LastVal); 64909467b48Spatrick } 65009467b48Spatrick 65109467b48Spatrick #ifndef NDEBUG 65209467b48Spatrick assert(CreateInstrNum == InstrNeeded && 65309467b48Spatrick "Inconsistent in instruction numbers"); 65409467b48Spatrick #endif 65509467b48Spatrick 65609467b48Spatrick return LastVal; 65709467b48Spatrick } 65809467b48Spatrick 65909467b48Spatrick Value *FAddCombine::createFSub(Value *Opnd0, Value *Opnd1) { 66009467b48Spatrick Value *V = Builder.CreateFSub(Opnd0, Opnd1); 66109467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(V)) 66209467b48Spatrick createInstPostProc(I); 66309467b48Spatrick return V; 66409467b48Spatrick } 66509467b48Spatrick 66609467b48Spatrick Value *FAddCombine::createFNeg(Value *V) { 667097a140dSpatrick Value *NewV = Builder.CreateFNeg(V); 66809467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(NewV)) 66909467b48Spatrick createInstPostProc(I, true); // fneg's don't receive instruction numbers. 67009467b48Spatrick return NewV; 67109467b48Spatrick } 67209467b48Spatrick 67309467b48Spatrick Value *FAddCombine::createFAdd(Value *Opnd0, Value *Opnd1) { 67409467b48Spatrick Value *V = Builder.CreateFAdd(Opnd0, Opnd1); 67509467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(V)) 67609467b48Spatrick createInstPostProc(I); 67709467b48Spatrick return V; 67809467b48Spatrick } 67909467b48Spatrick 68009467b48Spatrick Value *FAddCombine::createFMul(Value *Opnd0, Value *Opnd1) { 68109467b48Spatrick Value *V = Builder.CreateFMul(Opnd0, Opnd1); 68209467b48Spatrick if (Instruction *I = dyn_cast<Instruction>(V)) 68309467b48Spatrick createInstPostProc(I); 68409467b48Spatrick return V; 68509467b48Spatrick } 68609467b48Spatrick 68709467b48Spatrick void FAddCombine::createInstPostProc(Instruction *NewInstr, bool NoNumber) { 68809467b48Spatrick NewInstr->setDebugLoc(Instr->getDebugLoc()); 68909467b48Spatrick 69009467b48Spatrick // Keep track of the number of instruction created. 69109467b48Spatrick if (!NoNumber) 69209467b48Spatrick incCreateInstNum(); 69309467b48Spatrick 69409467b48Spatrick // Propagate fast-math flags 69509467b48Spatrick NewInstr->setFastMathFlags(Instr->getFastMathFlags()); 69609467b48Spatrick } 69709467b48Spatrick 69809467b48Spatrick // Return the number of instruction needed to emit the N-ary addition. 69909467b48Spatrick // NOTE: Keep this function in sync with createAddendVal(). 70009467b48Spatrick unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) { 70109467b48Spatrick unsigned OpndNum = Opnds.size(); 70209467b48Spatrick unsigned InstrNeeded = OpndNum - 1; 70309467b48Spatrick 70409467b48Spatrick // The number of addends in the form of "(-1)*x". 70509467b48Spatrick unsigned NegOpndNum = 0; 70609467b48Spatrick 70709467b48Spatrick // Adjust the number of instructions needed to emit the N-ary add. 70809467b48Spatrick for (const FAddend *Opnd : Opnds) { 70909467b48Spatrick if (Opnd->isConstant()) 71009467b48Spatrick continue; 71109467b48Spatrick 71209467b48Spatrick // The constant check above is really for a few special constant 71309467b48Spatrick // coefficients. 71409467b48Spatrick if (isa<UndefValue>(Opnd->getSymVal())) 71509467b48Spatrick continue; 71609467b48Spatrick 71709467b48Spatrick const FAddendCoef &CE = Opnd->getCoef(); 71809467b48Spatrick if (CE.isMinusOne() || CE.isMinusTwo()) 71909467b48Spatrick NegOpndNum++; 72009467b48Spatrick 72109467b48Spatrick // Let the addend be "c * x". If "c == +/-1", the value of the addend 72209467b48Spatrick // is immediately available; otherwise, it needs exactly one instruction 72309467b48Spatrick // to evaluate the value. 72409467b48Spatrick if (!CE.isMinusOne() && !CE.isOne()) 72509467b48Spatrick InstrNeeded++; 72609467b48Spatrick } 72709467b48Spatrick return InstrNeeded; 72809467b48Spatrick } 72909467b48Spatrick 73009467b48Spatrick // Input Addend Value NeedNeg(output) 73109467b48Spatrick // ================================================================ 73209467b48Spatrick // Constant C C false 73309467b48Spatrick // <+/-1, V> V coefficient is -1 73409467b48Spatrick // <2/-2, V> "fadd V, V" coefficient is -2 73509467b48Spatrick // <C, V> "fmul V, C" false 73609467b48Spatrick // 73709467b48Spatrick // NOTE: Keep this function in sync with FAddCombine::calcInstrNumber. 73809467b48Spatrick Value *FAddCombine::createAddendVal(const FAddend &Opnd, bool &NeedNeg) { 73909467b48Spatrick const FAddendCoef &Coeff = Opnd.getCoef(); 74009467b48Spatrick 74109467b48Spatrick if (Opnd.isConstant()) { 74209467b48Spatrick NeedNeg = false; 74309467b48Spatrick return Coeff.getValue(Instr->getType()); 74409467b48Spatrick } 74509467b48Spatrick 74609467b48Spatrick Value *OpndVal = Opnd.getSymVal(); 74709467b48Spatrick 74809467b48Spatrick if (Coeff.isMinusOne() || Coeff.isOne()) { 74909467b48Spatrick NeedNeg = Coeff.isMinusOne(); 75009467b48Spatrick return OpndVal; 75109467b48Spatrick } 75209467b48Spatrick 75309467b48Spatrick if (Coeff.isTwo() || Coeff.isMinusTwo()) { 75409467b48Spatrick NeedNeg = Coeff.isMinusTwo(); 75509467b48Spatrick return createFAdd(OpndVal, OpndVal); 75609467b48Spatrick } 75709467b48Spatrick 75809467b48Spatrick NeedNeg = false; 75909467b48Spatrick return createFMul(OpndVal, Coeff.getValue(Instr->getType())); 76009467b48Spatrick } 76109467b48Spatrick 76209467b48Spatrick // Checks if any operand is negative and we can convert add to sub. 76309467b48Spatrick // This function checks for following negative patterns 76409467b48Spatrick // ADD(XOR(OR(Z, NOT(C)), C)), 1) == NEG(AND(Z, C)) 76509467b48Spatrick // ADD(XOR(AND(Z, C), C), 1) == NEG(OR(Z, ~C)) 76609467b48Spatrick // XOR(AND(Z, C), (C + 1)) == NEG(OR(Z, ~C)) if C is even 76709467b48Spatrick static Value *checkForNegativeOperand(BinaryOperator &I, 76809467b48Spatrick InstCombiner::BuilderTy &Builder) { 76909467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 77009467b48Spatrick 77109467b48Spatrick // This function creates 2 instructions to replace ADD, we need at least one 77209467b48Spatrick // of LHS or RHS to have one use to ensure benefit in transform. 77309467b48Spatrick if (!LHS->hasOneUse() && !RHS->hasOneUse()) 77409467b48Spatrick return nullptr; 77509467b48Spatrick 77609467b48Spatrick Value *X = nullptr, *Y = nullptr, *Z = nullptr; 77709467b48Spatrick const APInt *C1 = nullptr, *C2 = nullptr; 77809467b48Spatrick 77909467b48Spatrick // if ONE is on other side, swap 78009467b48Spatrick if (match(RHS, m_Add(m_Value(X), m_One()))) 78109467b48Spatrick std::swap(LHS, RHS); 78209467b48Spatrick 78309467b48Spatrick if (match(LHS, m_Add(m_Value(X), m_One()))) { 78409467b48Spatrick // if XOR on other side, swap 78509467b48Spatrick if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1)))) 78609467b48Spatrick std::swap(X, RHS); 78709467b48Spatrick 78809467b48Spatrick if (match(X, m_Xor(m_Value(Y), m_APInt(C1)))) { 78909467b48Spatrick // X = XOR(Y, C1), Y = OR(Z, C2), C2 = NOT(C1) ==> X == NOT(AND(Z, C1)) 79009467b48Spatrick // ADD(ADD(X, 1), RHS) == ADD(X, ADD(RHS, 1)) == SUB(RHS, AND(Z, C1)) 79109467b48Spatrick if (match(Y, m_Or(m_Value(Z), m_APInt(C2))) && (*C2 == ~(*C1))) { 79209467b48Spatrick Value *NewAnd = Builder.CreateAnd(Z, *C1); 79309467b48Spatrick return Builder.CreateSub(RHS, NewAnd, "sub"); 79409467b48Spatrick } else if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && (*C1 == *C2)) { 79509467b48Spatrick // X = XOR(Y, C1), Y = AND(Z, C2), C2 == C1 ==> X == NOT(OR(Z, ~C1)) 79609467b48Spatrick // ADD(ADD(X, 1), RHS) == ADD(X, ADD(RHS, 1)) == SUB(RHS, OR(Z, ~C1)) 79709467b48Spatrick Value *NewOr = Builder.CreateOr(Z, ~(*C1)); 79809467b48Spatrick return Builder.CreateSub(RHS, NewOr, "sub"); 79909467b48Spatrick } 80009467b48Spatrick } 80109467b48Spatrick } 80209467b48Spatrick 80309467b48Spatrick // Restore LHS and RHS 80409467b48Spatrick LHS = I.getOperand(0); 80509467b48Spatrick RHS = I.getOperand(1); 80609467b48Spatrick 80709467b48Spatrick // if XOR is on other side, swap 80809467b48Spatrick if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1)))) 80909467b48Spatrick std::swap(LHS, RHS); 81009467b48Spatrick 81109467b48Spatrick // C2 is ODD 81209467b48Spatrick // LHS = XOR(Y, C1), Y = AND(Z, C2), C1 == (C2 + 1) => LHS == NEG(OR(Z, ~C2)) 81309467b48Spatrick // ADD(LHS, RHS) == SUB(RHS, OR(Z, ~C2)) 81409467b48Spatrick if (match(LHS, m_Xor(m_Value(Y), m_APInt(C1)))) 81509467b48Spatrick if (C1->countTrailingZeros() == 0) 81609467b48Spatrick if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && *C1 == (*C2 + 1)) { 81709467b48Spatrick Value *NewOr = Builder.CreateOr(Z, ~(*C2)); 81809467b48Spatrick return Builder.CreateSub(RHS, NewOr, "sub"); 81909467b48Spatrick } 82009467b48Spatrick return nullptr; 82109467b48Spatrick } 82209467b48Spatrick 82309467b48Spatrick /// Wrapping flags may allow combining constants separated by an extend. 82409467b48Spatrick static Instruction *foldNoWrapAdd(BinaryOperator &Add, 82509467b48Spatrick InstCombiner::BuilderTy &Builder) { 82609467b48Spatrick Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1); 82709467b48Spatrick Type *Ty = Add.getType(); 82809467b48Spatrick Constant *Op1C; 82909467b48Spatrick if (!match(Op1, m_Constant(Op1C))) 83009467b48Spatrick return nullptr; 83109467b48Spatrick 83209467b48Spatrick // Try this match first because it results in an add in the narrow type. 83309467b48Spatrick // (zext (X +nuw C2)) + C1 --> zext (X + (C2 + trunc(C1))) 83409467b48Spatrick Value *X; 83509467b48Spatrick const APInt *C1, *C2; 83609467b48Spatrick if (match(Op1, m_APInt(C1)) && 83709467b48Spatrick match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2))))) && 83809467b48Spatrick C1->isNegative() && C1->sge(-C2->sext(C1->getBitWidth()))) { 83909467b48Spatrick Constant *NewC = 84009467b48Spatrick ConstantInt::get(X->getType(), *C2 + C1->trunc(C2->getBitWidth())); 84109467b48Spatrick return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty); 84209467b48Spatrick } 84309467b48Spatrick 84409467b48Spatrick // More general combining of constants in the wide type. 84509467b48Spatrick // (sext (X +nsw NarrowC)) + C --> (sext X) + (sext(NarrowC) + C) 84609467b48Spatrick Constant *NarrowC; 84709467b48Spatrick if (match(Op0, m_OneUse(m_SExt(m_NSWAdd(m_Value(X), m_Constant(NarrowC)))))) { 84809467b48Spatrick Constant *WideC = ConstantExpr::getSExt(NarrowC, Ty); 84909467b48Spatrick Constant *NewC = ConstantExpr::getAdd(WideC, Op1C); 85009467b48Spatrick Value *WideX = Builder.CreateSExt(X, Ty); 85109467b48Spatrick return BinaryOperator::CreateAdd(WideX, NewC); 85209467b48Spatrick } 85309467b48Spatrick // (zext (X +nuw NarrowC)) + C --> (zext X) + (zext(NarrowC) + C) 85409467b48Spatrick if (match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_Constant(NarrowC)))))) { 85509467b48Spatrick Constant *WideC = ConstantExpr::getZExt(NarrowC, Ty); 85609467b48Spatrick Constant *NewC = ConstantExpr::getAdd(WideC, Op1C); 85709467b48Spatrick Value *WideX = Builder.CreateZExt(X, Ty); 85809467b48Spatrick return BinaryOperator::CreateAdd(WideX, NewC); 85909467b48Spatrick } 86009467b48Spatrick 86109467b48Spatrick return nullptr; 86209467b48Spatrick } 86309467b48Spatrick 864*73471bf0Spatrick Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) { 86509467b48Spatrick Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1); 86609467b48Spatrick Constant *Op1C; 867*73471bf0Spatrick if (!match(Op1, m_ImmConstant(Op1C))) 86809467b48Spatrick return nullptr; 86909467b48Spatrick 87009467b48Spatrick if (Instruction *NV = foldBinOpIntoSelectOrPhi(Add)) 87109467b48Spatrick return NV; 87209467b48Spatrick 87309467b48Spatrick Value *X; 87409467b48Spatrick Constant *Op00C; 87509467b48Spatrick 87609467b48Spatrick // add (sub C1, X), C2 --> sub (add C1, C2), X 87709467b48Spatrick if (match(Op0, m_Sub(m_Constant(Op00C), m_Value(X)))) 87809467b48Spatrick return BinaryOperator::CreateSub(ConstantExpr::getAdd(Op00C, Op1C), X); 87909467b48Spatrick 88009467b48Spatrick Value *Y; 88109467b48Spatrick 88209467b48Spatrick // add (sub X, Y), -1 --> add (not Y), X 88309467b48Spatrick if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))) && 88409467b48Spatrick match(Op1, m_AllOnes())) 88509467b48Spatrick return BinaryOperator::CreateAdd(Builder.CreateNot(Y), X); 88609467b48Spatrick 88709467b48Spatrick // zext(bool) + C -> bool ? C + 1 : C 88809467b48Spatrick if (match(Op0, m_ZExt(m_Value(X))) && 88909467b48Spatrick X->getType()->getScalarSizeInBits() == 1) 890*73471bf0Spatrick return SelectInst::Create(X, InstCombiner::AddOne(Op1C), Op1); 89109467b48Spatrick // sext(bool) + C -> bool ? C - 1 : C 89209467b48Spatrick if (match(Op0, m_SExt(m_Value(X))) && 89309467b48Spatrick X->getType()->getScalarSizeInBits() == 1) 894*73471bf0Spatrick return SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1); 89509467b48Spatrick 89609467b48Spatrick // ~X + C --> (C-1) - X 89709467b48Spatrick if (match(Op0, m_Not(m_Value(X)))) 898*73471bf0Spatrick return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X); 89909467b48Spatrick 90009467b48Spatrick const APInt *C; 90109467b48Spatrick if (!match(Op1, m_APInt(C))) 90209467b48Spatrick return nullptr; 90309467b48Spatrick 904*73471bf0Spatrick // (X | Op01C) + Op1C --> X + (Op01C + Op1C) iff the `or` is actually an `add` 905*73471bf0Spatrick Constant *Op01C; 906*73471bf0Spatrick if (match(Op0, m_Or(m_Value(X), m_ImmConstant(Op01C))) && 907*73471bf0Spatrick haveNoCommonBitsSet(X, Op01C, DL, &AC, &Add, &DT)) 908*73471bf0Spatrick return BinaryOperator::CreateAdd(X, ConstantExpr::getAdd(Op01C, Op1C)); 909*73471bf0Spatrick 91009467b48Spatrick // (X | C2) + C --> (X | C2) ^ C2 iff (C2 == -C) 91109467b48Spatrick const APInt *C2; 91209467b48Spatrick if (match(Op0, m_Or(m_Value(), m_APInt(C2))) && *C2 == -*C) 91309467b48Spatrick return BinaryOperator::CreateXor(Op0, ConstantInt::get(Add.getType(), *C2)); 91409467b48Spatrick 91509467b48Spatrick if (C->isSignMask()) { 91609467b48Spatrick // If wrapping is not allowed, then the addition must set the sign bit: 91709467b48Spatrick // X + (signmask) --> X | signmask 91809467b48Spatrick if (Add.hasNoSignedWrap() || Add.hasNoUnsignedWrap()) 91909467b48Spatrick return BinaryOperator::CreateOr(Op0, Op1); 92009467b48Spatrick 92109467b48Spatrick // If wrapping is allowed, then the addition flips the sign bit of LHS: 92209467b48Spatrick // X + (signmask) --> X ^ signmask 92309467b48Spatrick return BinaryOperator::CreateXor(Op0, Op1); 92409467b48Spatrick } 92509467b48Spatrick 92609467b48Spatrick // Is this add the last step in a convoluted sext? 92709467b48Spatrick // add(zext(xor i16 X, -32768), -32768) --> sext X 92809467b48Spatrick Type *Ty = Add.getType(); 92909467b48Spatrick if (match(Op0, m_ZExt(m_Xor(m_Value(X), m_APInt(C2)))) && 93009467b48Spatrick C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C) 93109467b48Spatrick return CastInst::Create(Instruction::SExt, X, Ty); 93209467b48Spatrick 933*73471bf0Spatrick if (match(Op0, m_Xor(m_Value(X), m_APInt(C2)))) { 934*73471bf0Spatrick // (X ^ signmask) + C --> (X + (signmask ^ C)) 935*73471bf0Spatrick if (C2->isSignMask()) 936*73471bf0Spatrick return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C2 ^ *C)); 937*73471bf0Spatrick 938*73471bf0Spatrick // If X has no high-bits set above an xor mask: 939*73471bf0Spatrick // add (xor X, LowMaskC), C --> sub (LowMaskC + C), X 940*73471bf0Spatrick if (C2->isMask()) { 941*73471bf0Spatrick KnownBits LHSKnown = computeKnownBits(X, 0, &Add); 942*73471bf0Spatrick if ((*C2 | LHSKnown.Zero).isAllOnesValue()) 943*73471bf0Spatrick return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *C), X); 944*73471bf0Spatrick } 945*73471bf0Spatrick 946*73471bf0Spatrick // Look for a math+logic pattern that corresponds to sext-in-register of a 947*73471bf0Spatrick // value with cleared high bits. Convert that into a pair of shifts: 948*73471bf0Spatrick // add (xor X, 0x80), 0xF..F80 --> (X << ShAmtC) >>s ShAmtC 949*73471bf0Spatrick // add (xor X, 0xF..F80), 0x80 --> (X << ShAmtC) >>s ShAmtC 950*73471bf0Spatrick if (Op0->hasOneUse() && *C2 == -(*C)) { 951*73471bf0Spatrick unsigned BitWidth = Ty->getScalarSizeInBits(); 952*73471bf0Spatrick unsigned ShAmt = 0; 953*73471bf0Spatrick if (C->isPowerOf2()) 954*73471bf0Spatrick ShAmt = BitWidth - C->logBase2() - 1; 955*73471bf0Spatrick else if (C2->isPowerOf2()) 956*73471bf0Spatrick ShAmt = BitWidth - C2->logBase2() - 1; 957*73471bf0Spatrick if (ShAmt && MaskedValueIsZero(X, APInt::getHighBitsSet(BitWidth, ShAmt), 958*73471bf0Spatrick 0, &Add)) { 959*73471bf0Spatrick Constant *ShAmtC = ConstantInt::get(Ty, ShAmt); 960*73471bf0Spatrick Value *NewShl = Builder.CreateShl(X, ShAmtC, "sext"); 961*73471bf0Spatrick return BinaryOperator::CreateAShr(NewShl, ShAmtC); 962*73471bf0Spatrick } 963*73471bf0Spatrick } 964*73471bf0Spatrick } 965*73471bf0Spatrick 96609467b48Spatrick if (C->isOneValue() && Op0->hasOneUse()) { 96709467b48Spatrick // add (sext i1 X), 1 --> zext (not X) 96809467b48Spatrick // TODO: The smallest IR representation is (select X, 0, 1), and that would 96909467b48Spatrick // not require the one-use check. But we need to remove a transform in 97009467b48Spatrick // visitSelect and make sure that IR value tracking for select is equal or 97109467b48Spatrick // better than for these ops. 97209467b48Spatrick if (match(Op0, m_SExt(m_Value(X))) && 97309467b48Spatrick X->getType()->getScalarSizeInBits() == 1) 97409467b48Spatrick return new ZExtInst(Builder.CreateNot(X), Ty); 97509467b48Spatrick 97609467b48Spatrick // Shifts and add used to flip and mask off the low bit: 97709467b48Spatrick // add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1 97809467b48Spatrick const APInt *C3; 97909467b48Spatrick if (match(Op0, m_AShr(m_Shl(m_Value(X), m_APInt(C2)), m_APInt(C3))) && 98009467b48Spatrick C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) { 98109467b48Spatrick Value *NotX = Builder.CreateNot(X); 98209467b48Spatrick return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1)); 98309467b48Spatrick } 98409467b48Spatrick } 98509467b48Spatrick 986*73471bf0Spatrick // If all bits affected by the add are included in a high-bit-mask, do the 987*73471bf0Spatrick // add before the mask op: 988*73471bf0Spatrick // (X & 0xFF00) + xx00 --> (X + xx00) & 0xFF00 989*73471bf0Spatrick if (match(Op0, m_OneUse(m_And(m_Value(X), m_APInt(C2)))) && 990*73471bf0Spatrick C2->isNegative() && C2->isShiftedMask() && *C == (*C & *C2)) { 991*73471bf0Spatrick Value *NewAdd = Builder.CreateAdd(X, ConstantInt::get(Ty, *C)); 992*73471bf0Spatrick return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *C2)); 993*73471bf0Spatrick } 994*73471bf0Spatrick 99509467b48Spatrick return nullptr; 99609467b48Spatrick } 99709467b48Spatrick 99809467b48Spatrick // Matches multiplication expression Op * C where C is a constant. Returns the 99909467b48Spatrick // constant value in C and the other operand in Op. Returns true if such a 100009467b48Spatrick // match is found. 100109467b48Spatrick static bool MatchMul(Value *E, Value *&Op, APInt &C) { 100209467b48Spatrick const APInt *AI; 100309467b48Spatrick if (match(E, m_Mul(m_Value(Op), m_APInt(AI)))) { 100409467b48Spatrick C = *AI; 100509467b48Spatrick return true; 100609467b48Spatrick } 100709467b48Spatrick if (match(E, m_Shl(m_Value(Op), m_APInt(AI)))) { 100809467b48Spatrick C = APInt(AI->getBitWidth(), 1); 100909467b48Spatrick C <<= *AI; 101009467b48Spatrick return true; 101109467b48Spatrick } 101209467b48Spatrick return false; 101309467b48Spatrick } 101409467b48Spatrick 101509467b48Spatrick // Matches remainder expression Op % C where C is a constant. Returns the 101609467b48Spatrick // constant value in C and the other operand in Op. Returns the signedness of 101709467b48Spatrick // the remainder operation in IsSigned. Returns true if such a match is 101809467b48Spatrick // found. 101909467b48Spatrick static bool MatchRem(Value *E, Value *&Op, APInt &C, bool &IsSigned) { 102009467b48Spatrick const APInt *AI; 102109467b48Spatrick IsSigned = false; 102209467b48Spatrick if (match(E, m_SRem(m_Value(Op), m_APInt(AI)))) { 102309467b48Spatrick IsSigned = true; 102409467b48Spatrick C = *AI; 102509467b48Spatrick return true; 102609467b48Spatrick } 102709467b48Spatrick if (match(E, m_URem(m_Value(Op), m_APInt(AI)))) { 102809467b48Spatrick C = *AI; 102909467b48Spatrick return true; 103009467b48Spatrick } 103109467b48Spatrick if (match(E, m_And(m_Value(Op), m_APInt(AI))) && (*AI + 1).isPowerOf2()) { 103209467b48Spatrick C = *AI + 1; 103309467b48Spatrick return true; 103409467b48Spatrick } 103509467b48Spatrick return false; 103609467b48Spatrick } 103709467b48Spatrick 103809467b48Spatrick // Matches division expression Op / C with the given signedness as indicated 103909467b48Spatrick // by IsSigned, where C is a constant. Returns the constant value in C and the 104009467b48Spatrick // other operand in Op. Returns true if such a match is found. 104109467b48Spatrick static bool MatchDiv(Value *E, Value *&Op, APInt &C, bool IsSigned) { 104209467b48Spatrick const APInt *AI; 104309467b48Spatrick if (IsSigned && match(E, m_SDiv(m_Value(Op), m_APInt(AI)))) { 104409467b48Spatrick C = *AI; 104509467b48Spatrick return true; 104609467b48Spatrick } 104709467b48Spatrick if (!IsSigned) { 104809467b48Spatrick if (match(E, m_UDiv(m_Value(Op), m_APInt(AI)))) { 104909467b48Spatrick C = *AI; 105009467b48Spatrick return true; 105109467b48Spatrick } 105209467b48Spatrick if (match(E, m_LShr(m_Value(Op), m_APInt(AI)))) { 105309467b48Spatrick C = APInt(AI->getBitWidth(), 1); 105409467b48Spatrick C <<= *AI; 105509467b48Spatrick return true; 105609467b48Spatrick } 105709467b48Spatrick } 105809467b48Spatrick return false; 105909467b48Spatrick } 106009467b48Spatrick 106109467b48Spatrick // Returns whether C0 * C1 with the given signedness overflows. 106209467b48Spatrick static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned) { 106309467b48Spatrick bool overflow; 106409467b48Spatrick if (IsSigned) 106509467b48Spatrick (void)C0.smul_ov(C1, overflow); 106609467b48Spatrick else 106709467b48Spatrick (void)C0.umul_ov(C1, overflow); 106809467b48Spatrick return overflow; 106909467b48Spatrick } 107009467b48Spatrick 107109467b48Spatrick // Simplifies X % C0 + (( X / C0 ) % C1) * C0 to X % (C0 * C1), where (C0 * C1) 107209467b48Spatrick // does not overflow. 1073*73471bf0Spatrick Value *InstCombinerImpl::SimplifyAddWithRemainder(BinaryOperator &I) { 107409467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 107509467b48Spatrick Value *X, *MulOpV; 107609467b48Spatrick APInt C0, MulOpC; 107709467b48Spatrick bool IsSigned; 107809467b48Spatrick // Match I = X % C0 + MulOpV * C0 107909467b48Spatrick if (((MatchRem(LHS, X, C0, IsSigned) && MatchMul(RHS, MulOpV, MulOpC)) || 108009467b48Spatrick (MatchRem(RHS, X, C0, IsSigned) && MatchMul(LHS, MulOpV, MulOpC))) && 108109467b48Spatrick C0 == MulOpC) { 108209467b48Spatrick Value *RemOpV; 108309467b48Spatrick APInt C1; 108409467b48Spatrick bool Rem2IsSigned; 108509467b48Spatrick // Match MulOpC = RemOpV % C1 108609467b48Spatrick if (MatchRem(MulOpV, RemOpV, C1, Rem2IsSigned) && 108709467b48Spatrick IsSigned == Rem2IsSigned) { 108809467b48Spatrick Value *DivOpV; 108909467b48Spatrick APInt DivOpC; 109009467b48Spatrick // Match RemOpV = X / C0 109109467b48Spatrick if (MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) && X == DivOpV && 109209467b48Spatrick C0 == DivOpC && !MulWillOverflow(C0, C1, IsSigned)) { 1093097a140dSpatrick Value *NewDivisor = ConstantInt::get(X->getType(), C0 * C1); 109409467b48Spatrick return IsSigned ? Builder.CreateSRem(X, NewDivisor, "srem") 109509467b48Spatrick : Builder.CreateURem(X, NewDivisor, "urem"); 109609467b48Spatrick } 109709467b48Spatrick } 109809467b48Spatrick } 109909467b48Spatrick 110009467b48Spatrick return nullptr; 110109467b48Spatrick } 110209467b48Spatrick 110309467b48Spatrick /// Fold 110409467b48Spatrick /// (1 << NBits) - 1 110509467b48Spatrick /// Into: 110609467b48Spatrick /// ~(-(1 << NBits)) 110709467b48Spatrick /// Because a 'not' is better for bit-tracking analysis and other transforms 110809467b48Spatrick /// than an 'add'. The new shl is always nsw, and is nuw if old `and` was. 110909467b48Spatrick static Instruction *canonicalizeLowbitMask(BinaryOperator &I, 111009467b48Spatrick InstCombiner::BuilderTy &Builder) { 111109467b48Spatrick Value *NBits; 111209467b48Spatrick if (!match(&I, m_Add(m_OneUse(m_Shl(m_One(), m_Value(NBits))), m_AllOnes()))) 111309467b48Spatrick return nullptr; 111409467b48Spatrick 111509467b48Spatrick Constant *MinusOne = Constant::getAllOnesValue(NBits->getType()); 111609467b48Spatrick Value *NotMask = Builder.CreateShl(MinusOne, NBits, "notmask"); 111709467b48Spatrick // Be wary of constant folding. 111809467b48Spatrick if (auto *BOp = dyn_cast<BinaryOperator>(NotMask)) { 111909467b48Spatrick // Always NSW. But NUW propagates from `add`. 112009467b48Spatrick BOp->setHasNoSignedWrap(); 112109467b48Spatrick BOp->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); 112209467b48Spatrick } 112309467b48Spatrick 112409467b48Spatrick return BinaryOperator::CreateNot(NotMask, I.getName()); 112509467b48Spatrick } 112609467b48Spatrick 112709467b48Spatrick static Instruction *foldToUnsignedSaturatedAdd(BinaryOperator &I) { 112809467b48Spatrick assert(I.getOpcode() == Instruction::Add && "Expecting add instruction"); 112909467b48Spatrick Type *Ty = I.getType(); 113009467b48Spatrick auto getUAddSat = [&]() { 113109467b48Spatrick return Intrinsic::getDeclaration(I.getModule(), Intrinsic::uadd_sat, Ty); 113209467b48Spatrick }; 113309467b48Spatrick 113409467b48Spatrick // add (umin X, ~Y), Y --> uaddsat X, Y 113509467b48Spatrick Value *X, *Y; 113609467b48Spatrick if (match(&I, m_c_Add(m_c_UMin(m_Value(X), m_Not(m_Value(Y))), 113709467b48Spatrick m_Deferred(Y)))) 113809467b48Spatrick return CallInst::Create(getUAddSat(), { X, Y }); 113909467b48Spatrick 114009467b48Spatrick // add (umin X, ~C), C --> uaddsat X, C 114109467b48Spatrick const APInt *C, *NotC; 114209467b48Spatrick if (match(&I, m_Add(m_UMin(m_Value(X), m_APInt(NotC)), m_APInt(C))) && 114309467b48Spatrick *C == ~*NotC) 114409467b48Spatrick return CallInst::Create(getUAddSat(), { X, ConstantInt::get(Ty, *C) }); 114509467b48Spatrick 114609467b48Spatrick return nullptr; 114709467b48Spatrick } 114809467b48Spatrick 1149*73471bf0Spatrick Instruction *InstCombinerImpl:: 1150*73471bf0Spatrick canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract( 115109467b48Spatrick BinaryOperator &I) { 115209467b48Spatrick assert((I.getOpcode() == Instruction::Add || 115309467b48Spatrick I.getOpcode() == Instruction::Or || 115409467b48Spatrick I.getOpcode() == Instruction::Sub) && 115509467b48Spatrick "Expecting add/or/sub instruction"); 115609467b48Spatrick 115709467b48Spatrick // We have a subtraction/addition between a (potentially truncated) *logical* 115809467b48Spatrick // right-shift of X and a "select". 115909467b48Spatrick Value *X, *Select; 116009467b48Spatrick Instruction *LowBitsToSkip, *Extract; 116109467b48Spatrick if (!match(&I, m_c_BinOp(m_TruncOrSelf(m_CombineAnd( 116209467b48Spatrick m_LShr(m_Value(X), m_Instruction(LowBitsToSkip)), 116309467b48Spatrick m_Instruction(Extract))), 116409467b48Spatrick m_Value(Select)))) 116509467b48Spatrick return nullptr; 116609467b48Spatrick 116709467b48Spatrick // `add`/`or` is commutative; but for `sub`, "select" *must* be on RHS. 116809467b48Spatrick if (I.getOpcode() == Instruction::Sub && I.getOperand(1) != Select) 116909467b48Spatrick return nullptr; 117009467b48Spatrick 117109467b48Spatrick Type *XTy = X->getType(); 117209467b48Spatrick bool HadTrunc = I.getType() != XTy; 117309467b48Spatrick 117409467b48Spatrick // If there was a truncation of extracted value, then we'll need to produce 117509467b48Spatrick // one extra instruction, so we need to ensure one instruction will go away. 117609467b48Spatrick if (HadTrunc && !match(&I, m_c_BinOp(m_OneUse(m_Value()), m_Value()))) 117709467b48Spatrick return nullptr; 117809467b48Spatrick 117909467b48Spatrick // Extraction should extract high NBits bits, with shift amount calculated as: 118009467b48Spatrick // low bits to skip = shift bitwidth - high bits to extract 118109467b48Spatrick // The shift amount itself may be extended, and we need to look past zero-ext 118209467b48Spatrick // when matching NBits, that will matter for matching later. 118309467b48Spatrick Constant *C; 118409467b48Spatrick Value *NBits; 118509467b48Spatrick if (!match( 118609467b48Spatrick LowBitsToSkip, 118709467b48Spatrick m_ZExtOrSelf(m_Sub(m_Constant(C), m_ZExtOrSelf(m_Value(NBits))))) || 118809467b48Spatrick !match(C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, 118909467b48Spatrick APInt(C->getType()->getScalarSizeInBits(), 119009467b48Spatrick X->getType()->getScalarSizeInBits())))) 119109467b48Spatrick return nullptr; 119209467b48Spatrick 119309467b48Spatrick // Sign-extending value can be zero-extended if we `sub`tract it, 119409467b48Spatrick // or sign-extended otherwise. 119509467b48Spatrick auto SkipExtInMagic = [&I](Value *&V) { 119609467b48Spatrick if (I.getOpcode() == Instruction::Sub) 119709467b48Spatrick match(V, m_ZExtOrSelf(m_Value(V))); 119809467b48Spatrick else 119909467b48Spatrick match(V, m_SExtOrSelf(m_Value(V))); 120009467b48Spatrick }; 120109467b48Spatrick 120209467b48Spatrick // Now, finally validate the sign-extending magic. 120309467b48Spatrick // `select` itself may be appropriately extended, look past that. 120409467b48Spatrick SkipExtInMagic(Select); 120509467b48Spatrick 120609467b48Spatrick ICmpInst::Predicate Pred; 120709467b48Spatrick const APInt *Thr; 120809467b48Spatrick Value *SignExtendingValue, *Zero; 120909467b48Spatrick bool ShouldSignext; 121009467b48Spatrick // It must be a select between two values we will later establish to be a 121109467b48Spatrick // sign-extending value and a zero constant. The condition guarding the 121209467b48Spatrick // sign-extension must be based on a sign bit of the same X we had in `lshr`. 121309467b48Spatrick if (!match(Select, m_Select(m_ICmp(Pred, m_Specific(X), m_APInt(Thr)), 121409467b48Spatrick m_Value(SignExtendingValue), m_Value(Zero))) || 121509467b48Spatrick !isSignBitCheck(Pred, *Thr, ShouldSignext)) 121609467b48Spatrick return nullptr; 121709467b48Spatrick 121809467b48Spatrick // icmp-select pair is commutative. 121909467b48Spatrick if (!ShouldSignext) 122009467b48Spatrick std::swap(SignExtendingValue, Zero); 122109467b48Spatrick 122209467b48Spatrick // If we should not perform sign-extension then we must add/or/subtract zero. 122309467b48Spatrick if (!match(Zero, m_Zero())) 122409467b48Spatrick return nullptr; 122509467b48Spatrick // Otherwise, it should be some constant, left-shifted by the same NBits we 122609467b48Spatrick // had in `lshr`. Said left-shift can also be appropriately extended. 122709467b48Spatrick // Again, we must look past zero-ext when looking for NBits. 122809467b48Spatrick SkipExtInMagic(SignExtendingValue); 122909467b48Spatrick Constant *SignExtendingValueBaseConstant; 123009467b48Spatrick if (!match(SignExtendingValue, 123109467b48Spatrick m_Shl(m_Constant(SignExtendingValueBaseConstant), 123209467b48Spatrick m_ZExtOrSelf(m_Specific(NBits))))) 123309467b48Spatrick return nullptr; 123409467b48Spatrick // If we `sub`, then the constant should be one, else it should be all-ones. 123509467b48Spatrick if (I.getOpcode() == Instruction::Sub 123609467b48Spatrick ? !match(SignExtendingValueBaseConstant, m_One()) 123709467b48Spatrick : !match(SignExtendingValueBaseConstant, m_AllOnes())) 123809467b48Spatrick return nullptr; 123909467b48Spatrick 124009467b48Spatrick auto *NewAShr = BinaryOperator::CreateAShr(X, LowBitsToSkip, 124109467b48Spatrick Extract->getName() + ".sext"); 124209467b48Spatrick NewAShr->copyIRFlags(Extract); // Preserve `exact`-ness. 124309467b48Spatrick if (!HadTrunc) 124409467b48Spatrick return NewAShr; 124509467b48Spatrick 124609467b48Spatrick Builder.Insert(NewAShr); 124709467b48Spatrick return TruncInst::CreateTruncOrBitCast(NewAShr, I.getType()); 124809467b48Spatrick } 124909467b48Spatrick 1250*73471bf0Spatrick /// This is a specialization of a more general transform from 1251*73471bf0Spatrick /// SimplifyUsingDistributiveLaws. If that code can be made to work optimally 1252*73471bf0Spatrick /// for multi-use cases or propagating nsw/nuw, then we would not need this. 1253*73471bf0Spatrick static Instruction *factorizeMathWithShlOps(BinaryOperator &I, 1254*73471bf0Spatrick InstCombiner::BuilderTy &Builder) { 1255*73471bf0Spatrick // TODO: Also handle mul by doubling the shift amount? 1256*73471bf0Spatrick assert((I.getOpcode() == Instruction::Add || 1257*73471bf0Spatrick I.getOpcode() == Instruction::Sub) && 1258*73471bf0Spatrick "Expected add/sub"); 1259*73471bf0Spatrick auto *Op0 = dyn_cast<BinaryOperator>(I.getOperand(0)); 1260*73471bf0Spatrick auto *Op1 = dyn_cast<BinaryOperator>(I.getOperand(1)); 1261*73471bf0Spatrick if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse())) 1262*73471bf0Spatrick return nullptr; 1263*73471bf0Spatrick 1264*73471bf0Spatrick Value *X, *Y, *ShAmt; 1265*73471bf0Spatrick if (!match(Op0, m_Shl(m_Value(X), m_Value(ShAmt))) || 1266*73471bf0Spatrick !match(Op1, m_Shl(m_Value(Y), m_Specific(ShAmt)))) 1267*73471bf0Spatrick return nullptr; 1268*73471bf0Spatrick 1269*73471bf0Spatrick // No-wrap propagates only when all ops have no-wrap. 1270*73471bf0Spatrick bool HasNSW = I.hasNoSignedWrap() && Op0->hasNoSignedWrap() && 1271*73471bf0Spatrick Op1->hasNoSignedWrap(); 1272*73471bf0Spatrick bool HasNUW = I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() && 1273*73471bf0Spatrick Op1->hasNoUnsignedWrap(); 1274*73471bf0Spatrick 1275*73471bf0Spatrick // add/sub (X << ShAmt), (Y << ShAmt) --> (add/sub X, Y) << ShAmt 1276*73471bf0Spatrick Value *NewMath = Builder.CreateBinOp(I.getOpcode(), X, Y); 1277*73471bf0Spatrick if (auto *NewI = dyn_cast<BinaryOperator>(NewMath)) { 1278*73471bf0Spatrick NewI->setHasNoSignedWrap(HasNSW); 1279*73471bf0Spatrick NewI->setHasNoUnsignedWrap(HasNUW); 1280*73471bf0Spatrick } 1281*73471bf0Spatrick auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt); 1282*73471bf0Spatrick NewShl->setHasNoSignedWrap(HasNSW); 1283*73471bf0Spatrick NewShl->setHasNoUnsignedWrap(HasNUW); 1284*73471bf0Spatrick return NewShl; 1285*73471bf0Spatrick } 1286*73471bf0Spatrick 1287*73471bf0Spatrick Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) { 128809467b48Spatrick if (Value *V = SimplifyAddInst(I.getOperand(0), I.getOperand(1), 128909467b48Spatrick I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), 129009467b48Spatrick SQ.getWithInstruction(&I))) 129109467b48Spatrick return replaceInstUsesWith(I, V); 129209467b48Spatrick 129309467b48Spatrick if (SimplifyAssociativeOrCommutative(I)) 129409467b48Spatrick return &I; 129509467b48Spatrick 129609467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 129709467b48Spatrick return X; 129809467b48Spatrick 129909467b48Spatrick // (A*B)+(A*C) -> A*(B+C) etc 130009467b48Spatrick if (Value *V = SimplifyUsingDistributiveLaws(I)) 130109467b48Spatrick return replaceInstUsesWith(I, V); 130209467b48Spatrick 1303*73471bf0Spatrick if (Instruction *R = factorizeMathWithShlOps(I, Builder)) 1304*73471bf0Spatrick return R; 1305*73471bf0Spatrick 130609467b48Spatrick if (Instruction *X = foldAddWithConstant(I)) 130709467b48Spatrick return X; 130809467b48Spatrick 130909467b48Spatrick if (Instruction *X = foldNoWrapAdd(I, Builder)) 131009467b48Spatrick return X; 131109467b48Spatrick 131209467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 131309467b48Spatrick Type *Ty = I.getType(); 131409467b48Spatrick if (Ty->isIntOrIntVectorTy(1)) 131509467b48Spatrick return BinaryOperator::CreateXor(LHS, RHS); 131609467b48Spatrick 131709467b48Spatrick // X + X --> X << 1 131809467b48Spatrick if (LHS == RHS) { 131909467b48Spatrick auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1)); 132009467b48Spatrick Shl->setHasNoSignedWrap(I.hasNoSignedWrap()); 132109467b48Spatrick Shl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); 132209467b48Spatrick return Shl; 132309467b48Spatrick } 132409467b48Spatrick 132509467b48Spatrick Value *A, *B; 132609467b48Spatrick if (match(LHS, m_Neg(m_Value(A)))) { 132709467b48Spatrick // -A + -B --> -(A + B) 132809467b48Spatrick if (match(RHS, m_Neg(m_Value(B)))) 132909467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateAdd(A, B)); 133009467b48Spatrick 133109467b48Spatrick // -A + B --> B - A 133209467b48Spatrick return BinaryOperator::CreateSub(RHS, A); 133309467b48Spatrick } 133409467b48Spatrick 133509467b48Spatrick // A + -B --> A - B 133609467b48Spatrick if (match(RHS, m_Neg(m_Value(B)))) 133709467b48Spatrick return BinaryOperator::CreateSub(LHS, B); 133809467b48Spatrick 133909467b48Spatrick if (Value *V = checkForNegativeOperand(I, Builder)) 134009467b48Spatrick return replaceInstUsesWith(I, V); 134109467b48Spatrick 134209467b48Spatrick // (A + 1) + ~B --> A - B 134309467b48Spatrick // ~B + (A + 1) --> A - B 134409467b48Spatrick // (~B + A) + 1 --> A - B 134509467b48Spatrick // (A + ~B) + 1 --> A - B 134609467b48Spatrick if (match(&I, m_c_BinOp(m_Add(m_Value(A), m_One()), m_Not(m_Value(B)))) || 134709467b48Spatrick match(&I, m_BinOp(m_c_Add(m_Not(m_Value(B)), m_Value(A)), m_One()))) 134809467b48Spatrick return BinaryOperator::CreateSub(A, B); 134909467b48Spatrick 1350097a140dSpatrick // (A + RHS) + RHS --> A + (RHS << 1) 1351097a140dSpatrick if (match(LHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(RHS))))) 1352097a140dSpatrick return BinaryOperator::CreateAdd(A, Builder.CreateShl(RHS, 1, "reass.add")); 1353097a140dSpatrick 1354097a140dSpatrick // LHS + (A + LHS) --> A + (LHS << 1) 1355097a140dSpatrick if (match(RHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(LHS))))) 1356097a140dSpatrick return BinaryOperator::CreateAdd(A, Builder.CreateShl(LHS, 1, "reass.add")); 1357097a140dSpatrick 135809467b48Spatrick // X % C0 + (( X / C0 ) % C1) * C0 => X % (C0 * C1) 135909467b48Spatrick if (Value *V = SimplifyAddWithRemainder(I)) return replaceInstUsesWith(I, V); 136009467b48Spatrick 1361097a140dSpatrick // ((X s/ C1) << C2) + X => X s% -C1 where -C1 is 1 << C2 1362097a140dSpatrick const APInt *C1, *C2; 1363097a140dSpatrick if (match(LHS, m_Shl(m_SDiv(m_Specific(RHS), m_APInt(C1)), m_APInt(C2)))) { 1364097a140dSpatrick APInt one(C2->getBitWidth(), 1); 1365097a140dSpatrick APInt minusC1 = -(*C1); 1366097a140dSpatrick if (minusC1 == (one << *C2)) { 1367097a140dSpatrick Constant *NewRHS = ConstantInt::get(RHS->getType(), minusC1); 1368097a140dSpatrick return BinaryOperator::CreateSRem(RHS, NewRHS); 1369097a140dSpatrick } 1370097a140dSpatrick } 1371097a140dSpatrick 137209467b48Spatrick // A+B --> A|B iff A and B have no bits set in common. 137309467b48Spatrick if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT)) 137409467b48Spatrick return BinaryOperator::CreateOr(LHS, RHS); 137509467b48Spatrick 137609467b48Spatrick // add (select X 0 (sub n A)) A --> select X A n 137709467b48Spatrick { 137809467b48Spatrick SelectInst *SI = dyn_cast<SelectInst>(LHS); 137909467b48Spatrick Value *A = RHS; 138009467b48Spatrick if (!SI) { 138109467b48Spatrick SI = dyn_cast<SelectInst>(RHS); 138209467b48Spatrick A = LHS; 138309467b48Spatrick } 138409467b48Spatrick if (SI && SI->hasOneUse()) { 138509467b48Spatrick Value *TV = SI->getTrueValue(); 138609467b48Spatrick Value *FV = SI->getFalseValue(); 138709467b48Spatrick Value *N; 138809467b48Spatrick 138909467b48Spatrick // Can we fold the add into the argument of the select? 139009467b48Spatrick // We check both true and false select arguments for a matching subtract. 139109467b48Spatrick if (match(FV, m_Zero()) && match(TV, m_Sub(m_Value(N), m_Specific(A)))) 139209467b48Spatrick // Fold the add into the true select value. 139309467b48Spatrick return SelectInst::Create(SI->getCondition(), N, A); 139409467b48Spatrick 139509467b48Spatrick if (match(TV, m_Zero()) && match(FV, m_Sub(m_Value(N), m_Specific(A)))) 139609467b48Spatrick // Fold the add into the false select value. 139709467b48Spatrick return SelectInst::Create(SI->getCondition(), A, N); 139809467b48Spatrick } 139909467b48Spatrick } 140009467b48Spatrick 140109467b48Spatrick if (Instruction *Ext = narrowMathIfNoOverflow(I)) 140209467b48Spatrick return Ext; 140309467b48Spatrick 140409467b48Spatrick // (add (xor A, B) (and A, B)) --> (or A, B) 140509467b48Spatrick // (add (and A, B) (xor A, B)) --> (or A, B) 140609467b48Spatrick if (match(&I, m_c_BinOp(m_Xor(m_Value(A), m_Value(B)), 140709467b48Spatrick m_c_And(m_Deferred(A), m_Deferred(B))))) 140809467b48Spatrick return BinaryOperator::CreateOr(A, B); 140909467b48Spatrick 141009467b48Spatrick // (add (or A, B) (and A, B)) --> (add A, B) 141109467b48Spatrick // (add (and A, B) (or A, B)) --> (add A, B) 141209467b48Spatrick if (match(&I, m_c_BinOp(m_Or(m_Value(A), m_Value(B)), 141309467b48Spatrick m_c_And(m_Deferred(A), m_Deferred(B))))) { 1414097a140dSpatrick // Replacing operands in-place to preserve nuw/nsw flags. 1415097a140dSpatrick replaceOperand(I, 0, A); 1416097a140dSpatrick replaceOperand(I, 1, B); 141709467b48Spatrick return &I; 141809467b48Spatrick } 141909467b48Spatrick 142009467b48Spatrick // TODO(jingyue): Consider willNotOverflowSignedAdd and 142109467b48Spatrick // willNotOverflowUnsignedAdd to reduce the number of invocations of 142209467b48Spatrick // computeKnownBits. 142309467b48Spatrick bool Changed = false; 142409467b48Spatrick if (!I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHS, RHS, I)) { 142509467b48Spatrick Changed = true; 142609467b48Spatrick I.setHasNoSignedWrap(true); 142709467b48Spatrick } 142809467b48Spatrick if (!I.hasNoUnsignedWrap() && willNotOverflowUnsignedAdd(LHS, RHS, I)) { 142909467b48Spatrick Changed = true; 143009467b48Spatrick I.setHasNoUnsignedWrap(true); 143109467b48Spatrick } 143209467b48Spatrick 143309467b48Spatrick if (Instruction *V = canonicalizeLowbitMask(I, Builder)) 143409467b48Spatrick return V; 143509467b48Spatrick 143609467b48Spatrick if (Instruction *V = 143709467b48Spatrick canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I)) 143809467b48Spatrick return V; 143909467b48Spatrick 144009467b48Spatrick if (Instruction *SatAdd = foldToUnsignedSaturatedAdd(I)) 144109467b48Spatrick return SatAdd; 144209467b48Spatrick 1443*73471bf0Spatrick // usub.sat(A, B) + B => umax(A, B) 1444*73471bf0Spatrick if (match(&I, m_c_BinOp( 1445*73471bf0Spatrick m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(m_Value(A), m_Value(B))), 1446*73471bf0Spatrick m_Deferred(B)))) { 1447*73471bf0Spatrick return replaceInstUsesWith(I, 1448*73471bf0Spatrick Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B})); 1449*73471bf0Spatrick } 1450*73471bf0Spatrick 1451*73471bf0Spatrick // ctpop(A) + ctpop(B) => ctpop(A | B) if A and B have no bits set in common. 1452*73471bf0Spatrick if (match(LHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(m_Value(A)))) && 1453*73471bf0Spatrick match(RHS, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(m_Value(B)))) && 1454*73471bf0Spatrick haveNoCommonBitsSet(A, B, DL, &AC, &I, &DT)) 1455*73471bf0Spatrick return replaceInstUsesWith( 1456*73471bf0Spatrick I, Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()}, 1457*73471bf0Spatrick {Builder.CreateOr(A, B)})); 1458*73471bf0Spatrick 145909467b48Spatrick return Changed ? &I : nullptr; 146009467b48Spatrick } 146109467b48Spatrick 146209467b48Spatrick /// Eliminate an op from a linear interpolation (lerp) pattern. 146309467b48Spatrick static Instruction *factorizeLerp(BinaryOperator &I, 146409467b48Spatrick InstCombiner::BuilderTy &Builder) { 146509467b48Spatrick Value *X, *Y, *Z; 146609467b48Spatrick if (!match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_Value(Y), 146709467b48Spatrick m_OneUse(m_FSub(m_FPOne(), 146809467b48Spatrick m_Value(Z))))), 146909467b48Spatrick m_OneUse(m_c_FMul(m_Value(X), m_Deferred(Z)))))) 147009467b48Spatrick return nullptr; 147109467b48Spatrick 147209467b48Spatrick // (Y * (1.0 - Z)) + (X * Z) --> Y + Z * (X - Y) [8 commuted variants] 147309467b48Spatrick Value *XY = Builder.CreateFSubFMF(X, Y, &I); 147409467b48Spatrick Value *MulZ = Builder.CreateFMulFMF(Z, XY, &I); 147509467b48Spatrick return BinaryOperator::CreateFAddFMF(Y, MulZ, &I); 147609467b48Spatrick } 147709467b48Spatrick 147809467b48Spatrick /// Factor a common operand out of fadd/fsub of fmul/fdiv. 147909467b48Spatrick static Instruction *factorizeFAddFSub(BinaryOperator &I, 148009467b48Spatrick InstCombiner::BuilderTy &Builder) { 148109467b48Spatrick assert((I.getOpcode() == Instruction::FAdd || 148209467b48Spatrick I.getOpcode() == Instruction::FSub) && "Expecting fadd/fsub"); 148309467b48Spatrick assert(I.hasAllowReassoc() && I.hasNoSignedZeros() && 148409467b48Spatrick "FP factorization requires FMF"); 148509467b48Spatrick 148609467b48Spatrick if (Instruction *Lerp = factorizeLerp(I, Builder)) 148709467b48Spatrick return Lerp; 148809467b48Spatrick 148909467b48Spatrick Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 149009467b48Spatrick Value *X, *Y, *Z; 149109467b48Spatrick bool IsFMul; 149209467b48Spatrick if ((match(Op0, m_OneUse(m_FMul(m_Value(X), m_Value(Z)))) && 149309467b48Spatrick match(Op1, m_OneUse(m_c_FMul(m_Value(Y), m_Specific(Z))))) || 149409467b48Spatrick (match(Op0, m_OneUse(m_FMul(m_Value(Z), m_Value(X)))) && 149509467b48Spatrick match(Op1, m_OneUse(m_c_FMul(m_Value(Y), m_Specific(Z)))))) 149609467b48Spatrick IsFMul = true; 149709467b48Spatrick else if (match(Op0, m_OneUse(m_FDiv(m_Value(X), m_Value(Z)))) && 149809467b48Spatrick match(Op1, m_OneUse(m_FDiv(m_Value(Y), m_Specific(Z))))) 149909467b48Spatrick IsFMul = false; 150009467b48Spatrick else 150109467b48Spatrick return nullptr; 150209467b48Spatrick 150309467b48Spatrick // (X * Z) + (Y * Z) --> (X + Y) * Z 150409467b48Spatrick // (X * Z) - (Y * Z) --> (X - Y) * Z 150509467b48Spatrick // (X / Z) + (Y / Z) --> (X + Y) / Z 150609467b48Spatrick // (X / Z) - (Y / Z) --> (X - Y) / Z 150709467b48Spatrick bool IsFAdd = I.getOpcode() == Instruction::FAdd; 150809467b48Spatrick Value *XY = IsFAdd ? Builder.CreateFAddFMF(X, Y, &I) 150909467b48Spatrick : Builder.CreateFSubFMF(X, Y, &I); 151009467b48Spatrick 151109467b48Spatrick // Bail out if we just created a denormal constant. 151209467b48Spatrick // TODO: This is copied from a previous implementation. Is it necessary? 151309467b48Spatrick const APFloat *C; 151409467b48Spatrick if (match(XY, m_APFloat(C)) && !C->isNormal()) 151509467b48Spatrick return nullptr; 151609467b48Spatrick 151709467b48Spatrick return IsFMul ? BinaryOperator::CreateFMulFMF(XY, Z, &I) 151809467b48Spatrick : BinaryOperator::CreateFDivFMF(XY, Z, &I); 151909467b48Spatrick } 152009467b48Spatrick 1521*73471bf0Spatrick Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) { 152209467b48Spatrick if (Value *V = SimplifyFAddInst(I.getOperand(0), I.getOperand(1), 152309467b48Spatrick I.getFastMathFlags(), 152409467b48Spatrick SQ.getWithInstruction(&I))) 152509467b48Spatrick return replaceInstUsesWith(I, V); 152609467b48Spatrick 152709467b48Spatrick if (SimplifyAssociativeOrCommutative(I)) 152809467b48Spatrick return &I; 152909467b48Spatrick 153009467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 153109467b48Spatrick return X; 153209467b48Spatrick 153309467b48Spatrick if (Instruction *FoldedFAdd = foldBinOpIntoSelectOrPhi(I)) 153409467b48Spatrick return FoldedFAdd; 153509467b48Spatrick 153609467b48Spatrick // (-X) + Y --> Y - X 153709467b48Spatrick Value *X, *Y; 153809467b48Spatrick if (match(&I, m_c_FAdd(m_FNeg(m_Value(X)), m_Value(Y)))) 153909467b48Spatrick return BinaryOperator::CreateFSubFMF(Y, X, &I); 154009467b48Spatrick 154109467b48Spatrick // Similar to above, but look through fmul/fdiv for the negated term. 154209467b48Spatrick // (-X * Y) + Z --> Z - (X * Y) [4 commuted variants] 154309467b48Spatrick Value *Z; 154409467b48Spatrick if (match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))), 154509467b48Spatrick m_Value(Z)))) { 154609467b48Spatrick Value *XY = Builder.CreateFMulFMF(X, Y, &I); 154709467b48Spatrick return BinaryOperator::CreateFSubFMF(Z, XY, &I); 154809467b48Spatrick } 154909467b48Spatrick // (-X / Y) + Z --> Z - (X / Y) [2 commuted variants] 155009467b48Spatrick // (X / -Y) + Z --> Z - (X / Y) [2 commuted variants] 155109467b48Spatrick if (match(&I, m_c_FAdd(m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y))), 155209467b48Spatrick m_Value(Z))) || 155309467b48Spatrick match(&I, m_c_FAdd(m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))), 155409467b48Spatrick m_Value(Z)))) { 155509467b48Spatrick Value *XY = Builder.CreateFDivFMF(X, Y, &I); 155609467b48Spatrick return BinaryOperator::CreateFSubFMF(Z, XY, &I); 155709467b48Spatrick } 155809467b48Spatrick 155909467b48Spatrick // Check for (fadd double (sitofp x), y), see if we can merge this into an 156009467b48Spatrick // integer add followed by a promotion. 156109467b48Spatrick Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); 156209467b48Spatrick if (SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) { 156309467b48Spatrick Value *LHSIntVal = LHSConv->getOperand(0); 156409467b48Spatrick Type *FPType = LHSConv->getType(); 156509467b48Spatrick 156609467b48Spatrick // TODO: This check is overly conservative. In many cases known bits 156709467b48Spatrick // analysis can tell us that the result of the addition has less significant 156809467b48Spatrick // bits than the integer type can hold. 156909467b48Spatrick auto IsValidPromotion = [](Type *FTy, Type *ITy) { 157009467b48Spatrick Type *FScalarTy = FTy->getScalarType(); 157109467b48Spatrick Type *IScalarTy = ITy->getScalarType(); 157209467b48Spatrick 157309467b48Spatrick // Do we have enough bits in the significand to represent the result of 157409467b48Spatrick // the integer addition? 157509467b48Spatrick unsigned MaxRepresentableBits = 157609467b48Spatrick APFloat::semanticsPrecision(FScalarTy->getFltSemantics()); 157709467b48Spatrick return IScalarTy->getIntegerBitWidth() <= MaxRepresentableBits; 157809467b48Spatrick }; 157909467b48Spatrick 158009467b48Spatrick // (fadd double (sitofp x), fpcst) --> (sitofp (add int x, intcst)) 158109467b48Spatrick // ... if the constant fits in the integer value. This is useful for things 158209467b48Spatrick // like (double)(x & 1234) + 4.0 -> (double)((X & 1234)+4) which no longer 158309467b48Spatrick // requires a constant pool load, and generally allows the add to be better 158409467b48Spatrick // instcombined. 158509467b48Spatrick if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHS)) 158609467b48Spatrick if (IsValidPromotion(FPType, LHSIntVal->getType())) { 158709467b48Spatrick Constant *CI = 158809467b48Spatrick ConstantExpr::getFPToSI(CFP, LHSIntVal->getType()); 158909467b48Spatrick if (LHSConv->hasOneUse() && 159009467b48Spatrick ConstantExpr::getSIToFP(CI, I.getType()) == CFP && 159109467b48Spatrick willNotOverflowSignedAdd(LHSIntVal, CI, I)) { 159209467b48Spatrick // Insert the new integer add. 159309467b48Spatrick Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, CI, "addconv"); 159409467b48Spatrick return new SIToFPInst(NewAdd, I.getType()); 159509467b48Spatrick } 159609467b48Spatrick } 159709467b48Spatrick 159809467b48Spatrick // (fadd double (sitofp x), (sitofp y)) --> (sitofp (add int x, y)) 159909467b48Spatrick if (SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) { 160009467b48Spatrick Value *RHSIntVal = RHSConv->getOperand(0); 160109467b48Spatrick // It's enough to check LHS types only because we require int types to 160209467b48Spatrick // be the same for this transform. 160309467b48Spatrick if (IsValidPromotion(FPType, LHSIntVal->getType())) { 160409467b48Spatrick // Only do this if x/y have the same type, if at least one of them has a 160509467b48Spatrick // single use (so we don't increase the number of int->fp conversions), 160609467b48Spatrick // and if the integer add will not overflow. 160709467b48Spatrick if (LHSIntVal->getType() == RHSIntVal->getType() && 160809467b48Spatrick (LHSConv->hasOneUse() || RHSConv->hasOneUse()) && 160909467b48Spatrick willNotOverflowSignedAdd(LHSIntVal, RHSIntVal, I)) { 161009467b48Spatrick // Insert the new integer add. 161109467b48Spatrick Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, RHSIntVal, "addconv"); 161209467b48Spatrick return new SIToFPInst(NewAdd, I.getType()); 161309467b48Spatrick } 161409467b48Spatrick } 161509467b48Spatrick } 161609467b48Spatrick } 161709467b48Spatrick 161809467b48Spatrick // Handle specials cases for FAdd with selects feeding the operation 161909467b48Spatrick if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS)) 162009467b48Spatrick return replaceInstUsesWith(I, V); 162109467b48Spatrick 162209467b48Spatrick if (I.hasAllowReassoc() && I.hasNoSignedZeros()) { 162309467b48Spatrick if (Instruction *F = factorizeFAddFSub(I, Builder)) 162409467b48Spatrick return F; 1625*73471bf0Spatrick 1626*73471bf0Spatrick // Try to fold fadd into start value of reduction intrinsic. 1627*73471bf0Spatrick if (match(&I, m_c_FAdd(m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>( 1628*73471bf0Spatrick m_AnyZeroFP(), m_Value(X))), 1629*73471bf0Spatrick m_Value(Y)))) { 1630*73471bf0Spatrick // fadd (rdx 0.0, X), Y --> rdx Y, X 1631*73471bf0Spatrick return replaceInstUsesWith( 1632*73471bf0Spatrick I, Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd, 1633*73471bf0Spatrick {X->getType()}, {Y, X}, &I)); 1634*73471bf0Spatrick } 1635*73471bf0Spatrick const APFloat *StartC, *C; 1636*73471bf0Spatrick if (match(LHS, m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>( 1637*73471bf0Spatrick m_APFloat(StartC), m_Value(X)))) && 1638*73471bf0Spatrick match(RHS, m_APFloat(C))) { 1639*73471bf0Spatrick // fadd (rdx StartC, X), C --> rdx (C + StartC), X 1640*73471bf0Spatrick Constant *NewStartC = ConstantFP::get(I.getType(), *C + *StartC); 1641*73471bf0Spatrick return replaceInstUsesWith( 1642*73471bf0Spatrick I, Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd, 1643*73471bf0Spatrick {X->getType()}, {NewStartC, X}, &I)); 1644*73471bf0Spatrick } 1645*73471bf0Spatrick 164609467b48Spatrick if (Value *V = FAddCombine(Builder).simplify(&I)) 164709467b48Spatrick return replaceInstUsesWith(I, V); 164809467b48Spatrick } 164909467b48Spatrick 165009467b48Spatrick return nullptr; 165109467b48Spatrick } 165209467b48Spatrick 165309467b48Spatrick /// Optimize pointer differences into the same array into a size. Consider: 165409467b48Spatrick /// &A[10] - &A[0]: we should compile this to "10". LHS/RHS are the pointer 165509467b48Spatrick /// operands to the ptrtoint instructions for the LHS/RHS of the subtract. 1656*73471bf0Spatrick Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS, 165709467b48Spatrick Type *Ty, bool IsNUW) { 165809467b48Spatrick // If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize 165909467b48Spatrick // this. 166009467b48Spatrick bool Swapped = false; 166109467b48Spatrick GEPOperator *GEP1 = nullptr, *GEP2 = nullptr; 1662*73471bf0Spatrick if (!isa<GEPOperator>(LHS) && isa<GEPOperator>(RHS)) { 1663*73471bf0Spatrick std::swap(LHS, RHS); 1664*73471bf0Spatrick Swapped = true; 1665*73471bf0Spatrick } 166609467b48Spatrick 1667*73471bf0Spatrick // Require at least one GEP with a common base pointer on both sides. 1668*73471bf0Spatrick if (auto *LHSGEP = dyn_cast<GEPOperator>(LHS)) { 166909467b48Spatrick // (gep X, ...) - X 167009467b48Spatrick if (LHSGEP->getOperand(0) == RHS) { 167109467b48Spatrick GEP1 = LHSGEP; 1672*73471bf0Spatrick } else if (auto *RHSGEP = dyn_cast<GEPOperator>(RHS)) { 167309467b48Spatrick // (gep X, ...) - (gep X, ...) 167409467b48Spatrick if (LHSGEP->getOperand(0)->stripPointerCasts() == 167509467b48Spatrick RHSGEP->getOperand(0)->stripPointerCasts()) { 167609467b48Spatrick GEP1 = LHSGEP; 1677*73471bf0Spatrick GEP2 = RHSGEP; 167809467b48Spatrick } 167909467b48Spatrick } 168009467b48Spatrick } 168109467b48Spatrick 168209467b48Spatrick if (!GEP1) 168309467b48Spatrick return nullptr; 168409467b48Spatrick 168509467b48Spatrick if (GEP2) { 168609467b48Spatrick // (gep X, ...) - (gep X, ...) 168709467b48Spatrick // 168809467b48Spatrick // Avoid duplicating the arithmetic if there are more than one non-constant 168909467b48Spatrick // indices between the two GEPs and either GEP has a non-constant index and 169009467b48Spatrick // multiple users. If zero non-constant index, the result is a constant and 169109467b48Spatrick // there is no duplication. If one non-constant index, the result is an add 169209467b48Spatrick // or sub with a constant, which is no larger than the original code, and 169309467b48Spatrick // there's no duplicated arithmetic, even if either GEP has multiple 169409467b48Spatrick // users. If more than one non-constant indices combined, as long as the GEP 169509467b48Spatrick // with at least one non-constant index doesn't have multiple users, there 169609467b48Spatrick // is no duplication. 169709467b48Spatrick unsigned NumNonConstantIndices1 = GEP1->countNonConstantIndices(); 169809467b48Spatrick unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices(); 169909467b48Spatrick if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 && 170009467b48Spatrick ((NumNonConstantIndices1 > 0 && !GEP1->hasOneUse()) || 170109467b48Spatrick (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) { 170209467b48Spatrick return nullptr; 170309467b48Spatrick } 170409467b48Spatrick } 170509467b48Spatrick 170609467b48Spatrick // Emit the offset of the GEP and an intptr_t. 170709467b48Spatrick Value *Result = EmitGEPOffset(GEP1); 170809467b48Spatrick 170909467b48Spatrick // If this is a single inbounds GEP and the original sub was nuw, 1710*73471bf0Spatrick // then the final multiplication is also nuw. 1711*73471bf0Spatrick if (auto *I = dyn_cast<Instruction>(Result)) 171209467b48Spatrick if (IsNUW && !GEP2 && !Swapped && GEP1->isInBounds() && 171309467b48Spatrick I->getOpcode() == Instruction::Mul) 171409467b48Spatrick I->setHasNoUnsignedWrap(); 171509467b48Spatrick 1716*73471bf0Spatrick // If we have a 2nd GEP of the same base pointer, subtract the offsets. 1717*73471bf0Spatrick // If both GEPs are inbounds, then the subtract does not have signed overflow. 171809467b48Spatrick if (GEP2) { 171909467b48Spatrick Value *Offset = EmitGEPOffset(GEP2); 1720*73471bf0Spatrick Result = Builder.CreateSub(Result, Offset, "gepdiff", /* NUW */ false, 1721*73471bf0Spatrick GEP1->isInBounds() && GEP2->isInBounds()); 172209467b48Spatrick } 172309467b48Spatrick 172409467b48Spatrick // If we have p - gep(p, ...) then we have to negate the result. 172509467b48Spatrick if (Swapped) 172609467b48Spatrick Result = Builder.CreateNeg(Result, "diff.neg"); 172709467b48Spatrick 172809467b48Spatrick return Builder.CreateIntCast(Result, Ty, true); 172909467b48Spatrick } 173009467b48Spatrick 1731*73471bf0Spatrick Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { 173209467b48Spatrick if (Value *V = SimplifySubInst(I.getOperand(0), I.getOperand(1), 173309467b48Spatrick I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), 173409467b48Spatrick SQ.getWithInstruction(&I))) 173509467b48Spatrick return replaceInstUsesWith(I, V); 173609467b48Spatrick 173709467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 173809467b48Spatrick return X; 173909467b48Spatrick 1740097a140dSpatrick Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 174109467b48Spatrick 174209467b48Spatrick // If this is a 'B = x-(-A)', change to B = x+A. 1743097a140dSpatrick // We deal with this without involving Negator to preserve NSW flag. 174409467b48Spatrick if (Value *V = dyn_castNegVal(Op1)) { 174509467b48Spatrick BinaryOperator *Res = BinaryOperator::CreateAdd(Op0, V); 174609467b48Spatrick 174709467b48Spatrick if (const auto *BO = dyn_cast<BinaryOperator>(Op1)) { 174809467b48Spatrick assert(BO->getOpcode() == Instruction::Sub && 174909467b48Spatrick "Expected a subtraction operator!"); 175009467b48Spatrick if (BO->hasNoSignedWrap() && I.hasNoSignedWrap()) 175109467b48Spatrick Res->setHasNoSignedWrap(true); 175209467b48Spatrick } else { 175309467b48Spatrick if (cast<Constant>(Op1)->isNotMinSignedValue() && I.hasNoSignedWrap()) 175409467b48Spatrick Res->setHasNoSignedWrap(true); 175509467b48Spatrick } 175609467b48Spatrick 175709467b48Spatrick return Res; 175809467b48Spatrick } 175909467b48Spatrick 1760*73471bf0Spatrick // Try this before Negator to preserve NSW flag. 1761*73471bf0Spatrick if (Instruction *R = factorizeMathWithShlOps(I, Builder)) 1762*73471bf0Spatrick return R; 1763*73471bf0Spatrick 1764*73471bf0Spatrick Constant *C; 1765*73471bf0Spatrick if (match(Op0, m_ImmConstant(C))) { 1766*73471bf0Spatrick Value *X; 1767*73471bf0Spatrick Constant *C2; 1768*73471bf0Spatrick 1769*73471bf0Spatrick // C-(X+C2) --> (C-C2)-X 1770*73471bf0Spatrick if (match(Op1, m_Add(m_Value(X), m_ImmConstant(C2)))) 1771*73471bf0Spatrick return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X); 1772*73471bf0Spatrick } 1773*73471bf0Spatrick 1774097a140dSpatrick auto TryToNarrowDeduceFlags = [this, &I, &Op0, &Op1]() -> Instruction * { 1775097a140dSpatrick if (Instruction *Ext = narrowMathIfNoOverflow(I)) 1776097a140dSpatrick return Ext; 1777097a140dSpatrick 1778097a140dSpatrick bool Changed = false; 1779097a140dSpatrick if (!I.hasNoSignedWrap() && willNotOverflowSignedSub(Op0, Op1, I)) { 1780097a140dSpatrick Changed = true; 1781097a140dSpatrick I.setHasNoSignedWrap(true); 1782097a140dSpatrick } 1783097a140dSpatrick if (!I.hasNoUnsignedWrap() && willNotOverflowUnsignedSub(Op0, Op1, I)) { 1784097a140dSpatrick Changed = true; 1785097a140dSpatrick I.setHasNoUnsignedWrap(true); 1786097a140dSpatrick } 1787097a140dSpatrick 1788097a140dSpatrick return Changed ? &I : nullptr; 1789097a140dSpatrick }; 1790097a140dSpatrick 1791097a140dSpatrick // First, let's try to interpret `sub a, b` as `add a, (sub 0, b)`, 1792097a140dSpatrick // and let's try to sink `(sub 0, b)` into `b` itself. But only if this isn't 1793097a140dSpatrick // a pure negation used by a select that looks like abs/nabs. 1794097a140dSpatrick bool IsNegation = match(Op0, m_ZeroInt()); 1795097a140dSpatrick if (!IsNegation || none_of(I.users(), [&I, Op1](const User *U) { 1796097a140dSpatrick const Instruction *UI = dyn_cast<Instruction>(U); 1797097a140dSpatrick if (!UI) 1798097a140dSpatrick return false; 1799097a140dSpatrick return match(UI, 1800097a140dSpatrick m_Select(m_Value(), m_Specific(Op1), m_Specific(&I))) || 1801097a140dSpatrick match(UI, m_Select(m_Value(), m_Specific(&I), m_Specific(Op1))); 1802097a140dSpatrick })) { 1803097a140dSpatrick if (Value *NegOp1 = Negator::Negate(IsNegation, Op1, *this)) 1804097a140dSpatrick return BinaryOperator::CreateAdd(NegOp1, Op0); 1805097a140dSpatrick } 1806097a140dSpatrick if (IsNegation) 1807097a140dSpatrick return TryToNarrowDeduceFlags(); // Should have been handled in Negator! 1808097a140dSpatrick 1809097a140dSpatrick // (A*B)-(A*C) -> A*(B-C) etc 1810097a140dSpatrick if (Value *V = SimplifyUsingDistributiveLaws(I)) 1811097a140dSpatrick return replaceInstUsesWith(I, V); 1812097a140dSpatrick 181309467b48Spatrick if (I.getType()->isIntOrIntVectorTy(1)) 181409467b48Spatrick return BinaryOperator::CreateXor(Op0, Op1); 181509467b48Spatrick 181609467b48Spatrick // Replace (-1 - A) with (~A). 181709467b48Spatrick if (match(Op0, m_AllOnes())) 181809467b48Spatrick return BinaryOperator::CreateNot(Op1); 181909467b48Spatrick 182009467b48Spatrick // (~X) - (~Y) --> Y - X 182109467b48Spatrick Value *X, *Y; 182209467b48Spatrick if (match(Op0, m_Not(m_Value(X))) && match(Op1, m_Not(m_Value(Y)))) 182309467b48Spatrick return BinaryOperator::CreateSub(Y, X); 182409467b48Spatrick 182509467b48Spatrick // (X + -1) - Y --> ~Y + X 182609467b48Spatrick if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes())))) 182709467b48Spatrick return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X); 182809467b48Spatrick 1829097a140dSpatrick // Reassociate sub/add sequences to create more add instructions and 1830097a140dSpatrick // reduce dependency chains: 1831097a140dSpatrick // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1) 1832097a140dSpatrick Value *Z; 1833097a140dSpatrick if (match(Op0, m_OneUse(m_c_Add(m_OneUse(m_Sub(m_Value(X), m_Value(Y))), 1834097a140dSpatrick m_Value(Z))))) { 1835097a140dSpatrick Value *XZ = Builder.CreateAdd(X, Z); 1836097a140dSpatrick Value *YW = Builder.CreateAdd(Y, Op1); 1837097a140dSpatrick return BinaryOperator::CreateSub(XZ, YW); 1838097a140dSpatrick } 183909467b48Spatrick 1840*73471bf0Spatrick // ((X - Y) - Op1) --> X - (Y + Op1) 1841*73471bf0Spatrick if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y))))) { 1842*73471bf0Spatrick Value *Add = Builder.CreateAdd(Y, Op1); 1843*73471bf0Spatrick return BinaryOperator::CreateSub(X, Add); 1844*73471bf0Spatrick } 1845*73471bf0Spatrick 1846097a140dSpatrick auto m_AddRdx = [](Value *&Vec) { 1847*73471bf0Spatrick return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_add>(m_Value(Vec))); 1848097a140dSpatrick }; 1849097a140dSpatrick Value *V0, *V1; 1850097a140dSpatrick if (match(Op0, m_AddRdx(V0)) && match(Op1, m_AddRdx(V1)) && 1851097a140dSpatrick V0->getType() == V1->getType()) { 1852097a140dSpatrick // Difference of sums is sum of differences: 1853097a140dSpatrick // add_rdx(V0) - add_rdx(V1) --> add_rdx(V0 - V1) 1854097a140dSpatrick Value *Sub = Builder.CreateSub(V0, V1); 1855*73471bf0Spatrick Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_add, 1856*73471bf0Spatrick {Sub->getType()}, {Sub}); 1857097a140dSpatrick return replaceInstUsesWith(I, Rdx); 185809467b48Spatrick } 185909467b48Spatrick 186009467b48Spatrick if (Constant *C = dyn_cast<Constant>(Op0)) { 186109467b48Spatrick Value *X; 1862097a140dSpatrick if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) 186309467b48Spatrick // C - (zext bool) --> bool ? C - 1 : C 1864*73471bf0Spatrick return SelectInst::Create(X, InstCombiner::SubOne(C), C); 1865097a140dSpatrick if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) 186609467b48Spatrick // C - (sext bool) --> bool ? C + 1 : C 1867*73471bf0Spatrick return SelectInst::Create(X, InstCombiner::AddOne(C), C); 186809467b48Spatrick 186909467b48Spatrick // C - ~X == X + (1+C) 187009467b48Spatrick if (match(Op1, m_Not(m_Value(X)))) 1871*73471bf0Spatrick return BinaryOperator::CreateAdd(X, InstCombiner::AddOne(C)); 187209467b48Spatrick 187309467b48Spatrick // Try to fold constant sub into select arguments. 187409467b48Spatrick if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) 187509467b48Spatrick if (Instruction *R = FoldOpIntoSelect(I, SI)) 187609467b48Spatrick return R; 187709467b48Spatrick 187809467b48Spatrick // Try to fold constant sub into PHI values. 187909467b48Spatrick if (PHINode *PN = dyn_cast<PHINode>(Op1)) 188009467b48Spatrick if (Instruction *R = foldOpIntoPhi(I, PN)) 188109467b48Spatrick return R; 188209467b48Spatrick 188309467b48Spatrick Constant *C2; 188409467b48Spatrick 188509467b48Spatrick // C-(C2-X) --> X+(C-C2) 1886*73471bf0Spatrick if (match(Op1, m_Sub(m_ImmConstant(C2), m_Value(X)))) 188709467b48Spatrick return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2)); 188809467b48Spatrick } 188909467b48Spatrick 189009467b48Spatrick const APInt *Op0C; 1891097a140dSpatrick if (match(Op0, m_APInt(Op0C)) && Op0C->isMask()) { 189209467b48Spatrick // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known 189309467b48Spatrick // zero. 189409467b48Spatrick KnownBits RHSKnown = computeKnownBits(Op1, 0, &I); 189509467b48Spatrick if ((*Op0C | RHSKnown.Zero).isAllOnesValue()) 189609467b48Spatrick return BinaryOperator::CreateXor(Op1, Op0); 189709467b48Spatrick } 189809467b48Spatrick 189909467b48Spatrick { 190009467b48Spatrick Value *Y; 190109467b48Spatrick // X-(X+Y) == -Y X-(Y+X) == -Y 190209467b48Spatrick if (match(Op1, m_c_Add(m_Specific(Op0), m_Value(Y)))) 190309467b48Spatrick return BinaryOperator::CreateNeg(Y); 190409467b48Spatrick 190509467b48Spatrick // (X-Y)-X == -Y 190609467b48Spatrick if (match(Op0, m_Sub(m_Specific(Op1), m_Value(Y)))) 190709467b48Spatrick return BinaryOperator::CreateNeg(Y); 190809467b48Spatrick } 190909467b48Spatrick 191009467b48Spatrick // (sub (or A, B) (and A, B)) --> (xor A, B) 191109467b48Spatrick { 191209467b48Spatrick Value *A, *B; 191309467b48Spatrick if (match(Op1, m_And(m_Value(A), m_Value(B))) && 191409467b48Spatrick match(Op0, m_c_Or(m_Specific(A), m_Specific(B)))) 191509467b48Spatrick return BinaryOperator::CreateXor(A, B); 191609467b48Spatrick } 191709467b48Spatrick 1918*73471bf0Spatrick // (sub (add A, B) (or A, B)) --> (and A, B) 1919*73471bf0Spatrick { 1920*73471bf0Spatrick Value *A, *B; 1921*73471bf0Spatrick if (match(Op0, m_Add(m_Value(A), m_Value(B))) && 1922*73471bf0Spatrick match(Op1, m_c_Or(m_Specific(A), m_Specific(B)))) 1923*73471bf0Spatrick return BinaryOperator::CreateAnd(A, B); 1924*73471bf0Spatrick } 1925*73471bf0Spatrick 1926*73471bf0Spatrick // (sub (add A, B) (and A, B)) --> (or A, B) 1927*73471bf0Spatrick { 1928*73471bf0Spatrick Value *A, *B; 1929*73471bf0Spatrick if (match(Op0, m_Add(m_Value(A), m_Value(B))) && 1930*73471bf0Spatrick match(Op1, m_c_And(m_Specific(A), m_Specific(B)))) 1931*73471bf0Spatrick return BinaryOperator::CreateOr(A, B); 1932*73471bf0Spatrick } 1933*73471bf0Spatrick 193409467b48Spatrick // (sub (and A, B) (or A, B)) --> neg (xor A, B) 193509467b48Spatrick { 193609467b48Spatrick Value *A, *B; 193709467b48Spatrick if (match(Op0, m_And(m_Value(A), m_Value(B))) && 193809467b48Spatrick match(Op1, m_c_Or(m_Specific(A), m_Specific(B))) && 193909467b48Spatrick (Op0->hasOneUse() || Op1->hasOneUse())) 194009467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateXor(A, B)); 194109467b48Spatrick } 194209467b48Spatrick 194309467b48Spatrick // (sub (or A, B), (xor A, B)) --> (and A, B) 194409467b48Spatrick { 194509467b48Spatrick Value *A, *B; 194609467b48Spatrick if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && 194709467b48Spatrick match(Op0, m_c_Or(m_Specific(A), m_Specific(B)))) 194809467b48Spatrick return BinaryOperator::CreateAnd(A, B); 194909467b48Spatrick } 195009467b48Spatrick 195109467b48Spatrick // (sub (xor A, B) (or A, B)) --> neg (and A, B) 195209467b48Spatrick { 195309467b48Spatrick Value *A, *B; 195409467b48Spatrick if (match(Op0, m_Xor(m_Value(A), m_Value(B))) && 195509467b48Spatrick match(Op1, m_c_Or(m_Specific(A), m_Specific(B))) && 195609467b48Spatrick (Op0->hasOneUse() || Op1->hasOneUse())) 195709467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateAnd(A, B)); 195809467b48Spatrick } 195909467b48Spatrick 196009467b48Spatrick { 196109467b48Spatrick Value *Y; 196209467b48Spatrick // ((X | Y) - X) --> (~X & Y) 196309467b48Spatrick if (match(Op0, m_OneUse(m_c_Or(m_Value(Y), m_Specific(Op1))))) 196409467b48Spatrick return BinaryOperator::CreateAnd( 196509467b48Spatrick Y, Builder.CreateNot(Op1, Op1->getName() + ".not")); 196609467b48Spatrick } 196709467b48Spatrick 196809467b48Spatrick { 196909467b48Spatrick // (sub (and Op1, (neg X)), Op1) --> neg (and Op1, (add X, -1)) 197009467b48Spatrick Value *X; 197109467b48Spatrick if (match(Op0, m_OneUse(m_c_And(m_Specific(Op1), 197209467b48Spatrick m_OneUse(m_Neg(m_Value(X))))))) { 197309467b48Spatrick return BinaryOperator::CreateNeg(Builder.CreateAnd( 197409467b48Spatrick Op1, Builder.CreateAdd(X, Constant::getAllOnesValue(I.getType())))); 197509467b48Spatrick } 197609467b48Spatrick } 197709467b48Spatrick 197809467b48Spatrick { 197909467b48Spatrick // (sub (and Op1, C), Op1) --> neg (and Op1, ~C) 198009467b48Spatrick Constant *C; 198109467b48Spatrick if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_Constant(C))))) { 198209467b48Spatrick return BinaryOperator::CreateNeg( 198309467b48Spatrick Builder.CreateAnd(Op1, Builder.CreateNot(C))); 198409467b48Spatrick } 198509467b48Spatrick } 198609467b48Spatrick 198709467b48Spatrick { 198809467b48Spatrick // If we have a subtraction between some value and a select between 198909467b48Spatrick // said value and something else, sink subtraction into select hands, i.e.: 199009467b48Spatrick // sub (select %Cond, %TrueVal, %FalseVal), %Op1 199109467b48Spatrick // -> 199209467b48Spatrick // select %Cond, (sub %TrueVal, %Op1), (sub %FalseVal, %Op1) 199309467b48Spatrick // or 199409467b48Spatrick // sub %Op0, (select %Cond, %TrueVal, %FalseVal) 199509467b48Spatrick // -> 199609467b48Spatrick // select %Cond, (sub %Op0, %TrueVal), (sub %Op0, %FalseVal) 199709467b48Spatrick // This will result in select between new subtraction and 0. 199809467b48Spatrick auto SinkSubIntoSelect = 199909467b48Spatrick [Ty = I.getType()](Value *Select, Value *OtherHandOfSub, 200009467b48Spatrick auto SubBuilder) -> Instruction * { 200109467b48Spatrick Value *Cond, *TrueVal, *FalseVal; 200209467b48Spatrick if (!match(Select, m_OneUse(m_Select(m_Value(Cond), m_Value(TrueVal), 200309467b48Spatrick m_Value(FalseVal))))) 200409467b48Spatrick return nullptr; 200509467b48Spatrick if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal) 200609467b48Spatrick return nullptr; 200709467b48Spatrick // While it is really tempting to just create two subtractions and let 200809467b48Spatrick // InstCombine fold one of those to 0, it isn't possible to do so 200909467b48Spatrick // because of worklist visitation order. So ugly it is. 201009467b48Spatrick bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal; 201109467b48Spatrick Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal); 201209467b48Spatrick Constant *Zero = Constant::getNullValue(Ty); 201309467b48Spatrick SelectInst *NewSel = 201409467b48Spatrick SelectInst::Create(Cond, OtherHandOfSubIsTrueVal ? Zero : NewSub, 201509467b48Spatrick OtherHandOfSubIsTrueVal ? NewSub : Zero); 201609467b48Spatrick // Preserve prof metadata if any. 201709467b48Spatrick NewSel->copyMetadata(cast<Instruction>(*Select)); 201809467b48Spatrick return NewSel; 201909467b48Spatrick }; 202009467b48Spatrick if (Instruction *NewSel = SinkSubIntoSelect( 202109467b48Spatrick /*Select=*/Op0, /*OtherHandOfSub=*/Op1, 202209467b48Spatrick [Builder = &Builder, Op1](Value *OtherHandOfSelect) { 202309467b48Spatrick return Builder->CreateSub(OtherHandOfSelect, 202409467b48Spatrick /*OtherHandOfSub=*/Op1); 202509467b48Spatrick })) 202609467b48Spatrick return NewSel; 202709467b48Spatrick if (Instruction *NewSel = SinkSubIntoSelect( 202809467b48Spatrick /*Select=*/Op1, /*OtherHandOfSub=*/Op0, 202909467b48Spatrick [Builder = &Builder, Op0](Value *OtherHandOfSelect) { 203009467b48Spatrick return Builder->CreateSub(/*OtherHandOfSub=*/Op0, 203109467b48Spatrick OtherHandOfSelect); 203209467b48Spatrick })) 203309467b48Spatrick return NewSel; 203409467b48Spatrick } 203509467b48Spatrick 203609467b48Spatrick // (X - (X & Y)) --> (X & ~Y) 2037097a140dSpatrick if (match(Op1, m_c_And(m_Specific(Op0), m_Value(Y))) && 2038097a140dSpatrick (Op1->hasOneUse() || isa<Constant>(Y))) 2039097a140dSpatrick return BinaryOperator::CreateAnd( 2040097a140dSpatrick Op0, Builder.CreateNot(Y, Y->getName() + ".not")); 204109467b48Spatrick 204209467b48Spatrick { 204309467b48Spatrick // ~A - Min/Max(~A, O) -> Max/Min(A, ~O) - A 204409467b48Spatrick // ~A - Min/Max(O, ~A) -> Max/Min(A, ~O) - A 204509467b48Spatrick // Min/Max(~A, O) - ~A -> A - Max/Min(A, ~O) 204609467b48Spatrick // Min/Max(O, ~A) - ~A -> A - Max/Min(A, ~O) 204709467b48Spatrick // So long as O here is freely invertible, this will be neutral or a win. 204809467b48Spatrick Value *LHS, *RHS, *A; 204909467b48Spatrick Value *NotA = Op0, *MinMax = Op1; 205009467b48Spatrick SelectPatternFlavor SPF = matchSelectPattern(MinMax, LHS, RHS).Flavor; 205109467b48Spatrick if (!SelectPatternResult::isMinOrMax(SPF)) { 205209467b48Spatrick NotA = Op1; 205309467b48Spatrick MinMax = Op0; 205409467b48Spatrick SPF = matchSelectPattern(MinMax, LHS, RHS).Flavor; 205509467b48Spatrick } 205609467b48Spatrick if (SelectPatternResult::isMinOrMax(SPF) && 205709467b48Spatrick match(NotA, m_Not(m_Value(A))) && (NotA == LHS || NotA == RHS)) { 205809467b48Spatrick if (NotA == LHS) 205909467b48Spatrick std::swap(LHS, RHS); 206009467b48Spatrick // LHS is now O above and expected to have at least 2 uses (the min/max) 206109467b48Spatrick // NotA is epected to have 2 uses from the min/max and 1 from the sub. 206209467b48Spatrick if (isFreeToInvert(LHS, !LHS->hasNUsesOrMore(3)) && 206309467b48Spatrick !NotA->hasNUsesOrMore(4)) { 206409467b48Spatrick // Note: We don't generate the inverse max/min, just create the not of 206509467b48Spatrick // it and let other folds do the rest. 206609467b48Spatrick Value *Not = Builder.CreateNot(MinMax); 206709467b48Spatrick if (NotA == Op0) 206809467b48Spatrick return BinaryOperator::CreateSub(Not, A); 206909467b48Spatrick else 207009467b48Spatrick return BinaryOperator::CreateSub(A, Not); 207109467b48Spatrick } 207209467b48Spatrick } 207309467b48Spatrick } 207409467b48Spatrick 207509467b48Spatrick // Optimize pointer differences into the same array into a size. Consider: 207609467b48Spatrick // &A[10] - &A[0]: we should compile this to "10". 207709467b48Spatrick Value *LHSOp, *RHSOp; 207809467b48Spatrick if (match(Op0, m_PtrToInt(m_Value(LHSOp))) && 207909467b48Spatrick match(Op1, m_PtrToInt(m_Value(RHSOp)))) 208009467b48Spatrick if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(), 208109467b48Spatrick I.hasNoUnsignedWrap())) 208209467b48Spatrick return replaceInstUsesWith(I, Res); 208309467b48Spatrick 208409467b48Spatrick // trunc(p)-trunc(q) -> trunc(p-q) 208509467b48Spatrick if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) && 208609467b48Spatrick match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp))))) 208709467b48Spatrick if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(), 208809467b48Spatrick /* IsNUW */ false)) 208909467b48Spatrick return replaceInstUsesWith(I, Res); 209009467b48Spatrick 209109467b48Spatrick // Canonicalize a shifty way to code absolute value to the common pattern. 209209467b48Spatrick // There are 2 potential commuted variants. 209309467b48Spatrick // We're relying on the fact that we only do this transform when the shift has 209409467b48Spatrick // exactly 2 uses and the xor has exactly 1 use (otherwise, we might increase 209509467b48Spatrick // instructions). 209609467b48Spatrick Value *A; 209709467b48Spatrick const APInt *ShAmt; 209809467b48Spatrick Type *Ty = I.getType(); 209909467b48Spatrick if (match(Op1, m_AShr(m_Value(A), m_APInt(ShAmt))) && 210009467b48Spatrick Op1->hasNUses(2) && *ShAmt == Ty->getScalarSizeInBits() - 1 && 210109467b48Spatrick match(Op0, m_OneUse(m_c_Xor(m_Specific(A), m_Specific(Op1))))) { 210209467b48Spatrick // B = ashr i32 A, 31 ; smear the sign bit 210309467b48Spatrick // sub (xor A, B), B ; flip bits if negative and subtract -1 (add 1) 210409467b48Spatrick // --> (A < 0) ? -A : A 210509467b48Spatrick Value *Cmp = Builder.CreateICmpSLT(A, ConstantInt::getNullValue(Ty)); 210609467b48Spatrick // Copy the nuw/nsw flags from the sub to the negate. 210709467b48Spatrick Value *Neg = Builder.CreateNeg(A, "", I.hasNoUnsignedWrap(), 210809467b48Spatrick I.hasNoSignedWrap()); 210909467b48Spatrick return SelectInst::Create(Cmp, Neg, A); 211009467b48Spatrick } 211109467b48Spatrick 2112*73471bf0Spatrick // If we are subtracting a low-bit masked subset of some value from an add 2113*73471bf0Spatrick // of that same value with no low bits changed, that is clearing some low bits 2114*73471bf0Spatrick // of the sum: 2115*73471bf0Spatrick // sub (X + AddC), (X & AndC) --> and (X + AddC), ~AndC 2116*73471bf0Spatrick const APInt *AddC, *AndC; 2117*73471bf0Spatrick if (match(Op0, m_Add(m_Value(X), m_APInt(AddC))) && 2118*73471bf0Spatrick match(Op1, m_And(m_Specific(X), m_APInt(AndC)))) { 2119*73471bf0Spatrick unsigned BitWidth = Ty->getScalarSizeInBits(); 2120*73471bf0Spatrick unsigned Cttz = AddC->countTrailingZeros(); 2121*73471bf0Spatrick APInt HighMask(APInt::getHighBitsSet(BitWidth, BitWidth - Cttz)); 2122*73471bf0Spatrick if ((HighMask & *AndC).isNullValue()) 2123*73471bf0Spatrick return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC))); 2124*73471bf0Spatrick } 2125*73471bf0Spatrick 212609467b48Spatrick if (Instruction *V = 212709467b48Spatrick canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I)) 212809467b48Spatrick return V; 212909467b48Spatrick 2130*73471bf0Spatrick // X - usub.sat(X, Y) => umin(X, Y) 2131*73471bf0Spatrick if (match(Op1, m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(m_Specific(Op0), 2132*73471bf0Spatrick m_Value(Y))))) 2133*73471bf0Spatrick return replaceInstUsesWith( 2134*73471bf0Spatrick I, Builder.CreateIntrinsic(Intrinsic::umin, {I.getType()}, {Op0, Y})); 2135*73471bf0Spatrick 2136*73471bf0Spatrick // C - ctpop(X) => ctpop(~X) if C is bitwidth 2137*73471bf0Spatrick if (match(Op0, m_SpecificInt(Ty->getScalarSizeInBits())) && 2138*73471bf0Spatrick match(Op1, m_OneUse(m_Intrinsic<Intrinsic::ctpop>(m_Value(X))))) 2139*73471bf0Spatrick return replaceInstUsesWith( 2140*73471bf0Spatrick I, Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()}, 2141*73471bf0Spatrick {Builder.CreateNot(X)})); 2142*73471bf0Spatrick 2143097a140dSpatrick return TryToNarrowDeduceFlags(); 214409467b48Spatrick } 214509467b48Spatrick 214609467b48Spatrick /// This eliminates floating-point negation in either 'fneg(X)' or 214709467b48Spatrick /// 'fsub(-0.0, X)' form by combining into a constant operand. 214809467b48Spatrick static Instruction *foldFNegIntoConstant(Instruction &I) { 2149*73471bf0Spatrick // This is limited with one-use because fneg is assumed better for 2150*73471bf0Spatrick // reassociation and cheaper in codegen than fmul/fdiv. 2151*73471bf0Spatrick // TODO: Should the m_OneUse restriction be removed? 2152*73471bf0Spatrick Instruction *FNegOp; 2153*73471bf0Spatrick if (!match(&I, m_FNeg(m_OneUse(m_Instruction(FNegOp))))) 2154*73471bf0Spatrick return nullptr; 2155*73471bf0Spatrick 215609467b48Spatrick Value *X; 215709467b48Spatrick Constant *C; 215809467b48Spatrick 2159*73471bf0Spatrick // Fold negation into constant operand. 216009467b48Spatrick // -(X * C) --> X * (-C) 2161*73471bf0Spatrick if (match(FNegOp, m_FMul(m_Value(X), m_Constant(C)))) 216209467b48Spatrick return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I); 216309467b48Spatrick // -(X / C) --> X / (-C) 2164*73471bf0Spatrick if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C)))) 216509467b48Spatrick return BinaryOperator::CreateFDivFMF(X, ConstantExpr::getFNeg(C), &I); 216609467b48Spatrick // -(C / X) --> (-C) / X 2167*73471bf0Spatrick if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X)))) { 2168*73471bf0Spatrick Instruction *FDiv = 2169*73471bf0Spatrick BinaryOperator::CreateFDivFMF(ConstantExpr::getFNeg(C), X, &I); 217009467b48Spatrick 2171*73471bf0Spatrick // Intersect 'nsz' and 'ninf' because those special value exceptions may not 2172*73471bf0Spatrick // apply to the fdiv. Everything else propagates from the fneg. 2173*73471bf0Spatrick // TODO: We could propagate nsz/ninf from fdiv alone? 2174*73471bf0Spatrick FastMathFlags FMF = I.getFastMathFlags(); 2175*73471bf0Spatrick FastMathFlags OpFMF = FNegOp->getFastMathFlags(); 2176*73471bf0Spatrick FDiv->setHasNoSignedZeros(FMF.noSignedZeros() & OpFMF.noSignedZeros()); 2177*73471bf0Spatrick FDiv->setHasNoInfs(FMF.noInfs() & OpFMF.noInfs()); 2178*73471bf0Spatrick return FDiv; 2179*73471bf0Spatrick } 2180097a140dSpatrick // With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]: 2181097a140dSpatrick // -(X + C) --> -X + -C --> -C - X 2182*73471bf0Spatrick if (I.hasNoSignedZeros() && match(FNegOp, m_FAdd(m_Value(X), m_Constant(C)))) 2183097a140dSpatrick return BinaryOperator::CreateFSubFMF(ConstantExpr::getFNeg(C), X, &I); 2184097a140dSpatrick 218509467b48Spatrick return nullptr; 218609467b48Spatrick } 218709467b48Spatrick 218809467b48Spatrick static Instruction *hoistFNegAboveFMulFDiv(Instruction &I, 218909467b48Spatrick InstCombiner::BuilderTy &Builder) { 219009467b48Spatrick Value *FNeg; 219109467b48Spatrick if (!match(&I, m_FNeg(m_Value(FNeg)))) 219209467b48Spatrick return nullptr; 219309467b48Spatrick 219409467b48Spatrick Value *X, *Y; 219509467b48Spatrick if (match(FNeg, m_OneUse(m_FMul(m_Value(X), m_Value(Y))))) 219609467b48Spatrick return BinaryOperator::CreateFMulFMF(Builder.CreateFNegFMF(X, &I), Y, &I); 219709467b48Spatrick 219809467b48Spatrick if (match(FNeg, m_OneUse(m_FDiv(m_Value(X), m_Value(Y))))) 219909467b48Spatrick return BinaryOperator::CreateFDivFMF(Builder.CreateFNegFMF(X, &I), Y, &I); 220009467b48Spatrick 220109467b48Spatrick return nullptr; 220209467b48Spatrick } 220309467b48Spatrick 2204*73471bf0Spatrick Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) { 220509467b48Spatrick Value *Op = I.getOperand(0); 220609467b48Spatrick 220709467b48Spatrick if (Value *V = SimplifyFNegInst(Op, I.getFastMathFlags(), 2208*73471bf0Spatrick getSimplifyQuery().getWithInstruction(&I))) 220909467b48Spatrick return replaceInstUsesWith(I, V); 221009467b48Spatrick 221109467b48Spatrick if (Instruction *X = foldFNegIntoConstant(I)) 221209467b48Spatrick return X; 221309467b48Spatrick 221409467b48Spatrick Value *X, *Y; 221509467b48Spatrick 221609467b48Spatrick // If we can ignore the sign of zeros: -(X - Y) --> (Y - X) 221709467b48Spatrick if (I.hasNoSignedZeros() && 221809467b48Spatrick match(Op, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) 221909467b48Spatrick return BinaryOperator::CreateFSubFMF(Y, X, &I); 222009467b48Spatrick 222109467b48Spatrick if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder)) 222209467b48Spatrick return R; 222309467b48Spatrick 2224*73471bf0Spatrick // Try to eliminate fneg if at least 1 arm of the select is negated. 2225*73471bf0Spatrick Value *Cond; 2226*73471bf0Spatrick if (match(Op, m_OneUse(m_Select(m_Value(Cond), m_Value(X), m_Value(Y))))) { 2227*73471bf0Spatrick // Unlike most transforms, this one is not safe to propagate nsz unless 2228*73471bf0Spatrick // it is present on the original select. (We are conservatively intersecting 2229*73471bf0Spatrick // the nsz flags from the select and root fneg instruction.) 2230*73471bf0Spatrick auto propagateSelectFMF = [&](SelectInst *S) { 2231*73471bf0Spatrick S->copyFastMathFlags(&I); 2232*73471bf0Spatrick if (auto *OldSel = dyn_cast<SelectInst>(Op)) 2233*73471bf0Spatrick if (!OldSel->hasNoSignedZeros()) 2234*73471bf0Spatrick S->setHasNoSignedZeros(false); 2235*73471bf0Spatrick }; 2236*73471bf0Spatrick // -(Cond ? -P : Y) --> Cond ? P : -Y 2237*73471bf0Spatrick Value *P; 2238*73471bf0Spatrick if (match(X, m_FNeg(m_Value(P)))) { 2239*73471bf0Spatrick Value *NegY = Builder.CreateFNegFMF(Y, &I, Y->getName() + ".neg"); 2240*73471bf0Spatrick SelectInst *NewSel = SelectInst::Create(Cond, P, NegY); 2241*73471bf0Spatrick propagateSelectFMF(NewSel); 2242*73471bf0Spatrick return NewSel; 2243*73471bf0Spatrick } 2244*73471bf0Spatrick // -(Cond ? X : -P) --> Cond ? -X : P 2245*73471bf0Spatrick if (match(Y, m_FNeg(m_Value(P)))) { 2246*73471bf0Spatrick Value *NegX = Builder.CreateFNegFMF(X, &I, X->getName() + ".neg"); 2247*73471bf0Spatrick SelectInst *NewSel = SelectInst::Create(Cond, NegX, P); 2248*73471bf0Spatrick propagateSelectFMF(NewSel); 2249*73471bf0Spatrick return NewSel; 2250*73471bf0Spatrick } 2251*73471bf0Spatrick } 2252*73471bf0Spatrick 225309467b48Spatrick return nullptr; 225409467b48Spatrick } 225509467b48Spatrick 2256*73471bf0Spatrick Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) { 225709467b48Spatrick if (Value *V = SimplifyFSubInst(I.getOperand(0), I.getOperand(1), 225809467b48Spatrick I.getFastMathFlags(), 2259*73471bf0Spatrick getSimplifyQuery().getWithInstruction(&I))) 226009467b48Spatrick return replaceInstUsesWith(I, V); 226109467b48Spatrick 226209467b48Spatrick if (Instruction *X = foldVectorBinop(I)) 226309467b48Spatrick return X; 226409467b48Spatrick 226509467b48Spatrick // Subtraction from -0.0 is the canonical form of fneg. 2266097a140dSpatrick // fsub -0.0, X ==> fneg X 2267097a140dSpatrick // fsub nsz 0.0, X ==> fneg nsz X 2268097a140dSpatrick // 2269097a140dSpatrick // FIXME This matcher does not respect FTZ or DAZ yet: 2270097a140dSpatrick // fsub -0.0, Denorm ==> +-0 2271097a140dSpatrick // fneg Denorm ==> -Denorm 2272097a140dSpatrick Value *Op; 2273097a140dSpatrick if (match(&I, m_FNeg(m_Value(Op)))) 2274097a140dSpatrick return UnaryOperator::CreateFNegFMF(Op, &I); 227509467b48Spatrick 227609467b48Spatrick if (Instruction *X = foldFNegIntoConstant(I)) 227709467b48Spatrick return X; 227809467b48Spatrick 227909467b48Spatrick if (Instruction *R = hoistFNegAboveFMulFDiv(I, Builder)) 228009467b48Spatrick return R; 228109467b48Spatrick 228209467b48Spatrick Value *X, *Y; 228309467b48Spatrick Constant *C; 228409467b48Spatrick 2285097a140dSpatrick Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); 228609467b48Spatrick // If Op0 is not -0.0 or we can ignore -0.0: Z - (X - Y) --> Z + (Y - X) 228709467b48Spatrick // Canonicalize to fadd to make analysis easier. 228809467b48Spatrick // This can also help codegen because fadd is commutative. 228909467b48Spatrick // Note that if this fsub was really an fneg, the fadd with -0.0 will get 229009467b48Spatrick // killed later. We still limit that particular transform with 'hasOneUse' 229109467b48Spatrick // because an fneg is assumed better/cheaper than a generic fsub. 229209467b48Spatrick if (I.hasNoSignedZeros() || CannotBeNegativeZero(Op0, SQ.TLI)) { 229309467b48Spatrick if (match(Op1, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) { 229409467b48Spatrick Value *NewSub = Builder.CreateFSubFMF(Y, X, &I); 229509467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, NewSub, &I); 229609467b48Spatrick } 229709467b48Spatrick } 229809467b48Spatrick 2299097a140dSpatrick // (-X) - Op1 --> -(X + Op1) 2300097a140dSpatrick if (I.hasNoSignedZeros() && !isa<ConstantExpr>(Op0) && 2301097a140dSpatrick match(Op0, m_OneUse(m_FNeg(m_Value(X))))) { 2302097a140dSpatrick Value *FAdd = Builder.CreateFAddFMF(X, Op1, &I); 2303097a140dSpatrick return UnaryOperator::CreateFNegFMF(FAdd, &I); 2304097a140dSpatrick } 2305097a140dSpatrick 230609467b48Spatrick if (isa<Constant>(Op0)) 230709467b48Spatrick if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) 230809467b48Spatrick if (Instruction *NV = FoldOpIntoSelect(I, SI)) 230909467b48Spatrick return NV; 231009467b48Spatrick 231109467b48Spatrick // X - C --> X + (-C) 231209467b48Spatrick // But don't transform constant expressions because there's an inverse fold 231309467b48Spatrick // for X + (-Y) --> X - Y. 2314*73471bf0Spatrick if (match(Op1, m_ImmConstant(C))) 231509467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I); 231609467b48Spatrick 231709467b48Spatrick // X - (-Y) --> X + Y 231809467b48Spatrick if (match(Op1, m_FNeg(m_Value(Y)))) 231909467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, Y, &I); 232009467b48Spatrick 232109467b48Spatrick // Similar to above, but look through a cast of the negated value: 232209467b48Spatrick // X - (fptrunc(-Y)) --> X + fptrunc(Y) 232309467b48Spatrick Type *Ty = I.getType(); 232409467b48Spatrick if (match(Op1, m_OneUse(m_FPTrunc(m_FNeg(m_Value(Y)))))) 232509467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPTrunc(Y, Ty), &I); 232609467b48Spatrick 232709467b48Spatrick // X - (fpext(-Y)) --> X + fpext(Y) 232809467b48Spatrick if (match(Op1, m_OneUse(m_FPExt(m_FNeg(m_Value(Y)))))) 232909467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPExt(Y, Ty), &I); 233009467b48Spatrick 233109467b48Spatrick // Similar to above, but look through fmul/fdiv of the negated value: 233209467b48Spatrick // Op0 - (-X * Y) --> Op0 + (X * Y) 233309467b48Spatrick // Op0 - (Y * -X) --> Op0 + (X * Y) 233409467b48Spatrick if (match(Op1, m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))))) { 233509467b48Spatrick Value *FMul = Builder.CreateFMulFMF(X, Y, &I); 233609467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, FMul, &I); 233709467b48Spatrick } 233809467b48Spatrick // Op0 - (-X / Y) --> Op0 + (X / Y) 233909467b48Spatrick // Op0 - (X / -Y) --> Op0 + (X / Y) 234009467b48Spatrick if (match(Op1, m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y)))) || 234109467b48Spatrick match(Op1, m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))))) { 234209467b48Spatrick Value *FDiv = Builder.CreateFDivFMF(X, Y, &I); 234309467b48Spatrick return BinaryOperator::CreateFAddFMF(Op0, FDiv, &I); 234409467b48Spatrick } 234509467b48Spatrick 234609467b48Spatrick // Handle special cases for FSub with selects feeding the operation 234709467b48Spatrick if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) 234809467b48Spatrick return replaceInstUsesWith(I, V); 234909467b48Spatrick 235009467b48Spatrick if (I.hasAllowReassoc() && I.hasNoSignedZeros()) { 235109467b48Spatrick // (Y - X) - Y --> -X 235209467b48Spatrick if (match(Op0, m_FSub(m_Specific(Op1), m_Value(X)))) 2353097a140dSpatrick return UnaryOperator::CreateFNegFMF(X, &I); 235409467b48Spatrick 235509467b48Spatrick // Y - (X + Y) --> -X 235609467b48Spatrick // Y - (Y + X) --> -X 235709467b48Spatrick if (match(Op1, m_c_FAdd(m_Specific(Op0), m_Value(X)))) 2358097a140dSpatrick return UnaryOperator::CreateFNegFMF(X, &I); 235909467b48Spatrick 236009467b48Spatrick // (X * C) - X --> X * (C - 1.0) 236109467b48Spatrick if (match(Op0, m_FMul(m_Specific(Op1), m_Constant(C)))) { 236209467b48Spatrick Constant *CSubOne = ConstantExpr::getFSub(C, ConstantFP::get(Ty, 1.0)); 236309467b48Spatrick return BinaryOperator::CreateFMulFMF(Op1, CSubOne, &I); 236409467b48Spatrick } 236509467b48Spatrick // X - (X * C) --> X * (1.0 - C) 236609467b48Spatrick if (match(Op1, m_FMul(m_Specific(Op0), m_Constant(C)))) { 236709467b48Spatrick Constant *OneSubC = ConstantExpr::getFSub(ConstantFP::get(Ty, 1.0), C); 236809467b48Spatrick return BinaryOperator::CreateFMulFMF(Op0, OneSubC, &I); 236909467b48Spatrick } 237009467b48Spatrick 2371097a140dSpatrick // Reassociate fsub/fadd sequences to create more fadd instructions and 2372097a140dSpatrick // reduce dependency chains: 2373097a140dSpatrick // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1) 2374097a140dSpatrick Value *Z; 2375097a140dSpatrick if (match(Op0, m_OneUse(m_c_FAdd(m_OneUse(m_FSub(m_Value(X), m_Value(Y))), 2376097a140dSpatrick m_Value(Z))))) { 2377097a140dSpatrick Value *XZ = Builder.CreateFAddFMF(X, Z, &I); 2378097a140dSpatrick Value *YW = Builder.CreateFAddFMF(Y, Op1, &I); 2379097a140dSpatrick return BinaryOperator::CreateFSubFMF(XZ, YW, &I); 2380097a140dSpatrick } 2381097a140dSpatrick 2382097a140dSpatrick auto m_FaddRdx = [](Value *&Sum, Value *&Vec) { 2383*73471bf0Spatrick return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>(m_Value(Sum), 2384*73471bf0Spatrick m_Value(Vec))); 2385097a140dSpatrick }; 2386097a140dSpatrick Value *A0, *A1, *V0, *V1; 2387097a140dSpatrick if (match(Op0, m_FaddRdx(A0, V0)) && match(Op1, m_FaddRdx(A1, V1)) && 2388097a140dSpatrick V0->getType() == V1->getType()) { 2389097a140dSpatrick // Difference of sums is sum of differences: 2390097a140dSpatrick // add_rdx(A0, V0) - add_rdx(A1, V1) --> add_rdx(A0, V0 - V1) - A1 2391097a140dSpatrick Value *Sub = Builder.CreateFSubFMF(V0, V1, &I); 2392*73471bf0Spatrick Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd, 2393*73471bf0Spatrick {Sub->getType()}, {A0, Sub}, &I); 2394097a140dSpatrick return BinaryOperator::CreateFSubFMF(Rdx, A1, &I); 2395097a140dSpatrick } 2396097a140dSpatrick 239709467b48Spatrick if (Instruction *F = factorizeFAddFSub(I, Builder)) 239809467b48Spatrick return F; 239909467b48Spatrick 240009467b48Spatrick // TODO: This performs reassociative folds for FP ops. Some fraction of the 240109467b48Spatrick // functionality has been subsumed by simple pattern matching here and in 240209467b48Spatrick // InstSimplify. We should let a dedicated reassociation pass handle more 240309467b48Spatrick // complex pattern matching and remove this from InstCombine. 240409467b48Spatrick if (Value *V = FAddCombine(Builder).simplify(&I)) 240509467b48Spatrick return replaceInstUsesWith(I, V); 2406097a140dSpatrick 2407097a140dSpatrick // (X - Y) - Op1 --> X - (Y + Op1) 2408097a140dSpatrick if (match(Op0, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) { 2409097a140dSpatrick Value *FAdd = Builder.CreateFAddFMF(Y, Op1, &I); 2410097a140dSpatrick return BinaryOperator::CreateFSubFMF(X, FAdd, &I); 2411097a140dSpatrick } 241209467b48Spatrick } 241309467b48Spatrick 241409467b48Spatrick return nullptr; 241509467b48Spatrick } 2416