xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- InstCombineCasts.cpp -----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the visit functions for cast operations.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "InstCombineInternal.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
150b57cec5SDimitry Andric #include "llvm/Analysis/ConstantFolding.h"
16e8d8bef9SDimitry Andric #include "llvm/IR/DataLayout.h"
17bdd1243dSDimitry Andric #include "llvm/IR/DebugInfo.h"
180b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h"
190b57cec5SDimitry Andric #include "llvm/Support/KnownBits.h"
20e8d8bef9SDimitry Andric #include "llvm/Transforms/InstCombine/InstCombiner.h"
21bdd1243dSDimitry Andric #include <optional>
22bdd1243dSDimitry Andric 
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric using namespace PatternMatch;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric #define DEBUG_TYPE "instcombine"
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric /// Given an expression that CanEvaluateTruncated or CanEvaluateSExtd returns
290b57cec5SDimitry Andric /// true for, actually insert the code to evaluate the expression.
30e8d8bef9SDimitry Andric Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty,
310b57cec5SDimitry Andric                                                  bool isSigned) {
325f757f3fSDimitry Andric   if (Constant *C = dyn_cast<Constant>(V))
335f757f3fSDimitry Andric     return ConstantFoldIntegerCast(C, Ty, isSigned, DL);
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   // Otherwise, it must be an instruction.
360b57cec5SDimitry Andric   Instruction *I = cast<Instruction>(V);
370b57cec5SDimitry Andric   Instruction *Res = nullptr;
380b57cec5SDimitry Andric   unsigned Opc = I->getOpcode();
390b57cec5SDimitry Andric   switch (Opc) {
400b57cec5SDimitry Andric   case Instruction::Add:
410b57cec5SDimitry Andric   case Instruction::Sub:
420b57cec5SDimitry Andric   case Instruction::Mul:
430b57cec5SDimitry Andric   case Instruction::And:
440b57cec5SDimitry Andric   case Instruction::Or:
450b57cec5SDimitry Andric   case Instruction::Xor:
460b57cec5SDimitry Andric   case Instruction::AShr:
470b57cec5SDimitry Andric   case Instruction::LShr:
480b57cec5SDimitry Andric   case Instruction::Shl:
490b57cec5SDimitry Andric   case Instruction::UDiv:
500b57cec5SDimitry Andric   case Instruction::URem: {
510b57cec5SDimitry Andric     Value *LHS = EvaluateInDifferentType(I->getOperand(0), Ty, isSigned);
520b57cec5SDimitry Andric     Value *RHS = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned);
530b57cec5SDimitry Andric     Res = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
540b57cec5SDimitry Andric     break;
550b57cec5SDimitry Andric   }
560b57cec5SDimitry Andric   case Instruction::Trunc:
570b57cec5SDimitry Andric   case Instruction::ZExt:
580b57cec5SDimitry Andric   case Instruction::SExt:
590b57cec5SDimitry Andric     // If the source type of the cast is the type we're trying for then we can
600b57cec5SDimitry Andric     // just return the source.  There's no need to insert it because it is not
610b57cec5SDimitry Andric     // new.
620b57cec5SDimitry Andric     if (I->getOperand(0)->getType() == Ty)
630b57cec5SDimitry Andric       return I->getOperand(0);
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric     // Otherwise, must be the same type of cast, so just reinsert a new one.
660b57cec5SDimitry Andric     // This also handles the case of zext(trunc(x)) -> zext(x).
670b57cec5SDimitry Andric     Res = CastInst::CreateIntegerCast(I->getOperand(0), Ty,
680b57cec5SDimitry Andric                                       Opc == Instruction::SExt);
690b57cec5SDimitry Andric     break;
700b57cec5SDimitry Andric   case Instruction::Select: {
710b57cec5SDimitry Andric     Value *True = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned);
720b57cec5SDimitry Andric     Value *False = EvaluateInDifferentType(I->getOperand(2), Ty, isSigned);
730b57cec5SDimitry Andric     Res = SelectInst::Create(I->getOperand(0), True, False);
740b57cec5SDimitry Andric     break;
750b57cec5SDimitry Andric   }
760b57cec5SDimitry Andric   case Instruction::PHI: {
770b57cec5SDimitry Andric     PHINode *OPN = cast<PHINode>(I);
780b57cec5SDimitry Andric     PHINode *NPN = PHINode::Create(Ty, OPN->getNumIncomingValues());
790b57cec5SDimitry Andric     for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) {
800b57cec5SDimitry Andric       Value *V =
810b57cec5SDimitry Andric           EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned);
820b57cec5SDimitry Andric       NPN->addIncoming(V, OPN->getIncomingBlock(i));
830b57cec5SDimitry Andric     }
840b57cec5SDimitry Andric     Res = NPN;
850b57cec5SDimitry Andric     break;
860b57cec5SDimitry Andric   }
87bdd1243dSDimitry Andric   case Instruction::FPToUI:
88bdd1243dSDimitry Andric   case Instruction::FPToSI:
89bdd1243dSDimitry Andric     Res = CastInst::Create(
90bdd1243dSDimitry Andric       static_cast<Instruction::CastOps>(Opc), I->getOperand(0), Ty);
91bdd1243dSDimitry Andric     break;
9206c3fb27SDimitry Andric   case Instruction::Call:
9306c3fb27SDimitry Andric     if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
9406c3fb27SDimitry Andric       switch (II->getIntrinsicID()) {
9506c3fb27SDimitry Andric       default:
9606c3fb27SDimitry Andric         llvm_unreachable("Unsupported call!");
9706c3fb27SDimitry Andric       case Intrinsic::vscale: {
9806c3fb27SDimitry Andric         Function *Fn =
9906c3fb27SDimitry Andric             Intrinsic::getDeclaration(I->getModule(), Intrinsic::vscale, {Ty});
10006c3fb27SDimitry Andric         Res = CallInst::Create(Fn->getFunctionType(), Fn);
10106c3fb27SDimitry Andric         break;
10206c3fb27SDimitry Andric       }
10306c3fb27SDimitry Andric       }
10406c3fb27SDimitry Andric     }
10506c3fb27SDimitry Andric     break;
1067a6dacacSDimitry Andric   case Instruction::ShuffleVector: {
1077a6dacacSDimitry Andric     auto *ScalarTy = cast<VectorType>(Ty)->getElementType();
1087a6dacacSDimitry Andric     auto *VTy = cast<VectorType>(I->getOperand(0)->getType());
1097a6dacacSDimitry Andric     auto *FixedTy = VectorType::get(ScalarTy, VTy->getElementCount());
1107a6dacacSDimitry Andric     Value *Op0 = EvaluateInDifferentType(I->getOperand(0), FixedTy, isSigned);
1117a6dacacSDimitry Andric     Value *Op1 = EvaluateInDifferentType(I->getOperand(1), FixedTy, isSigned);
1127a6dacacSDimitry Andric     Res = new ShuffleVectorInst(Op0, Op1,
1137a6dacacSDimitry Andric                                 cast<ShuffleVectorInst>(I)->getShuffleMask());
1147a6dacacSDimitry Andric     break;
1157a6dacacSDimitry Andric   }
1160b57cec5SDimitry Andric   default:
1170b57cec5SDimitry Andric     // TODO: Can handle more cases here.
1180b57cec5SDimitry Andric     llvm_unreachable("Unreachable!");
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   Res->takeName(I);
1225f757f3fSDimitry Andric   return InsertNewInstWith(Res, I->getIterator());
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
125e8d8bef9SDimitry Andric Instruction::CastOps
126e8d8bef9SDimitry Andric InstCombinerImpl::isEliminableCastPair(const CastInst *CI1,
1270b57cec5SDimitry Andric                                        const CastInst *CI2) {
1280b57cec5SDimitry Andric   Type *SrcTy = CI1->getSrcTy();
1290b57cec5SDimitry Andric   Type *MidTy = CI1->getDestTy();
1300b57cec5SDimitry Andric   Type *DstTy = CI2->getDestTy();
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   Instruction::CastOps firstOp = CI1->getOpcode();
1330b57cec5SDimitry Andric   Instruction::CastOps secondOp = CI2->getOpcode();
1340b57cec5SDimitry Andric   Type *SrcIntPtrTy =
1350b57cec5SDimitry Andric       SrcTy->isPtrOrPtrVectorTy() ? DL.getIntPtrType(SrcTy) : nullptr;
1360b57cec5SDimitry Andric   Type *MidIntPtrTy =
1370b57cec5SDimitry Andric       MidTy->isPtrOrPtrVectorTy() ? DL.getIntPtrType(MidTy) : nullptr;
1380b57cec5SDimitry Andric   Type *DstIntPtrTy =
1390b57cec5SDimitry Andric       DstTy->isPtrOrPtrVectorTy() ? DL.getIntPtrType(DstTy) : nullptr;
1400b57cec5SDimitry Andric   unsigned Res = CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy,
1410b57cec5SDimitry Andric                                                 DstTy, SrcIntPtrTy, MidIntPtrTy,
1420b57cec5SDimitry Andric                                                 DstIntPtrTy);
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   // We don't want to form an inttoptr or ptrtoint that converts to an integer
1450b57cec5SDimitry Andric   // type that differs from the pointer size.
1460b57cec5SDimitry Andric   if ((Res == Instruction::IntToPtr && SrcTy != DstIntPtrTy) ||
1470b57cec5SDimitry Andric       (Res == Instruction::PtrToInt && DstTy != SrcIntPtrTy))
1480b57cec5SDimitry Andric     Res = 0;
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   return Instruction::CastOps(Res);
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric /// Implement the transforms common to all CastInst visitors.
154e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) {
1550b57cec5SDimitry Andric   Value *Src = CI.getOperand(0);
156fe6060f1SDimitry Andric   Type *Ty = CI.getType();
1570b57cec5SDimitry Andric 
15806c3fb27SDimitry Andric   if (auto *SrcC = dyn_cast<Constant>(Src))
15906c3fb27SDimitry Andric     if (Constant *Res = ConstantFoldCastOperand(CI.getOpcode(), SrcC, Ty, DL))
16006c3fb27SDimitry Andric       return replaceInstUsesWith(CI, Res);
16106c3fb27SDimitry Andric 
1620b57cec5SDimitry Andric   // Try to eliminate a cast of a cast.
1630b57cec5SDimitry Andric   if (auto *CSrc = dyn_cast<CastInst>(Src)) {   // A->B->C cast
1640b57cec5SDimitry Andric     if (Instruction::CastOps NewOpc = isEliminableCastPair(CSrc, &CI)) {
1650b57cec5SDimitry Andric       // The first cast (CSrc) is eliminable so we need to fix up or replace
1660b57cec5SDimitry Andric       // the second cast (CI). CSrc will then have a good chance of being dead.
1670b57cec5SDimitry Andric       auto *Res = CastInst::Create(NewOpc, CSrc->getOperand(0), Ty);
1680b57cec5SDimitry Andric       // Point debug users of the dying cast to the new one.
1690b57cec5SDimitry Andric       if (CSrc->hasOneUse())
1700b57cec5SDimitry Andric         replaceAllDbgUsesWith(*CSrc, *Res, CI, DT);
1710b57cec5SDimitry Andric       return Res;
1720b57cec5SDimitry Andric     }
1730b57cec5SDimitry Andric   }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   if (auto *Sel = dyn_cast<SelectInst>(Src)) {
1765ffd83dbSDimitry Andric     // We are casting a select. Try to fold the cast into the select if the
1775ffd83dbSDimitry Andric     // select does not have a compare instruction with matching operand types
1785ffd83dbSDimitry Andric     // or the select is likely better done in a narrow type.
1795ffd83dbSDimitry Andric     // Creating a select with operands that are different sizes than its
1800b57cec5SDimitry Andric     // condition may inhibit other folds and lead to worse codegen.
1810b57cec5SDimitry Andric     auto *Cmp = dyn_cast<CmpInst>(Sel->getCondition());
1825ffd83dbSDimitry Andric     if (!Cmp || Cmp->getOperand(0)->getType() != Sel->getType() ||
1835ffd83dbSDimitry Andric         (CI.getOpcode() == Instruction::Trunc &&
1845ffd83dbSDimitry Andric          shouldChangeType(CI.getSrcTy(), CI.getType()))) {
185*0fca6ea1SDimitry Andric 
186*0fca6ea1SDimitry Andric       // If it's a bitcast involving vectors, make sure it has the same number
187*0fca6ea1SDimitry Andric       // of elements on both sides.
188*0fca6ea1SDimitry Andric       if (CI.getOpcode() != Instruction::BitCast ||
189*0fca6ea1SDimitry Andric           match(&CI, m_ElementWiseBitCast(m_Value()))) {
1900b57cec5SDimitry Andric         if (Instruction *NV = FoldOpIntoSelect(CI, Sel)) {
1910b57cec5SDimitry Andric           replaceAllDbgUsesWith(*Sel, *NV, CI, DT);
1920b57cec5SDimitry Andric           return NV;
1930b57cec5SDimitry Andric         }
1940b57cec5SDimitry Andric       }
1955ffd83dbSDimitry Andric     }
196*0fca6ea1SDimitry Andric   }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   // If we are casting a PHI, then fold the cast into the PHI.
1990b57cec5SDimitry Andric   if (auto *PN = dyn_cast<PHINode>(Src)) {
2000b57cec5SDimitry Andric     // Don't do this if it would create a PHI node with an illegal type from a
2010b57cec5SDimitry Andric     // legal type.
2020b57cec5SDimitry Andric     if (!Src->getType()->isIntegerTy() || !CI.getType()->isIntegerTy() ||
2035ffd83dbSDimitry Andric         shouldChangeType(CI.getSrcTy(), CI.getType()))
2040b57cec5SDimitry Andric       if (Instruction *NV = foldOpIntoPhi(CI, PN))
2050b57cec5SDimitry Andric         return NV;
2060b57cec5SDimitry Andric   }
2070b57cec5SDimitry Andric 
208fe6060f1SDimitry Andric   // Canonicalize a unary shuffle after the cast if neither operation changes
209fe6060f1SDimitry Andric   // the size or element size of the input vector.
210fe6060f1SDimitry Andric   // TODO: We could allow size-changing ops if that doesn't harm codegen.
211fe6060f1SDimitry Andric   // cast (shuffle X, Mask) --> shuffle (cast X), Mask
212fe6060f1SDimitry Andric   Value *X;
213fe6060f1SDimitry Andric   ArrayRef<int> Mask;
214fe6060f1SDimitry Andric   if (match(Src, m_OneUse(m_Shuffle(m_Value(X), m_Undef(), m_Mask(Mask))))) {
215fe6060f1SDimitry Andric     // TODO: Allow scalable vectors?
216fe6060f1SDimitry Andric     auto *SrcTy = dyn_cast<FixedVectorType>(X->getType());
217fe6060f1SDimitry Andric     auto *DestTy = dyn_cast<FixedVectorType>(Ty);
218fe6060f1SDimitry Andric     if (SrcTy && DestTy &&
219fe6060f1SDimitry Andric         SrcTy->getNumElements() == DestTy->getNumElements() &&
220fe6060f1SDimitry Andric         SrcTy->getPrimitiveSizeInBits() == DestTy->getPrimitiveSizeInBits()) {
221fe6060f1SDimitry Andric       Value *CastX = Builder.CreateCast(CI.getOpcode(), X, DestTy);
222349cc55cSDimitry Andric       return new ShuffleVectorInst(CastX, Mask);
223fe6060f1SDimitry Andric     }
224fe6060f1SDimitry Andric   }
225fe6060f1SDimitry Andric 
2260b57cec5SDimitry Andric   return nullptr;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric /// Constants and extensions/truncates from the destination type are always
2300b57cec5SDimitry Andric /// free to be evaluated in that type. This is a helper for canEvaluate*.
2310b57cec5SDimitry Andric static bool canAlwaysEvaluateInType(Value *V, Type *Ty) {
2320b57cec5SDimitry Andric   if (isa<Constant>(V))
2335f757f3fSDimitry Andric     return match(V, m_ImmConstant());
2345f757f3fSDimitry Andric 
2350b57cec5SDimitry Andric   Value *X;
2360b57cec5SDimitry Andric   if ((match(V, m_ZExtOrSExt(m_Value(X))) || match(V, m_Trunc(m_Value(X)))) &&
2370b57cec5SDimitry Andric       X->getType() == Ty)
2380b57cec5SDimitry Andric     return true;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   return false;
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric /// Filter out values that we can not evaluate in the destination type for free.
2440b57cec5SDimitry Andric /// This is a helper for canEvaluate*.
2450b57cec5SDimitry Andric static bool canNotEvaluateInType(Value *V, Type *Ty) {
2460b57cec5SDimitry Andric   if (!isa<Instruction>(V))
2470b57cec5SDimitry Andric     return true;
2480b57cec5SDimitry Andric   // We don't extend or shrink something that has multiple uses --  doing so
2490b57cec5SDimitry Andric   // would require duplicating the instruction which isn't profitable.
2500b57cec5SDimitry Andric   if (!V->hasOneUse())
2510b57cec5SDimitry Andric     return true;
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   return false;
2540b57cec5SDimitry Andric }
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric /// Return true if we can evaluate the specified expression tree as type Ty
2570b57cec5SDimitry Andric /// instead of its larger type, and arrive with the same value.
2580b57cec5SDimitry Andric /// This is used by code that tries to eliminate truncates.
2590b57cec5SDimitry Andric ///
2600b57cec5SDimitry Andric /// Ty will always be a type smaller than V.  We should return true if trunc(V)
2610b57cec5SDimitry Andric /// can be computed by computing V in the smaller type.  If V is an instruction,
2620b57cec5SDimitry Andric /// then trunc(inst(x,y)) can be computed as inst(trunc(x),trunc(y)), which only
2630b57cec5SDimitry Andric /// makes sense if x and y can be efficiently truncated.
2640b57cec5SDimitry Andric ///
2650b57cec5SDimitry Andric /// This function works on both vectors and scalars.
2660b57cec5SDimitry Andric ///
267e8d8bef9SDimitry Andric static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC,
2680b57cec5SDimitry Andric                                  Instruction *CxtI) {
2690b57cec5SDimitry Andric   if (canAlwaysEvaluateInType(V, Ty))
2700b57cec5SDimitry Andric     return true;
2710b57cec5SDimitry Andric   if (canNotEvaluateInType(V, Ty))
2720b57cec5SDimitry Andric     return false;
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric   auto *I = cast<Instruction>(V);
2750b57cec5SDimitry Andric   Type *OrigTy = V->getType();
2760b57cec5SDimitry Andric   switch (I->getOpcode()) {
2770b57cec5SDimitry Andric   case Instruction::Add:
2780b57cec5SDimitry Andric   case Instruction::Sub:
2790b57cec5SDimitry Andric   case Instruction::Mul:
2800b57cec5SDimitry Andric   case Instruction::And:
2810b57cec5SDimitry Andric   case Instruction::Or:
2820b57cec5SDimitry Andric   case Instruction::Xor:
2830b57cec5SDimitry Andric     // These operators can all arbitrarily be extended or truncated.
2840b57cec5SDimitry Andric     return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI) &&
2850b57cec5SDimitry Andric            canEvaluateTruncated(I->getOperand(1), Ty, IC, CxtI);
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   case Instruction::UDiv:
2880b57cec5SDimitry Andric   case Instruction::URem: {
2890b57cec5SDimitry Andric     // UDiv and URem can be truncated if all the truncated bits are zero.
2900b57cec5SDimitry Andric     uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
2910b57cec5SDimitry Andric     uint32_t BitWidth = Ty->getScalarSizeInBits();
2920b57cec5SDimitry Andric     assert(BitWidth < OrigBitWidth && "Unexpected bitwidths!");
2930b57cec5SDimitry Andric     APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth);
294*0fca6ea1SDimitry Andric     // Do not preserve the original context instruction. Simplifying div/rem
295*0fca6ea1SDimitry Andric     // based on later context may introduce a trap.
296*0fca6ea1SDimitry Andric     if (IC.MaskedValueIsZero(I->getOperand(0), Mask, 0, I) &&
297*0fca6ea1SDimitry Andric         IC.MaskedValueIsZero(I->getOperand(1), Mask, 0, I)) {
298*0fca6ea1SDimitry Andric       return canEvaluateTruncated(I->getOperand(0), Ty, IC, I) &&
299*0fca6ea1SDimitry Andric              canEvaluateTruncated(I->getOperand(1), Ty, IC, I);
3000b57cec5SDimitry Andric     }
3010b57cec5SDimitry Andric     break;
3020b57cec5SDimitry Andric   }
3030b57cec5SDimitry Andric   case Instruction::Shl: {
3045ffd83dbSDimitry Andric     // If we are truncating the result of this SHL, and if it's a shift of an
3055ffd83dbSDimitry Andric     // inrange amount, we can always perform a SHL in a smaller type.
3060b57cec5SDimitry Andric     uint32_t BitWidth = Ty->getScalarSizeInBits();
3075ffd83dbSDimitry Andric     KnownBits AmtKnownBits =
3085ffd83dbSDimitry Andric         llvm::computeKnownBits(I->getOperand(1), IC.getDataLayout());
3095ffd83dbSDimitry Andric     if (AmtKnownBits.getMaxValue().ult(BitWidth))
3105ffd83dbSDimitry Andric       return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI) &&
3115ffd83dbSDimitry Andric              canEvaluateTruncated(I->getOperand(1), Ty, IC, CxtI);
3120b57cec5SDimitry Andric     break;
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric   case Instruction::LShr: {
3150b57cec5SDimitry Andric     // If this is a truncate of a logical shr, we can truncate it to a smaller
3160b57cec5SDimitry Andric     // lshr iff we know that the bits we would otherwise be shifting in are
3170b57cec5SDimitry Andric     // already zeros.
3185ffd83dbSDimitry Andric     // TODO: It is enough to check that the bits we would be shifting in are
3195ffd83dbSDimitry Andric     //       zero - use AmtKnownBits.getMaxValue().
3200b57cec5SDimitry Andric     uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
3210b57cec5SDimitry Andric     uint32_t BitWidth = Ty->getScalarSizeInBits();
3225ffd83dbSDimitry Andric     KnownBits AmtKnownBits =
3235ffd83dbSDimitry Andric         llvm::computeKnownBits(I->getOperand(1), IC.getDataLayout());
3245ffd83dbSDimitry Andric     APInt ShiftedBits = APInt::getBitsSetFrom(OrigBitWidth, BitWidth);
3255ffd83dbSDimitry Andric     if (AmtKnownBits.getMaxValue().ult(BitWidth) &&
3265ffd83dbSDimitry Andric         IC.MaskedValueIsZero(I->getOperand(0), ShiftedBits, 0, CxtI)) {
3275ffd83dbSDimitry Andric       return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI) &&
3285ffd83dbSDimitry Andric              canEvaluateTruncated(I->getOperand(1), Ty, IC, CxtI);
3290b57cec5SDimitry Andric     }
3300b57cec5SDimitry Andric     break;
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric   case Instruction::AShr: {
3330b57cec5SDimitry Andric     // If this is a truncate of an arithmetic shr, we can truncate it to a
3340b57cec5SDimitry Andric     // smaller ashr iff we know that all the bits from the sign bit of the
3350b57cec5SDimitry Andric     // original type and the sign bit of the truncate type are similar.
3360b57cec5SDimitry Andric     // TODO: It is enough to check that the bits we would be shifting in are
3370b57cec5SDimitry Andric     //       similar to sign bit of the truncate type.
3380b57cec5SDimitry Andric     uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
3390b57cec5SDimitry Andric     uint32_t BitWidth = Ty->getScalarSizeInBits();
3405ffd83dbSDimitry Andric     KnownBits AmtKnownBits =
3415ffd83dbSDimitry Andric         llvm::computeKnownBits(I->getOperand(1), IC.getDataLayout());
3425ffd83dbSDimitry Andric     unsigned ShiftedBits = OrigBitWidth - BitWidth;
3435ffd83dbSDimitry Andric     if (AmtKnownBits.getMaxValue().ult(BitWidth) &&
3445ffd83dbSDimitry Andric         ShiftedBits < IC.ComputeNumSignBits(I->getOperand(0), 0, CxtI))
3455ffd83dbSDimitry Andric       return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI) &&
3465ffd83dbSDimitry Andric              canEvaluateTruncated(I->getOperand(1), Ty, IC, CxtI);
3470b57cec5SDimitry Andric     break;
3480b57cec5SDimitry Andric   }
3490b57cec5SDimitry Andric   case Instruction::Trunc:
3500b57cec5SDimitry Andric     // trunc(trunc(x)) -> trunc(x)
3510b57cec5SDimitry Andric     return true;
3520b57cec5SDimitry Andric   case Instruction::ZExt:
3530b57cec5SDimitry Andric   case Instruction::SExt:
3540b57cec5SDimitry Andric     // trunc(ext(x)) -> ext(x) if the source type is smaller than the new dest
3550b57cec5SDimitry Andric     // trunc(ext(x)) -> trunc(x) if the source type is larger than the new dest
3560b57cec5SDimitry Andric     return true;
3570b57cec5SDimitry Andric   case Instruction::Select: {
3580b57cec5SDimitry Andric     SelectInst *SI = cast<SelectInst>(I);
3590b57cec5SDimitry Andric     return canEvaluateTruncated(SI->getTrueValue(), Ty, IC, CxtI) &&
3600b57cec5SDimitry Andric            canEvaluateTruncated(SI->getFalseValue(), Ty, IC, CxtI);
3610b57cec5SDimitry Andric   }
3620b57cec5SDimitry Andric   case Instruction::PHI: {
3630b57cec5SDimitry Andric     // We can change a phi if we can change all operands.  Note that we never
3640b57cec5SDimitry Andric     // get into trouble with cyclic PHIs here because we only consider
3650b57cec5SDimitry Andric     // instructions with a single use.
3660b57cec5SDimitry Andric     PHINode *PN = cast<PHINode>(I);
3670b57cec5SDimitry Andric     for (Value *IncValue : PN->incoming_values())
3680b57cec5SDimitry Andric       if (!canEvaluateTruncated(IncValue, Ty, IC, CxtI))
3690b57cec5SDimitry Andric         return false;
3700b57cec5SDimitry Andric     return true;
3710b57cec5SDimitry Andric   }
372bdd1243dSDimitry Andric   case Instruction::FPToUI:
373bdd1243dSDimitry Andric   case Instruction::FPToSI: {
374bdd1243dSDimitry Andric     // If the integer type can hold the max FP value, it is safe to cast
375bdd1243dSDimitry Andric     // directly to that type. Otherwise, we may create poison via overflow
376bdd1243dSDimitry Andric     // that did not exist in the original code.
377bdd1243dSDimitry Andric     Type *InputTy = I->getOperand(0)->getType()->getScalarType();
378bdd1243dSDimitry Andric     const fltSemantics &Semantics = InputTy->getFltSemantics();
37906c3fb27SDimitry Andric     uint32_t MinBitWidth =
38006c3fb27SDimitry Andric       APFloatBase::semanticsIntSizeInBits(Semantics,
38106c3fb27SDimitry Andric           I->getOpcode() == Instruction::FPToSI);
38206c3fb27SDimitry Andric     return Ty->getScalarSizeInBits() >= MinBitWidth;
383bdd1243dSDimitry Andric   }
3847a6dacacSDimitry Andric   case Instruction::ShuffleVector:
3857a6dacacSDimitry Andric     return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI) &&
3867a6dacacSDimitry Andric            canEvaluateTruncated(I->getOperand(1), Ty, IC, CxtI);
3870b57cec5SDimitry Andric   default:
3880b57cec5SDimitry Andric     // TODO: Can handle more cases here.
3890b57cec5SDimitry Andric     break;
3900b57cec5SDimitry Andric   }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric   return false;
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric /// Given a vector that is bitcast to an integer, optionally logically
3960b57cec5SDimitry Andric /// right-shifted, and truncated, convert it to an extractelement.
3970b57cec5SDimitry Andric /// Example (big endian):
3980b57cec5SDimitry Andric ///   trunc (lshr (bitcast <4 x i32> %X to i128), 32) to i32
3990b57cec5SDimitry Andric ///   --->
4000b57cec5SDimitry Andric ///   extractelement <4 x i32> %X, 1
401e8d8bef9SDimitry Andric static Instruction *foldVecTruncToExtElt(TruncInst &Trunc,
402e8d8bef9SDimitry Andric                                          InstCombinerImpl &IC) {
4030b57cec5SDimitry Andric   Value *TruncOp = Trunc.getOperand(0);
4040b57cec5SDimitry Andric   Type *DestType = Trunc.getType();
4050b57cec5SDimitry Andric   if (!TruncOp->hasOneUse() || !isa<IntegerType>(DestType))
4060b57cec5SDimitry Andric     return nullptr;
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   Value *VecInput = nullptr;
4090b57cec5SDimitry Andric   ConstantInt *ShiftVal = nullptr;
4100b57cec5SDimitry Andric   if (!match(TruncOp, m_CombineOr(m_BitCast(m_Value(VecInput)),
4110b57cec5SDimitry Andric                                   m_LShr(m_BitCast(m_Value(VecInput)),
4120b57cec5SDimitry Andric                                          m_ConstantInt(ShiftVal)))) ||
4130b57cec5SDimitry Andric       !isa<VectorType>(VecInput->getType()))
4140b57cec5SDimitry Andric     return nullptr;
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   VectorType *VecType = cast<VectorType>(VecInput->getType());
4170b57cec5SDimitry Andric   unsigned VecWidth = VecType->getPrimitiveSizeInBits();
4180b57cec5SDimitry Andric   unsigned DestWidth = DestType->getPrimitiveSizeInBits();
4190b57cec5SDimitry Andric   unsigned ShiftAmount = ShiftVal ? ShiftVal->getZExtValue() : 0;
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   if ((VecWidth % DestWidth != 0) || (ShiftAmount % DestWidth != 0))
4220b57cec5SDimitry Andric     return nullptr;
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric   // If the element type of the vector doesn't match the result type,
4250b57cec5SDimitry Andric   // bitcast it to a vector type that we can extract from.
4260b57cec5SDimitry Andric   unsigned NumVecElts = VecWidth / DestWidth;
4270b57cec5SDimitry Andric   if (VecType->getElementType() != DestType) {
4285ffd83dbSDimitry Andric     VecType = FixedVectorType::get(DestType, NumVecElts);
4290b57cec5SDimitry Andric     VecInput = IC.Builder.CreateBitCast(VecInput, VecType, "bc");
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   unsigned Elt = ShiftAmount / DestWidth;
4330b57cec5SDimitry Andric   if (IC.getDataLayout().isBigEndian())
4340b57cec5SDimitry Andric     Elt = NumVecElts - 1 - Elt;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   return ExtractElementInst::Create(VecInput, IC.Builder.getInt32(Elt));
4370b57cec5SDimitry Andric }
4380b57cec5SDimitry Andric 
439e8d8bef9SDimitry Andric /// Funnel/Rotate left/right may occur in a wider type than necessary because of
440e8d8bef9SDimitry Andric /// type promotion rules. Try to narrow the inputs and convert to funnel shift.
441e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) {
4420b57cec5SDimitry Andric   assert((isa<VectorType>(Trunc.getSrcTy()) ||
4430b57cec5SDimitry Andric           shouldChangeType(Trunc.getSrcTy(), Trunc.getType())) &&
4440b57cec5SDimitry Andric          "Don't narrow to an illegal scalar type");
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric   // Bail out on strange types. It is possible to handle some of these patterns
4470b57cec5SDimitry Andric   // even with non-power-of-2 sizes, but it is not a likely scenario.
4480b57cec5SDimitry Andric   Type *DestTy = Trunc.getType();
4490b57cec5SDimitry Andric   unsigned NarrowWidth = DestTy->getScalarSizeInBits();
450fe6060f1SDimitry Andric   unsigned WideWidth = Trunc.getSrcTy()->getScalarSizeInBits();
4510b57cec5SDimitry Andric   if (!isPowerOf2_32(NarrowWidth))
4520b57cec5SDimitry Andric     return nullptr;
4530b57cec5SDimitry Andric 
454e8d8bef9SDimitry Andric   // First, find an or'd pair of opposite shifts:
455e8d8bef9SDimitry Andric   // trunc (or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1))
456e8d8bef9SDimitry Andric   BinaryOperator *Or0, *Or1;
457e8d8bef9SDimitry Andric   if (!match(Trunc.getOperand(0), m_OneUse(m_Or(m_BinOp(Or0), m_BinOp(Or1)))))
4580b57cec5SDimitry Andric     return nullptr;
4590b57cec5SDimitry Andric 
460e8d8bef9SDimitry Andric   Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
461e8d8bef9SDimitry Andric   if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0)))) ||
462e8d8bef9SDimitry Andric       !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1)))) ||
463e8d8bef9SDimitry Andric       Or0->getOpcode() == Or1->getOpcode())
4640b57cec5SDimitry Andric     return nullptr;
4650b57cec5SDimitry Andric 
466e8d8bef9SDimitry Andric   // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
467e8d8bef9SDimitry Andric   if (Or0->getOpcode() == BinaryOperator::LShr) {
468e8d8bef9SDimitry Andric     std::swap(Or0, Or1);
469e8d8bef9SDimitry Andric     std::swap(ShVal0, ShVal1);
470e8d8bef9SDimitry Andric     std::swap(ShAmt0, ShAmt1);
471e8d8bef9SDimitry Andric   }
472e8d8bef9SDimitry Andric   assert(Or0->getOpcode() == BinaryOperator::Shl &&
473e8d8bef9SDimitry Andric          Or1->getOpcode() == BinaryOperator::LShr &&
474e8d8bef9SDimitry Andric          "Illegal or(shift,shift) pair");
4750b57cec5SDimitry Andric 
476e8d8bef9SDimitry Andric   // Match the shift amount operands for a funnel/rotate pattern. This always
477e8d8bef9SDimitry Andric   // matches a subtraction on the R operand.
478e8d8bef9SDimitry Andric   auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
4790b57cec5SDimitry Andric     // The shift amounts may add up to the narrow bit width:
480e8d8bef9SDimitry Andric     // (shl ShVal0, L) | (lshr ShVal1, Width - L)
481fe6060f1SDimitry Andric     // If this is a funnel shift (different operands are shifted), then the
482fe6060f1SDimitry Andric     // shift amount can not over-shift (create poison) in the narrow type.
483fe6060f1SDimitry Andric     unsigned MaxShiftAmountWidth = Log2_32(NarrowWidth);
484fe6060f1SDimitry Andric     APInt HiBitMask = ~APInt::getLowBitsSet(WideWidth, MaxShiftAmountWidth);
485fe6060f1SDimitry Andric     if (ShVal0 == ShVal1 || MaskedValueIsZero(L, HiBitMask))
4860b57cec5SDimitry Andric       if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L)))))
4870b57cec5SDimitry Andric         return L;
4880b57cec5SDimitry Andric 
489e8d8bef9SDimitry Andric     // The following patterns currently only work for rotation patterns.
490e8d8bef9SDimitry Andric     // TODO: Add more general funnel-shift compatible patterns.
491e8d8bef9SDimitry Andric     if (ShVal0 != ShVal1)
492e8d8bef9SDimitry Andric       return nullptr;
493e8d8bef9SDimitry Andric 
4940b57cec5SDimitry Andric     // The shift amount may be masked with negation:
495e8d8bef9SDimitry Andric     // (shl ShVal0, (X & (Width - 1))) | (lshr ShVal1, ((-X) & (Width - 1)))
4960b57cec5SDimitry Andric     Value *X;
4970b57cec5SDimitry Andric     unsigned Mask = Width - 1;
4980b57cec5SDimitry Andric     if (match(L, m_And(m_Value(X), m_SpecificInt(Mask))) &&
4990b57cec5SDimitry Andric         match(R, m_And(m_Neg(m_Specific(X)), m_SpecificInt(Mask))))
5000b57cec5SDimitry Andric       return X;
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric     // Same as above, but the shift amount may be extended after masking:
5030b57cec5SDimitry Andric     if (match(L, m_ZExt(m_And(m_Value(X), m_SpecificInt(Mask)))) &&
5040b57cec5SDimitry Andric         match(R, m_ZExt(m_And(m_Neg(m_Specific(X)), m_SpecificInt(Mask)))))
5050b57cec5SDimitry Andric       return X;
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric     return nullptr;
5080b57cec5SDimitry Andric   };
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth);
511e8d8bef9SDimitry Andric   bool IsFshl = true; // Sub on LSHR.
5120b57cec5SDimitry Andric   if (!ShAmt) {
5130b57cec5SDimitry Andric     ShAmt = matchShiftAmount(ShAmt1, ShAmt0, NarrowWidth);
514e8d8bef9SDimitry Andric     IsFshl = false; // Sub on SHL.
5150b57cec5SDimitry Andric   }
5160b57cec5SDimitry Andric   if (!ShAmt)
5170b57cec5SDimitry Andric     return nullptr;
5180b57cec5SDimitry Andric 
519fe6060f1SDimitry Andric   // The right-shifted value must have high zeros in the wide type (for example
520fe6060f1SDimitry Andric   // from 'zext', 'and' or 'shift'). High bits of the left-shifted value are
521fe6060f1SDimitry Andric   // truncated, so those do not matter.
5220b57cec5SDimitry Andric   APInt HiBitMask = APInt::getHighBitsSet(WideWidth, WideWidth - NarrowWidth);
523fe6060f1SDimitry Andric   if (!MaskedValueIsZero(ShVal1, HiBitMask, 0, &Trunc))
5240b57cec5SDimitry Andric     return nullptr;
5250b57cec5SDimitry Andric 
5265f757f3fSDimitry Andric   // Adjust the width of ShAmt for narrowed funnel shift operation:
5275f757f3fSDimitry Andric   // - Zero-extend if ShAmt is narrower than the destination type.
5285f757f3fSDimitry Andric   // - Truncate if ShAmt is wider, discarding non-significant high-order bits.
5295f757f3fSDimitry Andric   // This prepares ShAmt for llvm.fshl.i8(trunc(ShVal), trunc(ShVal),
5305f757f3fSDimitry Andric   // zext/trunc(ShAmt)).
5315f757f3fSDimitry Andric   Value *NarrowShAmt = Builder.CreateZExtOrTrunc(ShAmt, DestTy);
5325f757f3fSDimitry Andric 
533e8d8bef9SDimitry Andric   Value *X, *Y;
534e8d8bef9SDimitry Andric   X = Y = Builder.CreateTrunc(ShVal0, DestTy);
535e8d8bef9SDimitry Andric   if (ShVal0 != ShVal1)
536e8d8bef9SDimitry Andric     Y = Builder.CreateTrunc(ShVal1, DestTy);
5370b57cec5SDimitry Andric   Intrinsic::ID IID = IsFshl ? Intrinsic::fshl : Intrinsic::fshr;
5380b57cec5SDimitry Andric   Function *F = Intrinsic::getDeclaration(Trunc.getModule(), IID, DestTy);
539fe6060f1SDimitry Andric   return CallInst::Create(F, {X, Y, NarrowShAmt});
5400b57cec5SDimitry Andric }
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric /// Try to narrow the width of math or bitwise logic instructions by pulling a
5430b57cec5SDimitry Andric /// truncate ahead of binary operators.
544e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) {
5450b57cec5SDimitry Andric   Type *SrcTy = Trunc.getSrcTy();
5460b57cec5SDimitry Andric   Type *DestTy = Trunc.getType();
54781ad6265SDimitry Andric   unsigned SrcWidth = SrcTy->getScalarSizeInBits();
54881ad6265SDimitry Andric   unsigned DestWidth = DestTy->getScalarSizeInBits();
54981ad6265SDimitry Andric 
5500b57cec5SDimitry Andric   if (!isa<VectorType>(SrcTy) && !shouldChangeType(SrcTy, DestTy))
5510b57cec5SDimitry Andric     return nullptr;
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric   BinaryOperator *BinOp;
5540b57cec5SDimitry Andric   if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(BinOp))))
5550b57cec5SDimitry Andric     return nullptr;
5560b57cec5SDimitry Andric 
5570b57cec5SDimitry Andric   Value *BinOp0 = BinOp->getOperand(0);
5580b57cec5SDimitry Andric   Value *BinOp1 = BinOp->getOperand(1);
5590b57cec5SDimitry Andric   switch (BinOp->getOpcode()) {
5600b57cec5SDimitry Andric   case Instruction::And:
5610b57cec5SDimitry Andric   case Instruction::Or:
5620b57cec5SDimitry Andric   case Instruction::Xor:
5630b57cec5SDimitry Andric   case Instruction::Add:
5640b57cec5SDimitry Andric   case Instruction::Sub:
5650b57cec5SDimitry Andric   case Instruction::Mul: {
5660b57cec5SDimitry Andric     Constant *C;
5670b57cec5SDimitry Andric     if (match(BinOp0, m_Constant(C))) {
5680b57cec5SDimitry Andric       // trunc (binop C, X) --> binop (trunc C', X)
5690b57cec5SDimitry Andric       Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
5700b57cec5SDimitry Andric       Value *TruncX = Builder.CreateTrunc(BinOp1, DestTy);
5710b57cec5SDimitry Andric       return BinaryOperator::Create(BinOp->getOpcode(), NarrowC, TruncX);
5720b57cec5SDimitry Andric     }
5730b57cec5SDimitry Andric     if (match(BinOp1, m_Constant(C))) {
5740b57cec5SDimitry Andric       // trunc (binop X, C) --> binop (trunc X, C')
5750b57cec5SDimitry Andric       Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
5760b57cec5SDimitry Andric       Value *TruncX = Builder.CreateTrunc(BinOp0, DestTy);
5770b57cec5SDimitry Andric       return BinaryOperator::Create(BinOp->getOpcode(), TruncX, NarrowC);
5780b57cec5SDimitry Andric     }
5790b57cec5SDimitry Andric     Value *X;
5800b57cec5SDimitry Andric     if (match(BinOp0, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) {
5810b57cec5SDimitry Andric       // trunc (binop (ext X), Y) --> binop X, (trunc Y)
5820b57cec5SDimitry Andric       Value *NarrowOp1 = Builder.CreateTrunc(BinOp1, DestTy);
5830b57cec5SDimitry Andric       return BinaryOperator::Create(BinOp->getOpcode(), X, NarrowOp1);
5840b57cec5SDimitry Andric     }
5850b57cec5SDimitry Andric     if (match(BinOp1, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) {
5860b57cec5SDimitry Andric       // trunc (binop Y, (ext X)) --> binop (trunc Y), X
5870b57cec5SDimitry Andric       Value *NarrowOp0 = Builder.CreateTrunc(BinOp0, DestTy);
5880b57cec5SDimitry Andric       return BinaryOperator::Create(BinOp->getOpcode(), NarrowOp0, X);
5890b57cec5SDimitry Andric     }
5900b57cec5SDimitry Andric     break;
5910b57cec5SDimitry Andric   }
59281ad6265SDimitry Andric   case Instruction::LShr:
59381ad6265SDimitry Andric   case Instruction::AShr: {
59481ad6265SDimitry Andric     // trunc (*shr (trunc A), C) --> trunc(*shr A, C)
59581ad6265SDimitry Andric     Value *A;
59681ad6265SDimitry Andric     Constant *C;
59781ad6265SDimitry Andric     if (match(BinOp0, m_Trunc(m_Value(A))) && match(BinOp1, m_Constant(C))) {
59881ad6265SDimitry Andric       unsigned MaxShiftAmt = SrcWidth - DestWidth;
59981ad6265SDimitry Andric       // If the shift is small enough, all zero/sign bits created by the shift
60081ad6265SDimitry Andric       // are removed by the trunc.
60181ad6265SDimitry Andric       if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE,
60281ad6265SDimitry Andric                                       APInt(SrcWidth, MaxShiftAmt)))) {
60381ad6265SDimitry Andric         auto *OldShift = cast<Instruction>(Trunc.getOperand(0));
60481ad6265SDimitry Andric         bool IsExact = OldShift->isExact();
6055f757f3fSDimitry Andric         if (Constant *ShAmt = ConstantFoldIntegerCast(C, A->getType(),
6065f757f3fSDimitry Andric                                                       /*IsSigned*/ true, DL)) {
60781ad6265SDimitry Andric           ShAmt = Constant::mergeUndefsWith(ShAmt, C);
60881ad6265SDimitry Andric           Value *Shift =
60981ad6265SDimitry Andric               OldShift->getOpcode() == Instruction::AShr
61081ad6265SDimitry Andric                   ? Builder.CreateAShr(A, ShAmt, OldShift->getName(), IsExact)
61181ad6265SDimitry Andric                   : Builder.CreateLShr(A, ShAmt, OldShift->getName(), IsExact);
61281ad6265SDimitry Andric           return CastInst::CreateTruncOrBitCast(Shift, DestTy);
61381ad6265SDimitry Andric         }
61481ad6265SDimitry Andric       }
6155f757f3fSDimitry Andric     }
61681ad6265SDimitry Andric     break;
61781ad6265SDimitry Andric   }
6180b57cec5SDimitry Andric   default: break;
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric 
621e8d8bef9SDimitry Andric   if (Instruction *NarrowOr = narrowFunnelShift(Trunc))
6220b57cec5SDimitry Andric     return NarrowOr;
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric   return nullptr;
6250b57cec5SDimitry Andric }
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric /// Try to narrow the width of a splat shuffle. This could be generalized to any
6280b57cec5SDimitry Andric /// shuffle with a constant operand, but we limit the transform to avoid
6290b57cec5SDimitry Andric /// creating a shuffle type that targets may not be able to lower effectively.
6300b57cec5SDimitry Andric static Instruction *shrinkSplatShuffle(TruncInst &Trunc,
6310b57cec5SDimitry Andric                                        InstCombiner::BuilderTy &Builder) {
6320b57cec5SDimitry Andric   auto *Shuf = dyn_cast<ShuffleVectorInst>(Trunc.getOperand(0));
633fe6060f1SDimitry Andric   if (Shuf && Shuf->hasOneUse() && match(Shuf->getOperand(1), m_Undef()) &&
634bdd1243dSDimitry Andric       all_equal(Shuf->getShuffleMask()) &&
6350b57cec5SDimitry Andric       Shuf->getType() == Shuf->getOperand(0)->getType()) {
636349cc55cSDimitry Andric     // trunc (shuf X, Undef, SplatMask) --> shuf (trunc X), Poison, SplatMask
637349cc55cSDimitry Andric     // trunc (shuf X, Poison, SplatMask) --> shuf (trunc X), Poison, SplatMask
6380b57cec5SDimitry Andric     Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), Trunc.getType());
639349cc55cSDimitry Andric     return new ShuffleVectorInst(NarrowOp, Shuf->getShuffleMask());
6400b57cec5SDimitry Andric   }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   return nullptr;
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric /// Try to narrow the width of an insert element. This could be generalized for
6460b57cec5SDimitry Andric /// any vector constant, but we limit the transform to insertion into undef to
6470b57cec5SDimitry Andric /// avoid potential backend problems from unsupported insertion widths. This
6480b57cec5SDimitry Andric /// could also be extended to handle the case of inserting a scalar constant
6490b57cec5SDimitry Andric /// into a vector variable.
6500b57cec5SDimitry Andric static Instruction *shrinkInsertElt(CastInst &Trunc,
6510b57cec5SDimitry Andric                                     InstCombiner::BuilderTy &Builder) {
6520b57cec5SDimitry Andric   Instruction::CastOps Opcode = Trunc.getOpcode();
6530b57cec5SDimitry Andric   assert((Opcode == Instruction::Trunc || Opcode == Instruction::FPTrunc) &&
6540b57cec5SDimitry Andric          "Unexpected instruction for shrinking");
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   auto *InsElt = dyn_cast<InsertElementInst>(Trunc.getOperand(0));
6570b57cec5SDimitry Andric   if (!InsElt || !InsElt->hasOneUse())
6580b57cec5SDimitry Andric     return nullptr;
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   Type *DestTy = Trunc.getType();
6610b57cec5SDimitry Andric   Type *DestScalarTy = DestTy->getScalarType();
6620b57cec5SDimitry Andric   Value *VecOp = InsElt->getOperand(0);
6630b57cec5SDimitry Andric   Value *ScalarOp = InsElt->getOperand(1);
6640b57cec5SDimitry Andric   Value *Index = InsElt->getOperand(2);
6650b57cec5SDimitry Andric 
666fe6060f1SDimitry Andric   if (match(VecOp, m_Undef())) {
6670b57cec5SDimitry Andric     // trunc   (inselt undef, X, Index) --> inselt undef,   (trunc X), Index
6680b57cec5SDimitry Andric     // fptrunc (inselt undef, X, Index) --> inselt undef, (fptrunc X), Index
6690b57cec5SDimitry Andric     UndefValue *NarrowUndef = UndefValue::get(DestTy);
6700b57cec5SDimitry Andric     Value *NarrowOp = Builder.CreateCast(Opcode, ScalarOp, DestScalarTy);
6710b57cec5SDimitry Andric     return InsertElementInst::Create(NarrowUndef, NarrowOp, Index);
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   return nullptr;
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
677e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
6785ffd83dbSDimitry Andric   if (Instruction *Result = commonCastTransforms(Trunc))
6790b57cec5SDimitry Andric     return Result;
6800b57cec5SDimitry Andric 
6815ffd83dbSDimitry Andric   Value *Src = Trunc.getOperand(0);
6825ffd83dbSDimitry Andric   Type *DestTy = Trunc.getType(), *SrcTy = Src->getType();
6835ffd83dbSDimitry Andric   unsigned DestWidth = DestTy->getScalarSizeInBits();
6845ffd83dbSDimitry Andric   unsigned SrcWidth = SrcTy->getScalarSizeInBits();
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric   // Attempt to truncate the entire input expression tree to the destination
6870b57cec5SDimitry Andric   // type.   Only do this if the dest type is a simple type, don't convert the
6880b57cec5SDimitry Andric   // expression tree to something weird like i93 unless the source is also
6890b57cec5SDimitry Andric   // strange.
6900b57cec5SDimitry Andric   if ((DestTy->isVectorTy() || shouldChangeType(SrcTy, DestTy)) &&
6915ffd83dbSDimitry Andric       canEvaluateTruncated(Src, DestTy, *this, &Trunc)) {
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric     // If this cast is a truncate, evaluting in a different type always
6940b57cec5SDimitry Andric     // eliminates the cast, so it is always a win.
6950b57cec5SDimitry Andric     LLVM_DEBUG(
6960b57cec5SDimitry Andric         dbgs() << "ICE: EvaluateInDifferentType converting expression type"
6970b57cec5SDimitry Andric                   " to avoid cast: "
6985ffd83dbSDimitry Andric                << Trunc << '\n');
6990b57cec5SDimitry Andric     Value *Res = EvaluateInDifferentType(Src, DestTy, false);
7000b57cec5SDimitry Andric     assert(Res->getType() == DestTy);
7015ffd83dbSDimitry Andric     return replaceInstUsesWith(Trunc, Res);
7025ffd83dbSDimitry Andric   }
7035ffd83dbSDimitry Andric 
7045ffd83dbSDimitry Andric   // For integer types, check if we can shorten the entire input expression to
7055ffd83dbSDimitry Andric   // DestWidth * 2, which won't allow removing the truncate, but reducing the
7065ffd83dbSDimitry Andric   // width may enable further optimizations, e.g. allowing for larger
7075ffd83dbSDimitry Andric   // vectorization factors.
7085ffd83dbSDimitry Andric   if (auto *DestITy = dyn_cast<IntegerType>(DestTy)) {
7095ffd83dbSDimitry Andric     if (DestWidth * 2 < SrcWidth) {
7105ffd83dbSDimitry Andric       auto *NewDestTy = DestITy->getExtendedType();
7115ffd83dbSDimitry Andric       if (shouldChangeType(SrcTy, NewDestTy) &&
7125ffd83dbSDimitry Andric           canEvaluateTruncated(Src, NewDestTy, *this, &Trunc)) {
7135ffd83dbSDimitry Andric         LLVM_DEBUG(
7145ffd83dbSDimitry Andric             dbgs() << "ICE: EvaluateInDifferentType converting expression type"
7155ffd83dbSDimitry Andric                       " to reduce the width of operand of"
7165ffd83dbSDimitry Andric                    << Trunc << '\n');
7175ffd83dbSDimitry Andric         Value *Res = EvaluateInDifferentType(Src, NewDestTy, false);
7185ffd83dbSDimitry Andric         return new TruncInst(Res, DestTy);
7195ffd83dbSDimitry Andric       }
7205ffd83dbSDimitry Andric     }
7210b57cec5SDimitry Andric   }
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   // Test if the trunc is the user of a select which is part of a
7240b57cec5SDimitry Andric   // minimum or maximum operation. If so, don't do any more simplification.
7250b57cec5SDimitry Andric   // Even simplifying demanded bits can break the canonical form of a
7260b57cec5SDimitry Andric   // min/max.
7270b57cec5SDimitry Andric   Value *LHS, *RHS;
7285ffd83dbSDimitry Andric   if (SelectInst *Sel = dyn_cast<SelectInst>(Src))
7295ffd83dbSDimitry Andric     if (matchSelectPattern(Sel, LHS, RHS).Flavor != SPF_UNKNOWN)
7300b57cec5SDimitry Andric       return nullptr;
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric   // See if we can simplify any instructions used by the input whose sole
7330b57cec5SDimitry Andric   // purpose is to compute bits we don't care about.
7345ffd83dbSDimitry Andric   if (SimplifyDemandedInstructionBits(Trunc))
7355ffd83dbSDimitry Andric     return &Trunc;
7360b57cec5SDimitry Andric 
7375ffd83dbSDimitry Andric   if (DestWidth == 1) {
7385ffd83dbSDimitry Andric     Value *Zero = Constant::getNullValue(SrcTy);
739*0fca6ea1SDimitry Andric 
740*0fca6ea1SDimitry Andric     Value *X;
741*0fca6ea1SDimitry Andric     const APInt *C1;
742*0fca6ea1SDimitry Andric     Constant *C2;
743*0fca6ea1SDimitry Andric     if (match(Src, m_OneUse(m_Shr(m_Shl(m_Power2(C1), m_Value(X)),
744*0fca6ea1SDimitry Andric                                   m_ImmConstant(C2))))) {
745*0fca6ea1SDimitry Andric       // trunc ((C1 << X) >> C2) to i1 --> X == (C2-cttz(C1)), where C1 is pow2
746*0fca6ea1SDimitry Andric       Constant *Log2C1 = ConstantInt::get(SrcTy, C1->exactLogBase2());
747*0fca6ea1SDimitry Andric       Constant *CmpC = ConstantExpr::getSub(C2, Log2C1);
748*0fca6ea1SDimitry Andric       return new ICmpInst(ICmpInst::ICMP_EQ, X, CmpC);
7490b57cec5SDimitry Andric     }
7500b57cec5SDimitry Andric 
7515ffd83dbSDimitry Andric     Constant *C;
752*0fca6ea1SDimitry Andric     if (match(Src, m_OneUse(m_LShr(m_Value(X), m_ImmConstant(C))))) {
7530b57cec5SDimitry Andric       // trunc (lshr X, C) to i1 --> icmp ne (and X, C'), 0
7545ffd83dbSDimitry Andric       Constant *One = ConstantInt::get(SrcTy, APInt(SrcWidth, 1));
755*0fca6ea1SDimitry Andric       Value *MaskC = Builder.CreateShl(One, C);
7565ffd83dbSDimitry Andric       Value *And = Builder.CreateAnd(X, MaskC);
7570b57cec5SDimitry Andric       return new ICmpInst(ICmpInst::ICMP_NE, And, Zero);
7580b57cec5SDimitry Andric     }
75906c3fb27SDimitry Andric     if (match(Src, m_OneUse(m_c_Or(m_LShr(m_Value(X), m_ImmConstant(C)),
7600b57cec5SDimitry Andric                                    m_Deferred(X))))) {
7610b57cec5SDimitry Andric       // trunc (or (lshr X, C), X) to i1 --> icmp ne (and X, C'), 0
7625ffd83dbSDimitry Andric       Constant *One = ConstantInt::get(SrcTy, APInt(SrcWidth, 1));
763*0fca6ea1SDimitry Andric       Value *MaskC = Builder.CreateShl(One, C);
76406c3fb27SDimitry Andric       Value *And = Builder.CreateAnd(X, Builder.CreateOr(MaskC, One));
7650b57cec5SDimitry Andric       return new ICmpInst(ICmpInst::ICMP_NE, And, Zero);
7660b57cec5SDimitry Andric     }
767*0fca6ea1SDimitry Andric 
768*0fca6ea1SDimitry Andric     {
769*0fca6ea1SDimitry Andric       const APInt *C;
770*0fca6ea1SDimitry Andric       if (match(Src, m_Shl(m_APInt(C), m_Value(X))) && (*C)[0] == 1) {
771*0fca6ea1SDimitry Andric         // trunc (C << X) to i1 --> X == 0, where C is odd
772*0fca6ea1SDimitry Andric         return new ICmpInst(ICmpInst::Predicate::ICMP_EQ, X, Zero);
773*0fca6ea1SDimitry Andric       }
774*0fca6ea1SDimitry Andric     }
775*0fca6ea1SDimitry Andric 
776*0fca6ea1SDimitry Andric     if (Trunc.hasNoUnsignedWrap() || Trunc.hasNoSignedWrap()) {
777*0fca6ea1SDimitry Andric       Value *X, *Y;
778*0fca6ea1SDimitry Andric       if (match(Src, m_Xor(m_Value(X), m_Value(Y))))
779*0fca6ea1SDimitry Andric         return new ICmpInst(ICmpInst::ICMP_NE, X, Y);
780*0fca6ea1SDimitry Andric     }
7810b57cec5SDimitry Andric   }
7820b57cec5SDimitry Andric 
783fe6060f1SDimitry Andric   Value *A, *B;
784e8d8bef9SDimitry Andric   Constant *C;
785e8d8bef9SDimitry Andric   if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) {
7865ffd83dbSDimitry Andric     unsigned AWidth = A->getType()->getScalarSizeInBits();
7875ffd83dbSDimitry Andric     unsigned MaxShiftAmt = SrcWidth - std::max(DestWidth, AWidth);
788e8d8bef9SDimitry Andric     auto *OldSh = cast<Instruction>(Src);
789e8d8bef9SDimitry Andric     bool IsExact = OldSh->isExact();
7900b57cec5SDimitry Andric 
7915ffd83dbSDimitry Andric     // If the shift is small enough, all zero bits created by the shift are
7925ffd83dbSDimitry Andric     // removed by the trunc.
793e8d8bef9SDimitry Andric     if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULE,
794e8d8bef9SDimitry Andric                                     APInt(SrcWidth, MaxShiftAmt)))) {
79506c3fb27SDimitry Andric       auto GetNewShAmt = [&](unsigned Width) {
79606c3fb27SDimitry Andric         Constant *MaxAmt = ConstantInt::get(SrcTy, Width - 1, false);
79706c3fb27SDimitry Andric         Constant *Cmp =
79806c3fb27SDimitry Andric             ConstantFoldCompareInstOperands(ICmpInst::ICMP_ULT, C, MaxAmt, DL);
79906c3fb27SDimitry Andric         Constant *ShAmt = ConstantFoldSelectInstruction(Cmp, C, MaxAmt);
80006c3fb27SDimitry Andric         return ConstantFoldCastOperand(Instruction::Trunc, ShAmt, A->getType(),
80106c3fb27SDimitry Andric                                        DL);
80206c3fb27SDimitry Andric       };
80306c3fb27SDimitry Andric 
8045ffd83dbSDimitry Andric       // trunc (lshr (sext A), C) --> ashr A, C
8055ffd83dbSDimitry Andric       if (A->getType() == DestTy) {
80606c3fb27SDimitry Andric         Constant *ShAmt = GetNewShAmt(DestWidth);
807e8d8bef9SDimitry Andric         ShAmt = Constant::mergeUndefsWith(ShAmt, C);
808e8d8bef9SDimitry Andric         return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt)
809e8d8bef9SDimitry Andric                        : BinaryOperator::CreateAShr(A, ShAmt);
8105ffd83dbSDimitry Andric       }
8115ffd83dbSDimitry Andric       // The types are mismatched, so create a cast after shifting:
8125ffd83dbSDimitry Andric       // trunc (lshr (sext A), C) --> sext/trunc (ashr A, C)
8135ffd83dbSDimitry Andric       if (Src->hasOneUse()) {
81406c3fb27SDimitry Andric         Constant *ShAmt = GetNewShAmt(AWidth);
815e8d8bef9SDimitry Andric         Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact);
8165ffd83dbSDimitry Andric         return CastInst::CreateIntegerCast(Shift, DestTy, true);
8170b57cec5SDimitry Andric       }
8180b57cec5SDimitry Andric     }
8195ffd83dbSDimitry Andric     // TODO: Mask high bits with 'and'.
8200b57cec5SDimitry Andric   }
8210b57cec5SDimitry Andric 
8225ffd83dbSDimitry Andric   if (Instruction *I = narrowBinOp(Trunc))
8230b57cec5SDimitry Andric     return I;
8240b57cec5SDimitry Andric 
8255ffd83dbSDimitry Andric   if (Instruction *I = shrinkSplatShuffle(Trunc, Builder))
8260b57cec5SDimitry Andric     return I;
8270b57cec5SDimitry Andric 
8285ffd83dbSDimitry Andric   if (Instruction *I = shrinkInsertElt(Trunc, Builder))
8290b57cec5SDimitry Andric     return I;
8300b57cec5SDimitry Andric 
831e8d8bef9SDimitry Andric   if (Src->hasOneUse() &&
832e8d8bef9SDimitry Andric       (isa<VectorType>(SrcTy) || shouldChangeType(SrcTy, DestTy))) {
8330b57cec5SDimitry Andric     // Transform "trunc (shl X, cst)" -> "shl (trunc X), cst" so long as the
8340b57cec5SDimitry Andric     // dest type is native and cst < dest size.
835e8d8bef9SDimitry Andric     if (match(Src, m_Shl(m_Value(A), m_Constant(C))) &&
8360b57cec5SDimitry Andric         !match(A, m_Shr(m_Value(), m_Constant()))) {
8370b57cec5SDimitry Andric       // Skip shifts of shift by constants. It undoes a combine in
8380b57cec5SDimitry Andric       // FoldShiftByConstant and is the extend in reg pattern.
839e8d8bef9SDimitry Andric       APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
840e8d8bef9SDimitry Andric       if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) {
8410b57cec5SDimitry Andric         Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr");
842e8d8bef9SDimitry Andric         return BinaryOperator::Create(Instruction::Shl, NewTrunc,
843e8d8bef9SDimitry Andric                                       ConstantExpr::getTrunc(C, DestTy));
8440b57cec5SDimitry Andric       }
8450b57cec5SDimitry Andric     }
8460b57cec5SDimitry Andric   }
8470b57cec5SDimitry Andric 
8485ffd83dbSDimitry Andric   if (Instruction *I = foldVecTruncToExtElt(Trunc, *this))
8490b57cec5SDimitry Andric     return I;
8500b57cec5SDimitry Andric 
8515ffd83dbSDimitry Andric   // Whenever an element is extracted from a vector, and then truncated,
8525ffd83dbSDimitry Andric   // canonicalize by converting it to a bitcast followed by an
8535ffd83dbSDimitry Andric   // extractelement.
8545ffd83dbSDimitry Andric   //
8555ffd83dbSDimitry Andric   // Example (little endian):
8565ffd83dbSDimitry Andric   //   trunc (extractelement <4 x i64> %X, 0) to i32
8575ffd83dbSDimitry Andric   //   --->
8585ffd83dbSDimitry Andric   //   extractelement <8 x i32> (bitcast <4 x i64> %X to <8 x i32>), i32 0
8595ffd83dbSDimitry Andric   Value *VecOp;
860e8d8bef9SDimitry Andric   ConstantInt *Cst;
8615ffd83dbSDimitry Andric   if (match(Src, m_OneUse(m_ExtractElt(m_Value(VecOp), m_ConstantInt(Cst))))) {
8625ffd83dbSDimitry Andric     auto *VecOpTy = cast<VectorType>(VecOp->getType());
863e8d8bef9SDimitry Andric     auto VecElts = VecOpTy->getElementCount();
8645ffd83dbSDimitry Andric 
8655ffd83dbSDimitry Andric     // A badly fit destination size would result in an invalid cast.
8665ffd83dbSDimitry Andric     if (SrcWidth % DestWidth == 0) {
8675ffd83dbSDimitry Andric       uint64_t TruncRatio = SrcWidth / DestWidth;
868e8d8bef9SDimitry Andric       uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio;
8695ffd83dbSDimitry Andric       uint64_t VecOpIdx = Cst->getZExtValue();
8705ffd83dbSDimitry Andric       uint64_t NewIdx = DL.isBigEndian() ? (VecOpIdx + 1) * TruncRatio - 1
8715ffd83dbSDimitry Andric                                          : VecOpIdx * TruncRatio;
8725ffd83dbSDimitry Andric       assert(BitCastNumElts <= std::numeric_limits<uint32_t>::max() &&
8735ffd83dbSDimitry Andric              "overflow 32-bits");
8745ffd83dbSDimitry Andric 
875e8d8bef9SDimitry Andric       auto *BitCastTo =
876e8d8bef9SDimitry Andric           VectorType::get(DestTy, BitCastNumElts, VecElts.isScalable());
8775ffd83dbSDimitry Andric       Value *BitCast = Builder.CreateBitCast(VecOp, BitCastTo);
8785ffd83dbSDimitry Andric       return ExtractElementInst::Create(BitCast, Builder.getInt32(NewIdx));
8795ffd83dbSDimitry Andric     }
8805ffd83dbSDimitry Andric   }
8815ffd83dbSDimitry Andric 
882fe6060f1SDimitry Andric   // trunc (ctlz_i32(zext(A), B) --> add(ctlz_i16(A, B), C)
883fe6060f1SDimitry Andric   if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ctlz>(m_ZExt(m_Value(A)),
884fe6060f1SDimitry Andric                                                        m_Value(B))))) {
885fe6060f1SDimitry Andric     unsigned AWidth = A->getType()->getScalarSizeInBits();
886fe6060f1SDimitry Andric     if (AWidth == DestWidth && AWidth > Log2_32(SrcWidth)) {
887fe6060f1SDimitry Andric       Value *WidthDiff = ConstantInt::get(A->getType(), SrcWidth - AWidth);
888fe6060f1SDimitry Andric       Value *NarrowCtlz =
889fe6060f1SDimitry Andric           Builder.CreateIntrinsic(Intrinsic::ctlz, {Trunc.getType()}, {A, B});
890fe6060f1SDimitry Andric       return BinaryOperator::CreateAdd(NarrowCtlz, WidthDiff);
891fe6060f1SDimitry Andric     }
892fe6060f1SDimitry Andric   }
893349cc55cSDimitry Andric 
89406c3fb27SDimitry Andric   if (match(Src, m_VScale())) {
895349cc55cSDimitry Andric     if (Trunc.getFunction() &&
896349cc55cSDimitry Andric         Trunc.getFunction()->hasFnAttribute(Attribute::VScaleRange)) {
8970eae32dcSDimitry Andric       Attribute Attr =
8980eae32dcSDimitry Andric           Trunc.getFunction()->getFnAttribute(Attribute::VScaleRange);
899bdd1243dSDimitry Andric       if (std::optional<unsigned> MaxVScale = Attr.getVScaleRangeMax()) {
90081ad6265SDimitry Andric         if (Log2_32(*MaxVScale) < DestWidth) {
901349cc55cSDimitry Andric           Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
902349cc55cSDimitry Andric           return replaceInstUsesWith(Trunc, VScale);
903349cc55cSDimitry Andric         }
904349cc55cSDimitry Andric       }
905349cc55cSDimitry Andric     }
9060eae32dcSDimitry Andric   }
907349cc55cSDimitry Andric 
908*0fca6ea1SDimitry Andric   bool Changed = false;
909*0fca6ea1SDimitry Andric   if (!Trunc.hasNoSignedWrap() &&
910*0fca6ea1SDimitry Andric       ComputeMaxSignificantBits(Src, /*Depth=*/0, &Trunc) <= DestWidth) {
911*0fca6ea1SDimitry Andric     Trunc.setHasNoSignedWrap(true);
912*0fca6ea1SDimitry Andric     Changed = true;
913*0fca6ea1SDimitry Andric   }
914*0fca6ea1SDimitry Andric   if (!Trunc.hasNoUnsignedWrap() &&
915*0fca6ea1SDimitry Andric       MaskedValueIsZero(Src, APInt::getBitsSetFrom(SrcWidth, DestWidth),
916*0fca6ea1SDimitry Andric                         /*Depth=*/0, &Trunc)) {
917*0fca6ea1SDimitry Andric     Trunc.setHasNoUnsignedWrap(true);
918*0fca6ea1SDimitry Andric     Changed = true;
919*0fca6ea1SDimitry Andric   }
920*0fca6ea1SDimitry Andric 
921*0fca6ea1SDimitry Andric   return Changed ? &Trunc : nullptr;
9220b57cec5SDimitry Andric }
9230b57cec5SDimitry Andric 
924bdd1243dSDimitry Andric Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp,
925bdd1243dSDimitry Andric                                                  ZExtInst &Zext) {
9260b57cec5SDimitry Andric   // If we are just checking for a icmp eq of a single bit and zext'ing it
9270b57cec5SDimitry Andric   // to an integer, then shift the bit to the appropriate place and then
9280b57cec5SDimitry Andric   // cast to integer to avoid the comparison.
92981ad6265SDimitry Andric 
93081ad6265SDimitry Andric   // FIXME: This set of transforms does not check for extra uses and/or creates
93181ad6265SDimitry Andric   //        an extra instruction (an optional final cast is not included
93281ad6265SDimitry Andric   //        in the transform comments). We may also want to favor icmp over
93381ad6265SDimitry Andric   //        shifts in cases of equal instructions because icmp has better
93481ad6265SDimitry Andric   //        analysis in general (invert the transform).
93581ad6265SDimitry Andric 
9360b57cec5SDimitry Andric   const APInt *Op1CV;
937480093f4SDimitry Andric   if (match(Cmp->getOperand(1), m_APInt(Op1CV))) {
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric     // zext (x <s  0) to i32 --> x>>u31      true if signbit set.
94081ad6265SDimitry Andric     if (Cmp->getPredicate() == ICmpInst::ICMP_SLT && Op1CV->isZero()) {
941480093f4SDimitry Andric       Value *In = Cmp->getOperand(0);
9420b57cec5SDimitry Andric       Value *Sh = ConstantInt::get(In->getType(),
9430b57cec5SDimitry Andric                                    In->getType()->getScalarSizeInBits() - 1);
9440b57cec5SDimitry Andric       In = Builder.CreateLShr(In, Sh, In->getName() + ".lobit");
945480093f4SDimitry Andric       if (In->getType() != Zext.getType())
946480093f4SDimitry Andric         In = Builder.CreateIntCast(In, Zext.getType(), false /*ZExt*/);
9470b57cec5SDimitry Andric 
948480093f4SDimitry Andric       return replaceInstUsesWith(Zext, In);
9490b57cec5SDimitry Andric     }
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric     // zext (X == 0) to i32 --> X^1      iff X has only the low bit set.
9520b57cec5SDimitry Andric     // zext (X == 0) to i32 --> (X>>1)^1 iff X has only the 2nd bit set.
9530b57cec5SDimitry Andric     // zext (X != 0) to i32 --> X        iff X has only the low bit set.
9540b57cec5SDimitry Andric     // zext (X != 0) to i32 --> X>>1     iff X has only the 2nd bit set.
9550b57cec5SDimitry Andric 
9565f757f3fSDimitry Andric     if (Op1CV->isZero() && Cmp->isEquality()) {
957bdd1243dSDimitry Andric       // Exactly 1 possible 1? But not the high-bit because that is
958bdd1243dSDimitry Andric       // canonicalized to this form.
9595f757f3fSDimitry Andric       KnownBits Known = computeKnownBits(Cmp->getOperand(0), 0, &Zext);
9600b57cec5SDimitry Andric       APInt KnownZeroMask(~Known.Zero);
9610b57cec5SDimitry Andric       uint32_t ShAmt = KnownZeroMask.logBase2();
9625f757f3fSDimitry Andric       bool IsExpectShAmt = KnownZeroMask.isPowerOf2() &&
9635f757f3fSDimitry Andric                            (Zext.getType()->getScalarSizeInBits() != ShAmt + 1);
9645f757f3fSDimitry Andric       if (IsExpectShAmt &&
9655f757f3fSDimitry Andric           (Cmp->getOperand(0)->getType() == Zext.getType() ||
9665f757f3fSDimitry Andric            Cmp->getPredicate() == ICmpInst::ICMP_NE || ShAmt == 0)) {
967480093f4SDimitry Andric         Value *In = Cmp->getOperand(0);
9680b57cec5SDimitry Andric         if (ShAmt) {
9690b57cec5SDimitry Andric           // Perform a logical shr by shiftamt.
9700b57cec5SDimitry Andric           // Insert the shift to put the result in the low bit.
9710b57cec5SDimitry Andric           In = Builder.CreateLShr(In, ConstantInt::get(In->getType(), ShAmt),
9720b57cec5SDimitry Andric                                   In->getName() + ".lobit");
9730b57cec5SDimitry Andric         }
9740b57cec5SDimitry Andric 
975bdd1243dSDimitry Andric         // Toggle the low bit for "X == 0".
976bdd1243dSDimitry Andric         if (Cmp->getPredicate() == ICmpInst::ICMP_EQ)
977bdd1243dSDimitry Andric           In = Builder.CreateXor(In, ConstantInt::get(In->getType(), 1));
9780b57cec5SDimitry Andric 
979480093f4SDimitry Andric         if (Zext.getType() == In->getType())
980480093f4SDimitry Andric           return replaceInstUsesWith(Zext, In);
9810b57cec5SDimitry Andric 
982480093f4SDimitry Andric         Value *IntCast = Builder.CreateIntCast(In, Zext.getType(), false);
983480093f4SDimitry Andric         return replaceInstUsesWith(Zext, IntCast);
9840b57cec5SDimitry Andric       }
9850b57cec5SDimitry Andric     }
9860b57cec5SDimitry Andric   }
9870b57cec5SDimitry Andric 
988480093f4SDimitry Andric   if (Cmp->isEquality() && Zext.getType() == Cmp->getOperand(0)->getType()) {
989fe6060f1SDimitry Andric     // Test if a bit is clear/set using a shifted-one mask:
990fe6060f1SDimitry Andric     // zext (icmp eq (and X, (1 << ShAmt)), 0) --> and (lshr (not X), ShAmt), 1
991fe6060f1SDimitry Andric     // zext (icmp ne (and X, (1 << ShAmt)), 0) --> and (lshr X, ShAmt), 1
992fe6060f1SDimitry Andric     Value *X, *ShAmt;
993fe6060f1SDimitry Andric     if (Cmp->hasOneUse() && match(Cmp->getOperand(1), m_ZeroInt()) &&
994fe6060f1SDimitry Andric         match(Cmp->getOperand(0),
995fe6060f1SDimitry Andric               m_OneUse(m_c_And(m_Shl(m_One(), m_Value(ShAmt)), m_Value(X))))) {
996fe6060f1SDimitry Andric       if (Cmp->getPredicate() == ICmpInst::ICMP_EQ)
997fe6060f1SDimitry Andric         X = Builder.CreateNot(X);
998fe6060f1SDimitry Andric       Value *Lshr = Builder.CreateLShr(X, ShAmt);
999fe6060f1SDimitry Andric       Value *And1 = Builder.CreateAnd(Lshr, ConstantInt::get(X->getType(), 1));
1000fe6060f1SDimitry Andric       return replaceInstUsesWith(Zext, And1);
1001fe6060f1SDimitry Andric     }
10020b57cec5SDimitry Andric   }
10030b57cec5SDimitry Andric 
10040b57cec5SDimitry Andric   return nullptr;
10050b57cec5SDimitry Andric }
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric /// Determine if the specified value can be computed in the specified wider type
10080b57cec5SDimitry Andric /// and produce the same low bits. If not, return false.
10090b57cec5SDimitry Andric ///
10100b57cec5SDimitry Andric /// If this function returns true, it can also return a non-zero number of bits
10110b57cec5SDimitry Andric /// (in BitsToClear) which indicates that the value it computes is correct for
10120b57cec5SDimitry Andric /// the zero extend, but that the additional BitsToClear bits need to be zero'd
10130b57cec5SDimitry Andric /// out.  For example, to promote something like:
10140b57cec5SDimitry Andric ///
10150b57cec5SDimitry Andric ///   %B = trunc i64 %A to i32
10160b57cec5SDimitry Andric ///   %C = lshr i32 %B, 8
10170b57cec5SDimitry Andric ///   %E = zext i32 %C to i64
10180b57cec5SDimitry Andric ///
10190b57cec5SDimitry Andric /// CanEvaluateZExtd for the 'lshr' will return true, and BitsToClear will be
10200b57cec5SDimitry Andric /// set to 8 to indicate that the promoted value needs to have bits 24-31
10210b57cec5SDimitry Andric /// cleared in addition to bits 32-63.  Since an 'and' will be generated to
10220b57cec5SDimitry Andric /// clear the top bits anyway, doing this has no extra cost.
10230b57cec5SDimitry Andric ///
10240b57cec5SDimitry Andric /// This function works on both vectors and scalars.
10250b57cec5SDimitry Andric static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear,
1026e8d8bef9SDimitry Andric                              InstCombinerImpl &IC, Instruction *CxtI) {
10270b57cec5SDimitry Andric   BitsToClear = 0;
10280b57cec5SDimitry Andric   if (canAlwaysEvaluateInType(V, Ty))
10290b57cec5SDimitry Andric     return true;
10300b57cec5SDimitry Andric   if (canNotEvaluateInType(V, Ty))
10310b57cec5SDimitry Andric     return false;
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric   auto *I = cast<Instruction>(V);
10340b57cec5SDimitry Andric   unsigned Tmp;
10350b57cec5SDimitry Andric   switch (I->getOpcode()) {
10360b57cec5SDimitry Andric   case Instruction::ZExt:  // zext(zext(x)) -> zext(x).
10370b57cec5SDimitry Andric   case Instruction::SExt:  // zext(sext(x)) -> sext(x).
10380b57cec5SDimitry Andric   case Instruction::Trunc: // zext(trunc(x)) -> trunc(x) or zext(x)
10390b57cec5SDimitry Andric     return true;
10400b57cec5SDimitry Andric   case Instruction::And:
10410b57cec5SDimitry Andric   case Instruction::Or:
10420b57cec5SDimitry Andric   case Instruction::Xor:
10430b57cec5SDimitry Andric   case Instruction::Add:
10440b57cec5SDimitry Andric   case Instruction::Sub:
10450b57cec5SDimitry Andric   case Instruction::Mul:
10460b57cec5SDimitry Andric     if (!canEvaluateZExtd(I->getOperand(0), Ty, BitsToClear, IC, CxtI) ||
10470b57cec5SDimitry Andric         !canEvaluateZExtd(I->getOperand(1), Ty, Tmp, IC, CxtI))
10480b57cec5SDimitry Andric       return false;
10490b57cec5SDimitry Andric     // These can all be promoted if neither operand has 'bits to clear'.
10500b57cec5SDimitry Andric     if (BitsToClear == 0 && Tmp == 0)
10510b57cec5SDimitry Andric       return true;
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric     // If the operation is an AND/OR/XOR and the bits to clear are zero in the
10540b57cec5SDimitry Andric     // other side, BitsToClear is ok.
10550b57cec5SDimitry Andric     if (Tmp == 0 && I->isBitwiseLogicOp()) {
10560b57cec5SDimitry Andric       // We use MaskedValueIsZero here for generality, but the case we care
10570b57cec5SDimitry Andric       // about the most is constant RHS.
10580b57cec5SDimitry Andric       unsigned VSize = V->getType()->getScalarSizeInBits();
10590b57cec5SDimitry Andric       if (IC.MaskedValueIsZero(I->getOperand(1),
10600b57cec5SDimitry Andric                                APInt::getHighBitsSet(VSize, BitsToClear),
10610b57cec5SDimitry Andric                                0, CxtI)) {
10620b57cec5SDimitry Andric         // If this is an And instruction and all of the BitsToClear are
10630b57cec5SDimitry Andric         // known to be zero we can reset BitsToClear.
10640b57cec5SDimitry Andric         if (I->getOpcode() == Instruction::And)
10650b57cec5SDimitry Andric           BitsToClear = 0;
10660b57cec5SDimitry Andric         return true;
10670b57cec5SDimitry Andric       }
10680b57cec5SDimitry Andric     }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric     // Otherwise, we don't know how to analyze this BitsToClear case yet.
10710b57cec5SDimitry Andric     return false;
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric   case Instruction::Shl: {
10740b57cec5SDimitry Andric     // We can promote shl(x, cst) if we can promote x.  Since shl overwrites the
10750b57cec5SDimitry Andric     // upper bits we can reduce BitsToClear by the shift amount.
10760b57cec5SDimitry Andric     const APInt *Amt;
10770b57cec5SDimitry Andric     if (match(I->getOperand(1), m_APInt(Amt))) {
10780b57cec5SDimitry Andric       if (!canEvaluateZExtd(I->getOperand(0), Ty, BitsToClear, IC, CxtI))
10790b57cec5SDimitry Andric         return false;
10800b57cec5SDimitry Andric       uint64_t ShiftAmt = Amt->getZExtValue();
10810b57cec5SDimitry Andric       BitsToClear = ShiftAmt < BitsToClear ? BitsToClear - ShiftAmt : 0;
10820b57cec5SDimitry Andric       return true;
10830b57cec5SDimitry Andric     }
10840b57cec5SDimitry Andric     return false;
10850b57cec5SDimitry Andric   }
10860b57cec5SDimitry Andric   case Instruction::LShr: {
10870b57cec5SDimitry Andric     // We can promote lshr(x, cst) if we can promote x.  This requires the
10880b57cec5SDimitry Andric     // ultimate 'and' to clear out the high zero bits we're clearing out though.
10890b57cec5SDimitry Andric     const APInt *Amt;
10900b57cec5SDimitry Andric     if (match(I->getOperand(1), m_APInt(Amt))) {
10910b57cec5SDimitry Andric       if (!canEvaluateZExtd(I->getOperand(0), Ty, BitsToClear, IC, CxtI))
10920b57cec5SDimitry Andric         return false;
10930b57cec5SDimitry Andric       BitsToClear += Amt->getZExtValue();
10940b57cec5SDimitry Andric       if (BitsToClear > V->getType()->getScalarSizeInBits())
10950b57cec5SDimitry Andric         BitsToClear = V->getType()->getScalarSizeInBits();
10960b57cec5SDimitry Andric       return true;
10970b57cec5SDimitry Andric     }
10980b57cec5SDimitry Andric     // Cannot promote variable LSHR.
10990b57cec5SDimitry Andric     return false;
11000b57cec5SDimitry Andric   }
11010b57cec5SDimitry Andric   case Instruction::Select:
11020b57cec5SDimitry Andric     if (!canEvaluateZExtd(I->getOperand(1), Ty, Tmp, IC, CxtI) ||
11030b57cec5SDimitry Andric         !canEvaluateZExtd(I->getOperand(2), Ty, BitsToClear, IC, CxtI) ||
11040b57cec5SDimitry Andric         // TODO: If important, we could handle the case when the BitsToClear are
11050b57cec5SDimitry Andric         // known zero in the disagreeing side.
11060b57cec5SDimitry Andric         Tmp != BitsToClear)
11070b57cec5SDimitry Andric       return false;
11080b57cec5SDimitry Andric     return true;
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric   case Instruction::PHI: {
11110b57cec5SDimitry Andric     // We can change a phi if we can change all operands.  Note that we never
11120b57cec5SDimitry Andric     // get into trouble with cyclic PHIs here because we only consider
11130b57cec5SDimitry Andric     // instructions with a single use.
11140b57cec5SDimitry Andric     PHINode *PN = cast<PHINode>(I);
11150b57cec5SDimitry Andric     if (!canEvaluateZExtd(PN->getIncomingValue(0), Ty, BitsToClear, IC, CxtI))
11160b57cec5SDimitry Andric       return false;
11170b57cec5SDimitry Andric     for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
11180b57cec5SDimitry Andric       if (!canEvaluateZExtd(PN->getIncomingValue(i), Ty, Tmp, IC, CxtI) ||
11190b57cec5SDimitry Andric           // TODO: If important, we could handle the case when the BitsToClear
11200b57cec5SDimitry Andric           // are known zero in the disagreeing input.
11210b57cec5SDimitry Andric           Tmp != BitsToClear)
11220b57cec5SDimitry Andric         return false;
11230b57cec5SDimitry Andric     return true;
11240b57cec5SDimitry Andric   }
112506c3fb27SDimitry Andric   case Instruction::Call:
112606c3fb27SDimitry Andric     // llvm.vscale() can always be executed in larger type, because the
112706c3fb27SDimitry Andric     // value is automatically zero-extended.
112806c3fb27SDimitry Andric     if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
112906c3fb27SDimitry Andric       if (II->getIntrinsicID() == Intrinsic::vscale)
113006c3fb27SDimitry Andric         return true;
113106c3fb27SDimitry Andric     return false;
11320b57cec5SDimitry Andric   default:
11330b57cec5SDimitry Andric     // TODO: Can handle more cases here.
11340b57cec5SDimitry Andric     return false;
11350b57cec5SDimitry Andric   }
11360b57cec5SDimitry Andric }
11370b57cec5SDimitry Andric 
1138bdd1243dSDimitry Andric Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
11390b57cec5SDimitry Andric   // If this zero extend is only used by a truncate, let the truncate be
11400b57cec5SDimitry Andric   // eliminated before we try to optimize this zext.
114106c3fb27SDimitry Andric   if (Zext.hasOneUse() && isa<TruncInst>(Zext.user_back()) &&
114206c3fb27SDimitry Andric       !isa<Constant>(Zext.getOperand(0)))
11430b57cec5SDimitry Andric     return nullptr;
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   // If one of the common conversion will work, do it.
1146bdd1243dSDimitry Andric   if (Instruction *Result = commonCastTransforms(Zext))
11470b57cec5SDimitry Andric     return Result;
11480b57cec5SDimitry Andric 
1149bdd1243dSDimitry Andric   Value *Src = Zext.getOperand(0);
1150bdd1243dSDimitry Andric   Type *SrcTy = Src->getType(), *DestTy = Zext.getType();
11510b57cec5SDimitry Andric 
1152*0fca6ea1SDimitry Andric   // zext nneg bool x -> 0
1153*0fca6ea1SDimitry Andric   if (SrcTy->isIntOrIntVectorTy(1) && Zext.hasNonNeg())
1154*0fca6ea1SDimitry Andric     return replaceInstUsesWith(Zext, Constant::getNullValue(Zext.getType()));
1155*0fca6ea1SDimitry Andric 
11560b57cec5SDimitry Andric   // Try to extend the entire expression tree to the wide destination type.
11570b57cec5SDimitry Andric   unsigned BitsToClear;
11580b57cec5SDimitry Andric   if (shouldChangeType(SrcTy, DestTy) &&
1159bdd1243dSDimitry Andric       canEvaluateZExtd(Src, DestTy, BitsToClear, *this, &Zext)) {
11600b57cec5SDimitry Andric     assert(BitsToClear <= SrcTy->getScalarSizeInBits() &&
11610b57cec5SDimitry Andric            "Can't clear more bits than in SrcTy");
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric     // Okay, we can transform this!  Insert the new expression now.
11640b57cec5SDimitry Andric     LLVM_DEBUG(
11650b57cec5SDimitry Andric         dbgs() << "ICE: EvaluateInDifferentType converting expression type"
11660b57cec5SDimitry Andric                   " to avoid zero extend: "
1167bdd1243dSDimitry Andric                << Zext << '\n');
11680b57cec5SDimitry Andric     Value *Res = EvaluateInDifferentType(Src, DestTy, false);
11690b57cec5SDimitry Andric     assert(Res->getType() == DestTy);
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric     // Preserve debug values referring to Src if the zext is its last use.
11720b57cec5SDimitry Andric     if (auto *SrcOp = dyn_cast<Instruction>(Src))
11730b57cec5SDimitry Andric       if (SrcOp->hasOneUse())
1174bdd1243dSDimitry Andric         replaceAllDbgUsesWith(*SrcOp, *Res, Zext, DT);
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric     uint32_t SrcBitsKept = SrcTy->getScalarSizeInBits() - BitsToClear;
11770b57cec5SDimitry Andric     uint32_t DestBitSize = DestTy->getScalarSizeInBits();
11780b57cec5SDimitry Andric 
11790b57cec5SDimitry Andric     // If the high bits are already filled with zeros, just replace this
11800b57cec5SDimitry Andric     // cast with the result.
11810b57cec5SDimitry Andric     if (MaskedValueIsZero(Res,
11820b57cec5SDimitry Andric                           APInt::getHighBitsSet(DestBitSize,
11830b57cec5SDimitry Andric                                                 DestBitSize - SrcBitsKept),
1184bdd1243dSDimitry Andric                              0, &Zext))
1185bdd1243dSDimitry Andric       return replaceInstUsesWith(Zext, Res);
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric     // We need to emit an AND to clear the high bits.
11880b57cec5SDimitry Andric     Constant *C = ConstantInt::get(Res->getType(),
11890b57cec5SDimitry Andric                                APInt::getLowBitsSet(DestBitSize, SrcBitsKept));
11900b57cec5SDimitry Andric     return BinaryOperator::CreateAnd(Res, C);
11910b57cec5SDimitry Andric   }
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric   // If this is a TRUNC followed by a ZEXT then we are dealing with integral
11940b57cec5SDimitry Andric   // types and if the sizes are just right we can convert this into a logical
11950b57cec5SDimitry Andric   // 'and' which will be much cheaper than the pair of casts.
1196bdd1243dSDimitry Andric   if (auto *CSrc = dyn_cast<TruncInst>(Src)) {   // A->B->C cast
11970b57cec5SDimitry Andric     // TODO: Subsume this into EvaluateInDifferentType.
11980b57cec5SDimitry Andric 
11990b57cec5SDimitry Andric     // Get the sizes of the types involved.  We know that the intermediate type
12000b57cec5SDimitry Andric     // will be smaller than A or C, but don't know the relation between A and C.
12010b57cec5SDimitry Andric     Value *A = CSrc->getOperand(0);
12020b57cec5SDimitry Andric     unsigned SrcSize = A->getType()->getScalarSizeInBits();
12030b57cec5SDimitry Andric     unsigned MidSize = CSrc->getType()->getScalarSizeInBits();
1204bdd1243dSDimitry Andric     unsigned DstSize = DestTy->getScalarSizeInBits();
12050b57cec5SDimitry Andric     // If we're actually extending zero bits, then if
12060b57cec5SDimitry Andric     // SrcSize <  DstSize: zext(a & mask)
12070b57cec5SDimitry Andric     // SrcSize == DstSize: a & mask
12080b57cec5SDimitry Andric     // SrcSize  > DstSize: trunc(a) & mask
12090b57cec5SDimitry Andric     if (SrcSize < DstSize) {
12100b57cec5SDimitry Andric       APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
12110b57cec5SDimitry Andric       Constant *AndConst = ConstantInt::get(A->getType(), AndValue);
12120b57cec5SDimitry Andric       Value *And = Builder.CreateAnd(A, AndConst, CSrc->getName() + ".mask");
1213bdd1243dSDimitry Andric       return new ZExtInst(And, DestTy);
12140b57cec5SDimitry Andric     }
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric     if (SrcSize == DstSize) {
12170b57cec5SDimitry Andric       APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
12180b57cec5SDimitry Andric       return BinaryOperator::CreateAnd(A, ConstantInt::get(A->getType(),
12190b57cec5SDimitry Andric                                                            AndValue));
12200b57cec5SDimitry Andric     }
12210b57cec5SDimitry Andric     if (SrcSize > DstSize) {
1222bdd1243dSDimitry Andric       Value *Trunc = Builder.CreateTrunc(A, DestTy);
12230b57cec5SDimitry Andric       APInt AndValue(APInt::getLowBitsSet(DstSize, MidSize));
12240b57cec5SDimitry Andric       return BinaryOperator::CreateAnd(Trunc,
12250b57cec5SDimitry Andric                                        ConstantInt::get(Trunc->getType(),
12260b57cec5SDimitry Andric                                                         AndValue));
12270b57cec5SDimitry Andric     }
12280b57cec5SDimitry Andric   }
12290b57cec5SDimitry Andric 
1230bdd1243dSDimitry Andric   if (auto *Cmp = dyn_cast<ICmpInst>(Src))
1231bdd1243dSDimitry Andric     return transformZExtICmp(Cmp, Zext);
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric   // zext(trunc(X) & C) -> (X & zext(C)).
12340b57cec5SDimitry Andric   Constant *C;
12350b57cec5SDimitry Andric   Value *X;
1236349cc55cSDimitry Andric   if (match(Src, m_OneUse(m_And(m_Trunc(m_Value(X)), m_Constant(C)))) &&
1237bdd1243dSDimitry Andric       X->getType() == DestTy)
12385f757f3fSDimitry Andric     return BinaryOperator::CreateAnd(X, Builder.CreateZExt(C, DestTy));
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric   // zext((trunc(X) & C) ^ C) -> ((X & zext(C)) ^ zext(C)).
12410b57cec5SDimitry Andric   Value *And;
1242349cc55cSDimitry Andric   if (match(Src, m_OneUse(m_Xor(m_Value(And), m_Constant(C)))) &&
12430b57cec5SDimitry Andric       match(And, m_OneUse(m_And(m_Trunc(m_Value(X)), m_Specific(C)))) &&
1244bdd1243dSDimitry Andric       X->getType() == DestTy) {
12455f757f3fSDimitry Andric     Value *ZC = Builder.CreateZExt(C, DestTy);
12460b57cec5SDimitry Andric     return BinaryOperator::CreateXor(Builder.CreateAnd(X, ZC), ZC);
12470b57cec5SDimitry Andric   }
12480b57cec5SDimitry Andric 
1249bdd1243dSDimitry Andric   // If we are truncating, masking, and then zexting back to the original type,
1250bdd1243dSDimitry Andric   // that's just a mask. This is not handled by canEvaluateZextd if the
1251bdd1243dSDimitry Andric   // intermediate values have extra uses. This could be generalized further for
1252bdd1243dSDimitry Andric   // a non-constant mask operand.
1253bdd1243dSDimitry Andric   // zext (and (trunc X), C) --> and X, (zext C)
1254bdd1243dSDimitry Andric   if (match(Src, m_And(m_Trunc(m_Value(X)), m_Constant(C))) &&
1255bdd1243dSDimitry Andric       X->getType() == DestTy) {
12565f757f3fSDimitry Andric     Value *ZextC = Builder.CreateZExt(C, DestTy);
1257bdd1243dSDimitry Andric     return BinaryOperator::CreateAnd(X, ZextC);
1258bdd1243dSDimitry Andric   }
1259bdd1243dSDimitry Andric 
126006c3fb27SDimitry Andric   if (match(Src, m_VScale())) {
1261bdd1243dSDimitry Andric     if (Zext.getFunction() &&
1262bdd1243dSDimitry Andric         Zext.getFunction()->hasFnAttribute(Attribute::VScaleRange)) {
1263bdd1243dSDimitry Andric       Attribute Attr =
1264bdd1243dSDimitry Andric           Zext.getFunction()->getFnAttribute(Attribute::VScaleRange);
1265bdd1243dSDimitry Andric       if (std::optional<unsigned> MaxVScale = Attr.getVScaleRangeMax()) {
1266349cc55cSDimitry Andric         unsigned TypeWidth = Src->getType()->getScalarSizeInBits();
126781ad6265SDimitry Andric         if (Log2_32(*MaxVScale) < TypeWidth) {
1268349cc55cSDimitry Andric           Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
1269bdd1243dSDimitry Andric           return replaceInstUsesWith(Zext, VScale);
1270349cc55cSDimitry Andric         }
1271349cc55cSDimitry Andric       }
1272349cc55cSDimitry Andric     }
12730eae32dcSDimitry Andric   }
1274349cc55cSDimitry Andric 
12755f757f3fSDimitry Andric   if (!Zext.hasNonNeg()) {
12765f757f3fSDimitry Andric     // If this zero extend is only used by a shift, add nneg flag.
12775f757f3fSDimitry Andric     if (Zext.hasOneUse() &&
12785f757f3fSDimitry Andric         SrcTy->getScalarSizeInBits() >
12795f757f3fSDimitry Andric             Log2_64_Ceil(DestTy->getScalarSizeInBits()) &&
12805f757f3fSDimitry Andric         match(Zext.user_back(), m_Shift(m_Value(), m_Specific(&Zext)))) {
12815f757f3fSDimitry Andric       Zext.setNonNeg();
12825f757f3fSDimitry Andric       return &Zext;
12835f757f3fSDimitry Andric     }
12845f757f3fSDimitry Andric 
12855f757f3fSDimitry Andric     if (isKnownNonNegative(Src, SQ.getWithInstruction(&Zext))) {
12865f757f3fSDimitry Andric       Zext.setNonNeg();
12875f757f3fSDimitry Andric       return &Zext;
12885f757f3fSDimitry Andric     }
12895f757f3fSDimitry Andric   }
12905f757f3fSDimitry Andric 
12910b57cec5SDimitry Andric   return nullptr;
12920b57cec5SDimitry Andric }
12930b57cec5SDimitry Andric 
12940b57cec5SDimitry Andric /// Transform (sext icmp) to bitwise / integer operations to eliminate the icmp.
1295bdd1243dSDimitry Andric Instruction *InstCombinerImpl::transformSExtICmp(ICmpInst *Cmp,
1296bdd1243dSDimitry Andric                                                  SExtInst &Sext) {
1297bdd1243dSDimitry Andric   Value *Op0 = Cmp->getOperand(0), *Op1 = Cmp->getOperand(1);
1298bdd1243dSDimitry Andric   ICmpInst::Predicate Pred = Cmp->getPredicate();
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric   // Don't bother if Op1 isn't of vector or integer type.
13010b57cec5SDimitry Andric   if (!Op1->getType()->isIntOrIntVectorTy())
13020b57cec5SDimitry Andric     return nullptr;
13030b57cec5SDimitry Andric 
1304bdd1243dSDimitry Andric   if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_ZeroInt())) {
1305bdd1243dSDimitry Andric     // sext (x <s 0) --> ashr x, 31 (all ones if negative)
13060b57cec5SDimitry Andric     Value *Sh = ConstantInt::get(Op0->getType(),
13070b57cec5SDimitry Andric                                  Op0->getType()->getScalarSizeInBits() - 1);
13080b57cec5SDimitry Andric     Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit");
1309bdd1243dSDimitry Andric     if (In->getType() != Sext.getType())
1310bdd1243dSDimitry Andric       In = Builder.CreateIntCast(In, Sext.getType(), true /*SExt*/);
13110b57cec5SDimitry Andric 
1312bdd1243dSDimitry Andric     return replaceInstUsesWith(Sext, In);
13130b57cec5SDimitry Andric   }
13140b57cec5SDimitry Andric 
13150b57cec5SDimitry Andric   if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
13160b57cec5SDimitry Andric     // If we know that only one bit of the LHS of the icmp can be set and we
13170b57cec5SDimitry Andric     // have an equality comparison with zero or a power of 2, we can transform
13180b57cec5SDimitry Andric     // the icmp and sext into bitwise/integer operations.
1319bdd1243dSDimitry Andric     if (Cmp->hasOneUse() &&
1320bdd1243dSDimitry Andric         Cmp->isEquality() && (Op1C->isZero() || Op1C->getValue().isPowerOf2())){
1321bdd1243dSDimitry Andric       KnownBits Known = computeKnownBits(Op0, 0, &Sext);
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric       APInt KnownZeroMask(~Known.Zero);
13240b57cec5SDimitry Andric       if (KnownZeroMask.isPowerOf2()) {
1325bdd1243dSDimitry Andric         Value *In = Cmp->getOperand(0);
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric         // If the icmp tests for a known zero bit we can constant fold it.
13280b57cec5SDimitry Andric         if (!Op1C->isZero() && Op1C->getValue() != KnownZeroMask) {
13290b57cec5SDimitry Andric           Value *V = Pred == ICmpInst::ICMP_NE ?
1330bdd1243dSDimitry Andric                        ConstantInt::getAllOnesValue(Sext.getType()) :
1331bdd1243dSDimitry Andric                        ConstantInt::getNullValue(Sext.getType());
1332bdd1243dSDimitry Andric           return replaceInstUsesWith(Sext, V);
13330b57cec5SDimitry Andric         }
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric         if (!Op1C->isZero() == (Pred == ICmpInst::ICMP_NE)) {
13360b57cec5SDimitry Andric           // sext ((x & 2^n) == 0)   -> (x >> n) - 1
13370b57cec5SDimitry Andric           // sext ((x & 2^n) != 2^n) -> (x >> n) - 1
133806c3fb27SDimitry Andric           unsigned ShiftAmt = KnownZeroMask.countr_zero();
13390b57cec5SDimitry Andric           // Perform a right shift to place the desired bit in the LSB.
13400b57cec5SDimitry Andric           if (ShiftAmt)
13410b57cec5SDimitry Andric             In = Builder.CreateLShr(In,
13420b57cec5SDimitry Andric                                     ConstantInt::get(In->getType(), ShiftAmt));
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric           // At this point "In" is either 1 or 0. Subtract 1 to turn
13450b57cec5SDimitry Andric           // {1, 0} -> {0, -1}.
13460b57cec5SDimitry Andric           In = Builder.CreateAdd(In,
13470b57cec5SDimitry Andric                                  ConstantInt::getAllOnesValue(In->getType()),
13480b57cec5SDimitry Andric                                  "sext");
13490b57cec5SDimitry Andric         } else {
13500b57cec5SDimitry Andric           // sext ((x & 2^n) != 0)   -> (x << bitwidth-n) a>> bitwidth-1
13510b57cec5SDimitry Andric           // sext ((x & 2^n) == 2^n) -> (x << bitwidth-n) a>> bitwidth-1
135206c3fb27SDimitry Andric           unsigned ShiftAmt = KnownZeroMask.countl_zero();
13530b57cec5SDimitry Andric           // Perform a left shift to place the desired bit in the MSB.
13540b57cec5SDimitry Andric           if (ShiftAmt)
13550b57cec5SDimitry Andric             In = Builder.CreateShl(In,
13560b57cec5SDimitry Andric                                    ConstantInt::get(In->getType(), ShiftAmt));
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric           // Distribute the bit over the whole bit width.
13590b57cec5SDimitry Andric           In = Builder.CreateAShr(In, ConstantInt::get(In->getType(),
13600b57cec5SDimitry Andric                                   KnownZeroMask.getBitWidth() - 1), "sext");
13610b57cec5SDimitry Andric         }
13620b57cec5SDimitry Andric 
1363bdd1243dSDimitry Andric         if (Sext.getType() == In->getType())
1364bdd1243dSDimitry Andric           return replaceInstUsesWith(Sext, In);
1365bdd1243dSDimitry Andric         return CastInst::CreateIntegerCast(In, Sext.getType(), true/*SExt*/);
13660b57cec5SDimitry Andric       }
13670b57cec5SDimitry Andric     }
13680b57cec5SDimitry Andric   }
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric   return nullptr;
13710b57cec5SDimitry Andric }
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric /// Return true if we can take the specified value and return it as type Ty
13740b57cec5SDimitry Andric /// without inserting any new casts and without changing the value of the common
13750b57cec5SDimitry Andric /// low bits.  This is used by code that tries to promote integer operations to
13760b57cec5SDimitry Andric /// a wider types will allow us to eliminate the extension.
13770b57cec5SDimitry Andric ///
13780b57cec5SDimitry Andric /// This function works on both vectors and scalars.
13790b57cec5SDimitry Andric ///
13800b57cec5SDimitry Andric static bool canEvaluateSExtd(Value *V, Type *Ty) {
13810b57cec5SDimitry Andric   assert(V->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits() &&
13820b57cec5SDimitry Andric          "Can't sign extend type to a smaller type");
13830b57cec5SDimitry Andric   if (canAlwaysEvaluateInType(V, Ty))
13840b57cec5SDimitry Andric     return true;
13850b57cec5SDimitry Andric   if (canNotEvaluateInType(V, Ty))
13860b57cec5SDimitry Andric     return false;
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric   auto *I = cast<Instruction>(V);
13890b57cec5SDimitry Andric   switch (I->getOpcode()) {
13900b57cec5SDimitry Andric   case Instruction::SExt:  // sext(sext(x)) -> sext(x)
13910b57cec5SDimitry Andric   case Instruction::ZExt:  // sext(zext(x)) -> zext(x)
13920b57cec5SDimitry Andric   case Instruction::Trunc: // sext(trunc(x)) -> trunc(x) or sext(x)
13930b57cec5SDimitry Andric     return true;
13940b57cec5SDimitry Andric   case Instruction::And:
13950b57cec5SDimitry Andric   case Instruction::Or:
13960b57cec5SDimitry Andric   case Instruction::Xor:
13970b57cec5SDimitry Andric   case Instruction::Add:
13980b57cec5SDimitry Andric   case Instruction::Sub:
13990b57cec5SDimitry Andric   case Instruction::Mul:
14000b57cec5SDimitry Andric     // These operators can all arbitrarily be extended if their inputs can.
14010b57cec5SDimitry Andric     return canEvaluateSExtd(I->getOperand(0), Ty) &&
14020b57cec5SDimitry Andric            canEvaluateSExtd(I->getOperand(1), Ty);
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric   //case Instruction::Shl:   TODO
14050b57cec5SDimitry Andric   //case Instruction::LShr:  TODO
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   case Instruction::Select:
14080b57cec5SDimitry Andric     return canEvaluateSExtd(I->getOperand(1), Ty) &&
14090b57cec5SDimitry Andric            canEvaluateSExtd(I->getOperand(2), Ty);
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric   case Instruction::PHI: {
14120b57cec5SDimitry Andric     // We can change a phi if we can change all operands.  Note that we never
14130b57cec5SDimitry Andric     // get into trouble with cyclic PHIs here because we only consider
14140b57cec5SDimitry Andric     // instructions with a single use.
14150b57cec5SDimitry Andric     PHINode *PN = cast<PHINode>(I);
14160b57cec5SDimitry Andric     for (Value *IncValue : PN->incoming_values())
14170b57cec5SDimitry Andric       if (!canEvaluateSExtd(IncValue, Ty)) return false;
14180b57cec5SDimitry Andric     return true;
14190b57cec5SDimitry Andric   }
14200b57cec5SDimitry Andric   default:
14210b57cec5SDimitry Andric     // TODO: Can handle more cases here.
14220b57cec5SDimitry Andric     break;
14230b57cec5SDimitry Andric   }
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric   return false;
14260b57cec5SDimitry Andric }
14270b57cec5SDimitry Andric 
1428bdd1243dSDimitry Andric Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
14290b57cec5SDimitry Andric   // If this sign extend is only used by a truncate, let the truncate be
14300b57cec5SDimitry Andric   // eliminated before we try to optimize this sext.
1431bdd1243dSDimitry Andric   if (Sext.hasOneUse() && isa<TruncInst>(Sext.user_back()))
14320b57cec5SDimitry Andric     return nullptr;
14330b57cec5SDimitry Andric 
1434bdd1243dSDimitry Andric   if (Instruction *I = commonCastTransforms(Sext))
14350b57cec5SDimitry Andric     return I;
14360b57cec5SDimitry Andric 
1437bdd1243dSDimitry Andric   Value *Src = Sext.getOperand(0);
1438bdd1243dSDimitry Andric   Type *SrcTy = Src->getType(), *DestTy = Sext.getType();
1439fe6060f1SDimitry Andric   unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
1440fe6060f1SDimitry Andric   unsigned DestBitSize = DestTy->getScalarSizeInBits();
14410b57cec5SDimitry Andric 
144281ad6265SDimitry Andric   // If the value being extended is zero or positive, use a zext instead.
14435f757f3fSDimitry Andric   if (isKnownNonNegative(Src, SQ.getWithInstruction(&Sext))) {
14445f757f3fSDimitry Andric     auto CI = CastInst::Create(Instruction::ZExt, Src, DestTy);
14455f757f3fSDimitry Andric     CI->setNonNeg(true);
14465f757f3fSDimitry Andric     return CI;
14475f757f3fSDimitry Andric   }
14480b57cec5SDimitry Andric 
14490b57cec5SDimitry Andric   // Try to extend the entire expression tree to the wide destination type.
14500b57cec5SDimitry Andric   if (shouldChangeType(SrcTy, DestTy) && canEvaluateSExtd(Src, DestTy)) {
14510b57cec5SDimitry Andric     // Okay, we can transform this!  Insert the new expression now.
14520b57cec5SDimitry Andric     LLVM_DEBUG(
14530b57cec5SDimitry Andric         dbgs() << "ICE: EvaluateInDifferentType converting expression type"
14540b57cec5SDimitry Andric                   " to avoid sign extend: "
1455bdd1243dSDimitry Andric                << Sext << '\n');
14560b57cec5SDimitry Andric     Value *Res = EvaluateInDifferentType(Src, DestTy, true);
14570b57cec5SDimitry Andric     assert(Res->getType() == DestTy);
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric     // If the high bits are already filled with sign bit, just replace this
14600b57cec5SDimitry Andric     // cast with the result.
1461bdd1243dSDimitry Andric     if (ComputeNumSignBits(Res, 0, &Sext) > DestBitSize - SrcBitSize)
1462bdd1243dSDimitry Andric       return replaceInstUsesWith(Sext, Res);
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric     // We need to emit a shl + ashr to do the sign extend.
14650b57cec5SDimitry Andric     Value *ShAmt = ConstantInt::get(DestTy, DestBitSize-SrcBitSize);
14660b57cec5SDimitry Andric     return BinaryOperator::CreateAShr(Builder.CreateShl(Res, ShAmt, "sext"),
14670b57cec5SDimitry Andric                                       ShAmt);
14680b57cec5SDimitry Andric   }
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   Value *X;
1471fe6060f1SDimitry Andric   if (match(Src, m_Trunc(m_Value(X)))) {
1472fe6060f1SDimitry Andric     // If the input has more sign bits than bits truncated, then convert
1473fe6060f1SDimitry Andric     // directly to final type.
1474fe6060f1SDimitry Andric     unsigned XBitSize = X->getType()->getScalarSizeInBits();
1475bdd1243dSDimitry Andric     if (ComputeNumSignBits(X, 0, &Sext) > XBitSize - SrcBitSize)
1476fe6060f1SDimitry Andric       return CastInst::CreateIntegerCast(X, DestTy, /* isSigned */ true);
1477fe6060f1SDimitry Andric 
1478fe6060f1SDimitry Andric     // If input is a trunc from the destination type, then convert into shifts.
1479fe6060f1SDimitry Andric     if (Src->hasOneUse() && X->getType() == DestTy) {
1480fe6060f1SDimitry Andric       // sext (trunc X) --> ashr (shl X, C), C
14810b57cec5SDimitry Andric       Constant *ShAmt = ConstantInt::get(DestTy, DestBitSize - SrcBitSize);
14820b57cec5SDimitry Andric       return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShAmt), ShAmt);
14830b57cec5SDimitry Andric     }
14840b57cec5SDimitry Andric 
1485fe6060f1SDimitry Andric     // If we are replacing shifted-in high zero bits with sign bits, convert
1486fe6060f1SDimitry Andric     // the logic shift to arithmetic shift and eliminate the cast to
1487fe6060f1SDimitry Andric     // intermediate type:
1488fe6060f1SDimitry Andric     // sext (trunc (lshr Y, C)) --> sext/trunc (ashr Y, C)
1489fe6060f1SDimitry Andric     Value *Y;
1490fe6060f1SDimitry Andric     if (Src->hasOneUse() &&
1491fe6060f1SDimitry Andric         match(X, m_LShr(m_Value(Y),
1492*0fca6ea1SDimitry Andric                         m_SpecificIntAllowPoison(XBitSize - SrcBitSize)))) {
1493fe6060f1SDimitry Andric       Value *Ashr = Builder.CreateAShr(Y, XBitSize - SrcBitSize);
1494fe6060f1SDimitry Andric       return CastInst::CreateIntegerCast(Ashr, DestTy, /* isSigned */ true);
1495fe6060f1SDimitry Andric     }
1496fe6060f1SDimitry Andric   }
1497fe6060f1SDimitry Andric 
1498bdd1243dSDimitry Andric   if (auto *Cmp = dyn_cast<ICmpInst>(Src))
1499bdd1243dSDimitry Andric     return transformSExtICmp(Cmp, Sext);
15000b57cec5SDimitry Andric 
15010b57cec5SDimitry Andric   // If the input is a shl/ashr pair of a same constant, then this is a sign
15020b57cec5SDimitry Andric   // extension from a smaller value.  If we could trust arbitrary bitwidth
15030b57cec5SDimitry Andric   // integers, we could turn this into a truncate to the smaller bit and then
15040b57cec5SDimitry Andric   // use a sext for the whole extension.  Since we don't, look deeper and check
15050b57cec5SDimitry Andric   // for a truncate.  If the source and dest are the same type, eliminate the
15060b57cec5SDimitry Andric   // trunc and extend and just do shifts.  For example, turn:
15070b57cec5SDimitry Andric   //   %a = trunc i32 %i to i8
1508e8d8bef9SDimitry Andric   //   %b = shl i8 %a, C
1509e8d8bef9SDimitry Andric   //   %c = ashr i8 %b, C
15100b57cec5SDimitry Andric   //   %d = sext i8 %c to i32
15110b57cec5SDimitry Andric   // into:
1512e8d8bef9SDimitry Andric   //   %a = shl i32 %i, 32-(8-C)
1513e8d8bef9SDimitry Andric   //   %d = ashr i32 %a, 32-(8-C)
15140b57cec5SDimitry Andric   Value *A = nullptr;
15150b57cec5SDimitry Andric   // TODO: Eventually this could be subsumed by EvaluateInDifferentType.
15165ffd83dbSDimitry Andric   Constant *BA = nullptr, *CA = nullptr;
15175ffd83dbSDimitry Andric   if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A)), m_Constant(BA)),
15185f757f3fSDimitry Andric                         m_ImmConstant(CA))) &&
1519e8d8bef9SDimitry Andric       BA->isElementWiseEqual(CA) && A->getType() == DestTy) {
15205f757f3fSDimitry Andric     Constant *WideCurrShAmt =
15215f757f3fSDimitry Andric         ConstantFoldCastOperand(Instruction::SExt, CA, DestTy, DL);
15225f757f3fSDimitry Andric     assert(WideCurrShAmt && "Constant folding of ImmConstant cannot fail");
1523e8d8bef9SDimitry Andric     Constant *NumLowbitsLeft = ConstantExpr::getSub(
1524e8d8bef9SDimitry Andric         ConstantInt::get(DestTy, SrcTy->getScalarSizeInBits()), WideCurrShAmt);
1525e8d8bef9SDimitry Andric     Constant *NewShAmt = ConstantExpr::getSub(
1526e8d8bef9SDimitry Andric         ConstantInt::get(DestTy, DestTy->getScalarSizeInBits()),
1527e8d8bef9SDimitry Andric         NumLowbitsLeft);
1528e8d8bef9SDimitry Andric     NewShAmt =
1529e8d8bef9SDimitry Andric         Constant::mergeUndefsWith(Constant::mergeUndefsWith(NewShAmt, BA), CA);
1530bdd1243dSDimitry Andric     A = Builder.CreateShl(A, NewShAmt, Sext.getName());
1531e8d8bef9SDimitry Andric     return BinaryOperator::CreateAShr(A, NewShAmt);
15320b57cec5SDimitry Andric   }
15330b57cec5SDimitry Andric 
1534349cc55cSDimitry Andric   // Splatting a bit of constant-index across a value:
1535349cc55cSDimitry Andric   // sext (ashr (trunc iN X to iM), M-1) to iN --> ashr (shl X, N-M), N-1
153681ad6265SDimitry Andric   // If the dest type is different, use a cast (adjust use check).
1537349cc55cSDimitry Andric   if (match(Src, m_OneUse(m_AShr(m_Trunc(m_Value(X)),
153881ad6265SDimitry Andric                                  m_SpecificInt(SrcBitSize - 1))))) {
153981ad6265SDimitry Andric     Type *XTy = X->getType();
154081ad6265SDimitry Andric     unsigned XBitSize = XTy->getScalarSizeInBits();
154181ad6265SDimitry Andric     Constant *ShlAmtC = ConstantInt::get(XTy, XBitSize - SrcBitSize);
154281ad6265SDimitry Andric     Constant *AshrAmtC = ConstantInt::get(XTy, XBitSize - 1);
154381ad6265SDimitry Andric     if (XTy == DestTy)
154481ad6265SDimitry Andric       return BinaryOperator::CreateAShr(Builder.CreateShl(X, ShlAmtC),
154581ad6265SDimitry Andric                                         AshrAmtC);
154681ad6265SDimitry Andric     if (cast<BinaryOperator>(Src)->getOperand(0)->hasOneUse()) {
154781ad6265SDimitry Andric       Value *Ashr = Builder.CreateAShr(Builder.CreateShl(X, ShlAmtC), AshrAmtC);
154881ad6265SDimitry Andric       return CastInst::CreateIntegerCast(Ashr, DestTy, /* isSigned */ true);
154981ad6265SDimitry Andric     }
1550349cc55cSDimitry Andric   }
1551349cc55cSDimitry Andric 
155206c3fb27SDimitry Andric   if (match(Src, m_VScale())) {
1553bdd1243dSDimitry Andric     if (Sext.getFunction() &&
1554bdd1243dSDimitry Andric         Sext.getFunction()->hasFnAttribute(Attribute::VScaleRange)) {
1555bdd1243dSDimitry Andric       Attribute Attr =
1556bdd1243dSDimitry Andric           Sext.getFunction()->getFnAttribute(Attribute::VScaleRange);
1557bdd1243dSDimitry Andric       if (std::optional<unsigned> MaxVScale = Attr.getVScaleRangeMax()) {
155881ad6265SDimitry Andric         if (Log2_32(*MaxVScale) < (SrcBitSize - 1)) {
1559349cc55cSDimitry Andric           Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
1560bdd1243dSDimitry Andric           return replaceInstUsesWith(Sext, VScale);
1561349cc55cSDimitry Andric         }
1562349cc55cSDimitry Andric       }
1563349cc55cSDimitry Andric     }
15640eae32dcSDimitry Andric   }
1565349cc55cSDimitry Andric 
15660b57cec5SDimitry Andric   return nullptr;
15670b57cec5SDimitry Andric }
15680b57cec5SDimitry Andric 
15690b57cec5SDimitry Andric /// Return a Constant* for the specified floating-point constant if it fits
15700b57cec5SDimitry Andric /// in the specified FP type without changing its value.
15710b57cec5SDimitry Andric static bool fitsInFPType(ConstantFP *CFP, const fltSemantics &Sem) {
15720b57cec5SDimitry Andric   bool losesInfo;
15730b57cec5SDimitry Andric   APFloat F = CFP->getValueAPF();
15740b57cec5SDimitry Andric   (void)F.convert(Sem, APFloat::rmNearestTiesToEven, &losesInfo);
15750b57cec5SDimitry Andric   return !losesInfo;
15760b57cec5SDimitry Andric }
15770b57cec5SDimitry Andric 
1578*0fca6ea1SDimitry Andric static Type *shrinkFPConstant(ConstantFP *CFP, bool PreferBFloat) {
15790b57cec5SDimitry Andric   if (CFP->getType() == Type::getPPC_FP128Ty(CFP->getContext()))
15800b57cec5SDimitry Andric     return nullptr;  // No constant folding of this.
1581*0fca6ea1SDimitry Andric   // See if the value can be truncated to bfloat and then reextended.
1582*0fca6ea1SDimitry Andric   if (PreferBFloat && fitsInFPType(CFP, APFloat::BFloat()))
1583*0fca6ea1SDimitry Andric     return Type::getBFloatTy(CFP->getContext());
15840b57cec5SDimitry Andric   // See if the value can be truncated to half and then reextended.
1585*0fca6ea1SDimitry Andric   if (!PreferBFloat && fitsInFPType(CFP, APFloat::IEEEhalf()))
15860b57cec5SDimitry Andric     return Type::getHalfTy(CFP->getContext());
15870b57cec5SDimitry Andric   // See if the value can be truncated to float and then reextended.
15880b57cec5SDimitry Andric   if (fitsInFPType(CFP, APFloat::IEEEsingle()))
15890b57cec5SDimitry Andric     return Type::getFloatTy(CFP->getContext());
15900b57cec5SDimitry Andric   if (CFP->getType()->isDoubleTy())
15910b57cec5SDimitry Andric     return nullptr;  // Won't shrink.
15920b57cec5SDimitry Andric   if (fitsInFPType(CFP, APFloat::IEEEdouble()))
15930b57cec5SDimitry Andric     return Type::getDoubleTy(CFP->getContext());
15940b57cec5SDimitry Andric   // Don't try to shrink to various long double types.
15950b57cec5SDimitry Andric   return nullptr;
15960b57cec5SDimitry Andric }
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric // Determine if this is a vector of ConstantFPs and if so, return the minimal
15990b57cec5SDimitry Andric // type we can safely truncate all elements to.
1600*0fca6ea1SDimitry Andric static Type *shrinkFPConstantVector(Value *V, bool PreferBFloat) {
16010b57cec5SDimitry Andric   auto *CV = dyn_cast<Constant>(V);
1602fe6060f1SDimitry Andric   auto *CVVTy = dyn_cast<FixedVectorType>(V->getType());
16035ffd83dbSDimitry Andric   if (!CV || !CVVTy)
16040b57cec5SDimitry Andric     return nullptr;
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric   Type *MinType = nullptr;
16070b57cec5SDimitry Andric 
1608fe6060f1SDimitry Andric   unsigned NumElts = CVVTy->getNumElements();
1609fe6060f1SDimitry Andric 
1610fe6060f1SDimitry Andric   // For fixed-width vectors we find the minimal type by looking
1611fe6060f1SDimitry Andric   // through the constant values of the vector.
16120b57cec5SDimitry Andric   for (unsigned i = 0; i != NumElts; ++i) {
1613bdd1243dSDimitry Andric     if (isa<UndefValue>(CV->getAggregateElement(i)))
1614bdd1243dSDimitry Andric       continue;
1615bdd1243dSDimitry Andric 
16160b57cec5SDimitry Andric     auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i));
16170b57cec5SDimitry Andric     if (!CFP)
16180b57cec5SDimitry Andric       return nullptr;
16190b57cec5SDimitry Andric 
1620*0fca6ea1SDimitry Andric     Type *T = shrinkFPConstant(CFP, PreferBFloat);
16210b57cec5SDimitry Andric     if (!T)
16220b57cec5SDimitry Andric       return nullptr;
16230b57cec5SDimitry Andric 
16240b57cec5SDimitry Andric     // If we haven't found a type yet or this type has a larger mantissa than
16250b57cec5SDimitry Andric     // our previous type, this is our new minimal type.
16260b57cec5SDimitry Andric     if (!MinType || T->getFPMantissaWidth() > MinType->getFPMantissaWidth())
16270b57cec5SDimitry Andric       MinType = T;
16280b57cec5SDimitry Andric   }
16290b57cec5SDimitry Andric 
16300b57cec5SDimitry Andric   // Make a vector type from the minimal type.
1631bdd1243dSDimitry Andric   return MinType ? FixedVectorType::get(MinType, NumElts) : nullptr;
16320b57cec5SDimitry Andric }
16330b57cec5SDimitry Andric 
16340b57cec5SDimitry Andric /// Find the minimum FP type we can safely truncate to.
1635*0fca6ea1SDimitry Andric static Type *getMinimumFPType(Value *V, bool PreferBFloat) {
16360b57cec5SDimitry Andric   if (auto *FPExt = dyn_cast<FPExtInst>(V))
16370b57cec5SDimitry Andric     return FPExt->getOperand(0)->getType();
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric   // If this value is a constant, return the constant in the smallest FP type
16400b57cec5SDimitry Andric   // that can accurately represent it.  This allows us to turn
16410b57cec5SDimitry Andric   // (float)((double)X+2.0) into x+2.0f.
16420b57cec5SDimitry Andric   if (auto *CFP = dyn_cast<ConstantFP>(V))
1643*0fca6ea1SDimitry Andric     if (Type *T = shrinkFPConstant(CFP, PreferBFloat))
16440b57cec5SDimitry Andric       return T;
16450b57cec5SDimitry Andric 
1646fe6060f1SDimitry Andric   // We can only correctly find a minimum type for a scalable vector when it is
1647fe6060f1SDimitry Andric   // a splat. For splats of constant values the fpext is wrapped up as a
1648fe6060f1SDimitry Andric   // ConstantExpr.
1649fe6060f1SDimitry Andric   if (auto *FPCExt = dyn_cast<ConstantExpr>(V))
1650fe6060f1SDimitry Andric     if (FPCExt->getOpcode() == Instruction::FPExt)
1651fe6060f1SDimitry Andric       return FPCExt->getOperand(0)->getType();
1652fe6060f1SDimitry Andric 
1653fe6060f1SDimitry Andric   // Try to shrink a vector of FP constants. This returns nullptr on scalable
1654fe6060f1SDimitry Andric   // vectors
1655*0fca6ea1SDimitry Andric   if (Type *T = shrinkFPConstantVector(V, PreferBFloat))
16560b57cec5SDimitry Andric     return T;
16570b57cec5SDimitry Andric 
16580b57cec5SDimitry Andric   return V->getType();
16590b57cec5SDimitry Andric }
16600b57cec5SDimitry Andric 
16615ffd83dbSDimitry Andric /// Return true if the cast from integer to FP can be proven to be exact for all
16625ffd83dbSDimitry Andric /// possible inputs (the conversion does not lose any precision).
166381ad6265SDimitry Andric static bool isKnownExactCastIntToFP(CastInst &I, InstCombinerImpl &IC) {
16645ffd83dbSDimitry Andric   CastInst::CastOps Opcode = I.getOpcode();
16655ffd83dbSDimitry Andric   assert((Opcode == CastInst::SIToFP || Opcode == CastInst::UIToFP) &&
16665ffd83dbSDimitry Andric          "Unexpected cast");
16675ffd83dbSDimitry Andric   Value *Src = I.getOperand(0);
16685ffd83dbSDimitry Andric   Type *SrcTy = Src->getType();
16695ffd83dbSDimitry Andric   Type *FPTy = I.getType();
16705ffd83dbSDimitry Andric   bool IsSigned = Opcode == Instruction::SIToFP;
16715ffd83dbSDimitry Andric   int SrcSize = (int)SrcTy->getScalarSizeInBits() - IsSigned;
16725ffd83dbSDimitry Andric 
16735ffd83dbSDimitry Andric   // Easy case - if the source integer type has less bits than the FP mantissa,
16745ffd83dbSDimitry Andric   // then the cast must be exact.
16755ffd83dbSDimitry Andric   int DestNumSigBits = FPTy->getFPMantissaWidth();
16765ffd83dbSDimitry Andric   if (SrcSize <= DestNumSigBits)
16775ffd83dbSDimitry Andric     return true;
16785ffd83dbSDimitry Andric 
16795ffd83dbSDimitry Andric   // Cast from FP to integer and back to FP is independent of the intermediate
16805ffd83dbSDimitry Andric   // integer width because of poison on overflow.
16815ffd83dbSDimitry Andric   Value *F;
16825ffd83dbSDimitry Andric   if (match(Src, m_FPToSI(m_Value(F))) || match(Src, m_FPToUI(m_Value(F)))) {
16835ffd83dbSDimitry Andric     // If this is uitofp (fptosi F), the source needs an extra bit to avoid
16845ffd83dbSDimitry Andric     // potential rounding of negative FP input values.
16855ffd83dbSDimitry Andric     int SrcNumSigBits = F->getType()->getFPMantissaWidth();
16865ffd83dbSDimitry Andric     if (!IsSigned && match(Src, m_FPToSI(m_Value())))
16875ffd83dbSDimitry Andric       SrcNumSigBits++;
16885ffd83dbSDimitry Andric 
16895ffd83dbSDimitry Andric     // [su]itofp (fpto[su]i F) --> exact if the source type has less or equal
16905ffd83dbSDimitry Andric     // significant bits than the destination (and make sure neither type is
16915ffd83dbSDimitry Andric     // weird -- ppc_fp128).
16925ffd83dbSDimitry Andric     if (SrcNumSigBits > 0 && DestNumSigBits > 0 &&
16935ffd83dbSDimitry Andric         SrcNumSigBits <= DestNumSigBits)
16945ffd83dbSDimitry Andric       return true;
16955ffd83dbSDimitry Andric   }
16965ffd83dbSDimitry Andric 
16975ffd83dbSDimitry Andric   // TODO:
16985ffd83dbSDimitry Andric   // Try harder to find if the source integer type has less significant bits.
1699753f127fSDimitry Andric   // For example, compute number of sign bits.
170081ad6265SDimitry Andric   KnownBits SrcKnown = IC.computeKnownBits(Src, 0, &I);
1701753f127fSDimitry Andric   int SigBits = (int)SrcTy->getScalarSizeInBits() -
1702753f127fSDimitry Andric                 SrcKnown.countMinLeadingZeros() -
1703753f127fSDimitry Andric                 SrcKnown.countMinTrailingZeros();
1704753f127fSDimitry Andric   if (SigBits <= DestNumSigBits)
170581ad6265SDimitry Andric     return true;
170681ad6265SDimitry Andric 
17075ffd83dbSDimitry Andric   return false;
17085ffd83dbSDimitry Andric }
17095ffd83dbSDimitry Andric 
1710e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
17110b57cec5SDimitry Andric   if (Instruction *I = commonCastTransforms(FPT))
17120b57cec5SDimitry Andric     return I;
17130b57cec5SDimitry Andric 
17140b57cec5SDimitry Andric   // If we have fptrunc(OpI (fpextend x), (fpextend y)), we would like to
17150b57cec5SDimitry Andric   // simplify this expression to avoid one or more of the trunc/extend
17160b57cec5SDimitry Andric   // operations if we can do so without changing the numerical results.
17170b57cec5SDimitry Andric   //
17180b57cec5SDimitry Andric   // The exact manner in which the widths of the operands interact to limit
17190b57cec5SDimitry Andric   // what we can and cannot do safely varies from operation to operation, and
17200b57cec5SDimitry Andric   // is explained below in the various case statements.
17210b57cec5SDimitry Andric   Type *Ty = FPT.getType();
17228bcb0991SDimitry Andric   auto *BO = dyn_cast<BinaryOperator>(FPT.getOperand(0));
17238bcb0991SDimitry Andric   if (BO && BO->hasOneUse()) {
1724*0fca6ea1SDimitry Andric     Type *LHSMinType =
1725*0fca6ea1SDimitry Andric         getMinimumFPType(BO->getOperand(0), /*PreferBFloat=*/Ty->isBFloatTy());
1726*0fca6ea1SDimitry Andric     Type *RHSMinType =
1727*0fca6ea1SDimitry Andric         getMinimumFPType(BO->getOperand(1), /*PreferBFloat=*/Ty->isBFloatTy());
17288bcb0991SDimitry Andric     unsigned OpWidth = BO->getType()->getFPMantissaWidth();
17290b57cec5SDimitry Andric     unsigned LHSWidth = LHSMinType->getFPMantissaWidth();
17300b57cec5SDimitry Andric     unsigned RHSWidth = RHSMinType->getFPMantissaWidth();
17310b57cec5SDimitry Andric     unsigned SrcWidth = std::max(LHSWidth, RHSWidth);
17320b57cec5SDimitry Andric     unsigned DstWidth = Ty->getFPMantissaWidth();
17338bcb0991SDimitry Andric     switch (BO->getOpcode()) {
17340b57cec5SDimitry Andric       default: break;
17350b57cec5SDimitry Andric       case Instruction::FAdd:
17360b57cec5SDimitry Andric       case Instruction::FSub:
17370b57cec5SDimitry Andric         // For addition and subtraction, the infinitely precise result can
17380b57cec5SDimitry Andric         // essentially be arbitrarily wide; proving that double rounding
17390b57cec5SDimitry Andric         // will not occur because the result of OpI is exact (as we will for
17400b57cec5SDimitry Andric         // FMul, for example) is hopeless.  However, we *can* nonetheless
17410b57cec5SDimitry Andric         // frequently know that double rounding cannot occur (or that it is
17420b57cec5SDimitry Andric         // innocuous) by taking advantage of the specific structure of
17430b57cec5SDimitry Andric         // infinitely-precise results that admit double rounding.
17440b57cec5SDimitry Andric         //
17450b57cec5SDimitry Andric         // Specifically, if OpWidth >= 2*DstWdith+1 and DstWidth is sufficient
17460b57cec5SDimitry Andric         // to represent both sources, we can guarantee that the double
17470b57cec5SDimitry Andric         // rounding is innocuous (See p50 of Figueroa's 2000 PhD thesis,
17480b57cec5SDimitry Andric         // "A Rigorous Framework for Fully Supporting the IEEE Standard ..."
17490b57cec5SDimitry Andric         // for proof of this fact).
17500b57cec5SDimitry Andric         //
17510b57cec5SDimitry Andric         // Note: Figueroa does not consider the case where DstFormat !=
17520b57cec5SDimitry Andric         // SrcFormat.  It's possible (likely even!) that this analysis
17530b57cec5SDimitry Andric         // could be tightened for those cases, but they are rare (the main
17540b57cec5SDimitry Andric         // case of interest here is (float)((double)float + float)).
17550b57cec5SDimitry Andric         if (OpWidth >= 2*DstWidth+1 && DstWidth >= SrcWidth) {
17568bcb0991SDimitry Andric           Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);
17578bcb0991SDimitry Andric           Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);
17588bcb0991SDimitry Andric           Instruction *RI = BinaryOperator::Create(BO->getOpcode(), LHS, RHS);
17598bcb0991SDimitry Andric           RI->copyFastMathFlags(BO);
17600b57cec5SDimitry Andric           return RI;
17610b57cec5SDimitry Andric         }
17620b57cec5SDimitry Andric         break;
17630b57cec5SDimitry Andric       case Instruction::FMul:
17640b57cec5SDimitry Andric         // For multiplication, the infinitely precise result has at most
17650b57cec5SDimitry Andric         // LHSWidth + RHSWidth significant bits; if OpWidth is sufficient
17660b57cec5SDimitry Andric         // that such a value can be exactly represented, then no double
17670b57cec5SDimitry Andric         // rounding can possibly occur; we can safely perform the operation
17680b57cec5SDimitry Andric         // in the destination format if it can represent both sources.
17690b57cec5SDimitry Andric         if (OpWidth >= LHSWidth + RHSWidth && DstWidth >= SrcWidth) {
17708bcb0991SDimitry Andric           Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);
17718bcb0991SDimitry Andric           Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);
17728bcb0991SDimitry Andric           return BinaryOperator::CreateFMulFMF(LHS, RHS, BO);
17730b57cec5SDimitry Andric         }
17740b57cec5SDimitry Andric         break;
17750b57cec5SDimitry Andric       case Instruction::FDiv:
17760b57cec5SDimitry Andric         // For division, we use again use the bound from Figueroa's
17770b57cec5SDimitry Andric         // dissertation.  I am entirely certain that this bound can be
17780b57cec5SDimitry Andric         // tightened in the unbalanced operand case by an analysis based on
17790b57cec5SDimitry Andric         // the diophantine rational approximation bound, but the well-known
17800b57cec5SDimitry Andric         // condition used here is a good conservative first pass.
17810b57cec5SDimitry Andric         // TODO: Tighten bound via rigorous analysis of the unbalanced case.
17820b57cec5SDimitry Andric         if (OpWidth >= 2*DstWidth && DstWidth >= SrcWidth) {
17838bcb0991SDimitry Andric           Value *LHS = Builder.CreateFPTrunc(BO->getOperand(0), Ty);
17848bcb0991SDimitry Andric           Value *RHS = Builder.CreateFPTrunc(BO->getOperand(1), Ty);
17858bcb0991SDimitry Andric           return BinaryOperator::CreateFDivFMF(LHS, RHS, BO);
17860b57cec5SDimitry Andric         }
17870b57cec5SDimitry Andric         break;
17880b57cec5SDimitry Andric       case Instruction::FRem: {
17890b57cec5SDimitry Andric         // Remainder is straightforward.  Remainder is always exact, so the
17900b57cec5SDimitry Andric         // type of OpI doesn't enter into things at all.  We simply evaluate
17910b57cec5SDimitry Andric         // in whichever source type is larger, then convert to the
17920b57cec5SDimitry Andric         // destination type.
17930b57cec5SDimitry Andric         if (SrcWidth == OpWidth)
17940b57cec5SDimitry Andric           break;
17950b57cec5SDimitry Andric         Value *LHS, *RHS;
17960b57cec5SDimitry Andric         if (LHSWidth == SrcWidth) {
17978bcb0991SDimitry Andric            LHS = Builder.CreateFPTrunc(BO->getOperand(0), LHSMinType);
17988bcb0991SDimitry Andric            RHS = Builder.CreateFPTrunc(BO->getOperand(1), LHSMinType);
17990b57cec5SDimitry Andric         } else {
18008bcb0991SDimitry Andric            LHS = Builder.CreateFPTrunc(BO->getOperand(0), RHSMinType);
18018bcb0991SDimitry Andric            RHS = Builder.CreateFPTrunc(BO->getOperand(1), RHSMinType);
18020b57cec5SDimitry Andric         }
18030b57cec5SDimitry Andric 
18048bcb0991SDimitry Andric         Value *ExactResult = Builder.CreateFRemFMF(LHS, RHS, BO);
18050b57cec5SDimitry Andric         return CastInst::CreateFPCast(ExactResult, Ty);
18060b57cec5SDimitry Andric       }
18070b57cec5SDimitry Andric     }
18080b57cec5SDimitry Andric   }
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric   // (fptrunc (fneg x)) -> (fneg (fptrunc x))
18110b57cec5SDimitry Andric   Value *X;
18120b57cec5SDimitry Andric   Instruction *Op = dyn_cast<Instruction>(FPT.getOperand(0));
18130b57cec5SDimitry Andric   if (Op && Op->hasOneUse()) {
1814480093f4SDimitry Andric     // FIXME: The FMF should propagate from the fptrunc, not the source op.
1815480093f4SDimitry Andric     IRBuilder<>::FastMathFlagGuard FMFG(Builder);
1816480093f4SDimitry Andric     if (isa<FPMathOperator>(Op))
1817480093f4SDimitry Andric       Builder.setFastMathFlags(Op->getFastMathFlags());
1818480093f4SDimitry Andric 
18190b57cec5SDimitry Andric     if (match(Op, m_FNeg(m_Value(X)))) {
18200b57cec5SDimitry Andric       Value *InnerTrunc = Builder.CreateFPTrunc(X, Ty);
18210b57cec5SDimitry Andric 
18220b57cec5SDimitry Andric       return UnaryOperator::CreateFNegFMF(InnerTrunc, Op);
18230b57cec5SDimitry Andric     }
1824480093f4SDimitry Andric 
1825480093f4SDimitry Andric     // If we are truncating a select that has an extended operand, we can
1826480093f4SDimitry Andric     // narrow the other operand and do the select as a narrow op.
1827480093f4SDimitry Andric     Value *Cond, *X, *Y;
1828480093f4SDimitry Andric     if (match(Op, m_Select(m_Value(Cond), m_FPExt(m_Value(X)), m_Value(Y))) &&
1829480093f4SDimitry Andric         X->getType() == Ty) {
1830480093f4SDimitry Andric       // fptrunc (select Cond, (fpext X), Y --> select Cond, X, (fptrunc Y)
1831480093f4SDimitry Andric       Value *NarrowY = Builder.CreateFPTrunc(Y, Ty);
1832480093f4SDimitry Andric       Value *Sel = Builder.CreateSelect(Cond, X, NarrowY, "narrow.sel", Op);
1833480093f4SDimitry Andric       return replaceInstUsesWith(FPT, Sel);
1834480093f4SDimitry Andric     }
1835480093f4SDimitry Andric     if (match(Op, m_Select(m_Value(Cond), m_Value(Y), m_FPExt(m_Value(X)))) &&
1836480093f4SDimitry Andric         X->getType() == Ty) {
1837480093f4SDimitry Andric       // fptrunc (select Cond, Y, (fpext X) --> select Cond, (fptrunc Y), X
1838480093f4SDimitry Andric       Value *NarrowY = Builder.CreateFPTrunc(Y, Ty);
1839480093f4SDimitry Andric       Value *Sel = Builder.CreateSelect(Cond, NarrowY, X, "narrow.sel", Op);
1840480093f4SDimitry Andric       return replaceInstUsesWith(FPT, Sel);
1841480093f4SDimitry Andric     }
18420b57cec5SDimitry Andric   }
18430b57cec5SDimitry Andric 
18440b57cec5SDimitry Andric   if (auto *II = dyn_cast<IntrinsicInst>(FPT.getOperand(0))) {
18450b57cec5SDimitry Andric     switch (II->getIntrinsicID()) {
18460b57cec5SDimitry Andric     default: break;
18470b57cec5SDimitry Andric     case Intrinsic::ceil:
18480b57cec5SDimitry Andric     case Intrinsic::fabs:
18490b57cec5SDimitry Andric     case Intrinsic::floor:
18500b57cec5SDimitry Andric     case Intrinsic::nearbyint:
18510b57cec5SDimitry Andric     case Intrinsic::rint:
18520b57cec5SDimitry Andric     case Intrinsic::round:
18535ffd83dbSDimitry Andric     case Intrinsic::roundeven:
18540b57cec5SDimitry Andric     case Intrinsic::trunc: {
18550b57cec5SDimitry Andric       Value *Src = II->getArgOperand(0);
18560b57cec5SDimitry Andric       if (!Src->hasOneUse())
18570b57cec5SDimitry Andric         break;
18580b57cec5SDimitry Andric 
18590b57cec5SDimitry Andric       // Except for fabs, this transformation requires the input of the unary FP
18600b57cec5SDimitry Andric       // operation to be itself an fpext from the type to which we're
18610b57cec5SDimitry Andric       // truncating.
18620b57cec5SDimitry Andric       if (II->getIntrinsicID() != Intrinsic::fabs) {
18630b57cec5SDimitry Andric         FPExtInst *FPExtSrc = dyn_cast<FPExtInst>(Src);
18640b57cec5SDimitry Andric         if (!FPExtSrc || FPExtSrc->getSrcTy() != Ty)
18650b57cec5SDimitry Andric           break;
18660b57cec5SDimitry Andric       }
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric       // Do unary FP operation on smaller type.
18690b57cec5SDimitry Andric       // (fptrunc (fabs x)) -> (fabs (fptrunc x))
18700b57cec5SDimitry Andric       Value *InnerTrunc = Builder.CreateFPTrunc(Src, Ty);
18710b57cec5SDimitry Andric       Function *Overload = Intrinsic::getDeclaration(FPT.getModule(),
18720b57cec5SDimitry Andric                                                      II->getIntrinsicID(), Ty);
18730b57cec5SDimitry Andric       SmallVector<OperandBundleDef, 1> OpBundles;
18740b57cec5SDimitry Andric       II->getOperandBundlesAsDefs(OpBundles);
18750b57cec5SDimitry Andric       CallInst *NewCI =
18760b57cec5SDimitry Andric           CallInst::Create(Overload, {InnerTrunc}, OpBundles, II->getName());
18770b57cec5SDimitry Andric       NewCI->copyFastMathFlags(II);
18780b57cec5SDimitry Andric       return NewCI;
18790b57cec5SDimitry Andric     }
18800b57cec5SDimitry Andric     }
18810b57cec5SDimitry Andric   }
18820b57cec5SDimitry Andric 
18830b57cec5SDimitry Andric   if (Instruction *I = shrinkInsertElt(FPT, Builder))
18840b57cec5SDimitry Andric     return I;
18850b57cec5SDimitry Andric 
18865ffd83dbSDimitry Andric   Value *Src = FPT.getOperand(0);
18875ffd83dbSDimitry Andric   if (isa<SIToFPInst>(Src) || isa<UIToFPInst>(Src)) {
18885ffd83dbSDimitry Andric     auto *FPCast = cast<CastInst>(Src);
188981ad6265SDimitry Andric     if (isKnownExactCastIntToFP(*FPCast, *this))
18905ffd83dbSDimitry Andric       return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);
18915ffd83dbSDimitry Andric   }
18925ffd83dbSDimitry Andric 
18930b57cec5SDimitry Andric   return nullptr;
18940b57cec5SDimitry Andric }
18950b57cec5SDimitry Andric 
1896e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) {
18975ffd83dbSDimitry Andric   // If the source operand is a cast from integer to FP and known exact, then
18985ffd83dbSDimitry Andric   // cast the integer operand directly to the destination type.
18995ffd83dbSDimitry Andric   Type *Ty = FPExt.getType();
19005ffd83dbSDimitry Andric   Value *Src = FPExt.getOperand(0);
19015ffd83dbSDimitry Andric   if (isa<SIToFPInst>(Src) || isa<UIToFPInst>(Src)) {
19025ffd83dbSDimitry Andric     auto *FPCast = cast<CastInst>(Src);
190381ad6265SDimitry Andric     if (isKnownExactCastIntToFP(*FPCast, *this))
19045ffd83dbSDimitry Andric       return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);
19050b57cec5SDimitry Andric   }
19060b57cec5SDimitry Andric 
19075ffd83dbSDimitry Andric   return commonCastTransforms(FPExt);
19085ffd83dbSDimitry Andric }
19095ffd83dbSDimitry Andric 
19105ffd83dbSDimitry Andric /// fpto{s/u}i({u/s}itofp(X)) --> X or zext(X) or sext(X) or trunc(X)
19115ffd83dbSDimitry Andric /// This is safe if the intermediate type has enough bits in its mantissa to
19125ffd83dbSDimitry Andric /// accurately represent all values of X.  For example, this won't work with
19135ffd83dbSDimitry Andric /// i64 -> float -> i64.
1914e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) {
19150b57cec5SDimitry Andric   if (!isa<UIToFPInst>(FI.getOperand(0)) && !isa<SIToFPInst>(FI.getOperand(0)))
19160b57cec5SDimitry Andric     return nullptr;
19170b57cec5SDimitry Andric 
19185ffd83dbSDimitry Andric   auto *OpI = cast<CastInst>(FI.getOperand(0));
19195ffd83dbSDimitry Andric   Value *X = OpI->getOperand(0);
19205ffd83dbSDimitry Andric   Type *XType = X->getType();
19215ffd83dbSDimitry Andric   Type *DestType = FI.getType();
19220b57cec5SDimitry Andric   bool IsOutputSigned = isa<FPToSIInst>(FI);
19230b57cec5SDimitry Andric 
19240b57cec5SDimitry Andric   // Since we can assume the conversion won't overflow, our decision as to
19250b57cec5SDimitry Andric   // whether the input will fit in the float should depend on the minimum
19260b57cec5SDimitry Andric   // of the input range and output range.
19270b57cec5SDimitry Andric 
19280b57cec5SDimitry Andric   // This means this is also safe for a signed input and unsigned output, since
19290b57cec5SDimitry Andric   // a negative input would lead to undefined behavior.
193081ad6265SDimitry Andric   if (!isKnownExactCastIntToFP(*OpI, *this)) {
19315ffd83dbSDimitry Andric     // The first cast may not round exactly based on the source integer width
19325ffd83dbSDimitry Andric     // and FP width, but the overflow UB rules can still allow this to fold.
19335ffd83dbSDimitry Andric     // If the destination type is narrow, that means the intermediate FP value
19345ffd83dbSDimitry Andric     // must be large enough to hold the source value exactly.
19355ffd83dbSDimitry Andric     // For example, (uint8_t)((float)(uint32_t 16777217) is undefined behavior.
193681ad6265SDimitry Andric     int OutputSize = (int)DestType->getScalarSizeInBits();
19375ffd83dbSDimitry Andric     if (OutputSize > OpI->getType()->getFPMantissaWidth())
19380b57cec5SDimitry Andric       return nullptr;
19390b57cec5SDimitry Andric   }
19400b57cec5SDimitry Andric 
19415ffd83dbSDimitry Andric   if (DestType->getScalarSizeInBits() > XType->getScalarSizeInBits()) {
19425ffd83dbSDimitry Andric     bool IsInputSigned = isa<SIToFPInst>(OpI);
19435ffd83dbSDimitry Andric     if (IsInputSigned && IsOutputSigned)
19445ffd83dbSDimitry Andric       return new SExtInst(X, DestType);
19455ffd83dbSDimitry Andric     return new ZExtInst(X, DestType);
19465ffd83dbSDimitry Andric   }
19475ffd83dbSDimitry Andric   if (DestType->getScalarSizeInBits() < XType->getScalarSizeInBits())
19485ffd83dbSDimitry Andric     return new TruncInst(X, DestType);
19490b57cec5SDimitry Andric 
19505ffd83dbSDimitry Andric   assert(XType == DestType && "Unexpected types for int to FP to int casts");
19515ffd83dbSDimitry Andric   return replaceInstUsesWith(FI, X);
19525ffd83dbSDimitry Andric }
19535ffd83dbSDimitry Andric 
1954*0fca6ea1SDimitry Andric static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) {
1955*0fca6ea1SDimitry Andric   // fpto{u/s}i non-norm --> 0
1956*0fca6ea1SDimitry Andric   FPClassTest Mask =
1957*0fca6ea1SDimitry Andric       FI.getOpcode() == Instruction::FPToUI ? fcPosNormal : fcNormal;
1958*0fca6ea1SDimitry Andric   KnownFPClass FPClass =
1959*0fca6ea1SDimitry Andric       computeKnownFPClass(FI.getOperand(0), Mask, /*Depth=*/0,
1960*0fca6ea1SDimitry Andric                           IC.getSimplifyQuery().getWithInstruction(&FI));
1961*0fca6ea1SDimitry Andric   if (FPClass.isKnownNever(Mask))
1962*0fca6ea1SDimitry Andric     return IC.replaceInstUsesWith(FI, ConstantInt::getNullValue(FI.getType()));
1963*0fca6ea1SDimitry Andric 
1964*0fca6ea1SDimitry Andric   return nullptr;
1965*0fca6ea1SDimitry Andric }
1966*0fca6ea1SDimitry Andric 
1967e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) {
19685ffd83dbSDimitry Andric   if (Instruction *I = foldItoFPtoI(FI))
19690b57cec5SDimitry Andric     return I;
19700b57cec5SDimitry Andric 
1971*0fca6ea1SDimitry Andric   if (Instruction *I = foldFPtoI(FI, *this))
1972*0fca6ea1SDimitry Andric     return I;
1973*0fca6ea1SDimitry Andric 
19740b57cec5SDimitry Andric   return commonCastTransforms(FI);
19750b57cec5SDimitry Andric }
19760b57cec5SDimitry Andric 
1977e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) {
19785ffd83dbSDimitry Andric   if (Instruction *I = foldItoFPtoI(FI))
19790b57cec5SDimitry Andric     return I;
19800b57cec5SDimitry Andric 
1981*0fca6ea1SDimitry Andric   if (Instruction *I = foldFPtoI(FI, *this))
1982*0fca6ea1SDimitry Andric     return I;
1983*0fca6ea1SDimitry Andric 
19840b57cec5SDimitry Andric   return commonCastTransforms(FI);
19850b57cec5SDimitry Andric }
19860b57cec5SDimitry Andric 
1987e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) {
1988*0fca6ea1SDimitry Andric   if (Instruction *R = commonCastTransforms(CI))
1989*0fca6ea1SDimitry Andric     return R;
1990*0fca6ea1SDimitry Andric   if (!CI.hasNonNeg() && isKnownNonNegative(CI.getOperand(0), SQ)) {
1991*0fca6ea1SDimitry Andric     CI.setNonNeg();
1992*0fca6ea1SDimitry Andric     return &CI;
1993*0fca6ea1SDimitry Andric   }
1994*0fca6ea1SDimitry Andric   return nullptr;
19950b57cec5SDimitry Andric }
19960b57cec5SDimitry Andric 
1997e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) {
1998*0fca6ea1SDimitry Andric   if (Instruction *R = commonCastTransforms(CI))
1999*0fca6ea1SDimitry Andric     return R;
2000*0fca6ea1SDimitry Andric   if (isKnownNonNegative(CI.getOperand(0), SQ)) {
2001*0fca6ea1SDimitry Andric     auto *UI =
2002*0fca6ea1SDimitry Andric         CastInst::Create(Instruction::UIToFP, CI.getOperand(0), CI.getType());
2003*0fca6ea1SDimitry Andric     UI->setNonNeg(true);
2004*0fca6ea1SDimitry Andric     return UI;
2005*0fca6ea1SDimitry Andric   }
2006*0fca6ea1SDimitry Andric   return nullptr;
20070b57cec5SDimitry Andric }
20080b57cec5SDimitry Andric 
2009e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
20100b57cec5SDimitry Andric   // If the source integer type is not the intptr_t type for this target, do a
20110b57cec5SDimitry Andric   // trunc or zext to the intptr_t type, then inttoptr of it.  This allows the
20120b57cec5SDimitry Andric   // cast to be exposed to other transforms.
20130b57cec5SDimitry Andric   unsigned AS = CI.getAddressSpace();
20140b57cec5SDimitry Andric   if (CI.getOperand(0)->getType()->getScalarSizeInBits() !=
20150b57cec5SDimitry Andric       DL.getPointerSizeInBits(AS)) {
2016fe6060f1SDimitry Andric     Type *Ty = CI.getOperand(0)->getType()->getWithNewType(
2017fe6060f1SDimitry Andric         DL.getIntPtrType(CI.getContext(), AS));
20180b57cec5SDimitry Andric     Value *P = Builder.CreateZExtOrTrunc(CI.getOperand(0), Ty);
20190b57cec5SDimitry Andric     return new IntToPtrInst(P, CI.getType());
20200b57cec5SDimitry Andric   }
20210b57cec5SDimitry Andric 
20220b57cec5SDimitry Andric   if (Instruction *I = commonCastTransforms(CI))
20230b57cec5SDimitry Andric     return I;
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   return nullptr;
20260b57cec5SDimitry Andric }
20270b57cec5SDimitry Andric 
2028e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
20290b57cec5SDimitry Andric   // If the destination integer type is not the intptr_t type for this target,
20300b57cec5SDimitry Andric   // do a ptrtoint to intptr_t then do a trunc or zext.  This allows the cast
20310b57cec5SDimitry Andric   // to be exposed to other transforms.
2032e8d8bef9SDimitry Andric   Value *SrcOp = CI.getPointerOperand();
2033fe6060f1SDimitry Andric   Type *SrcTy = SrcOp->getType();
20340b57cec5SDimitry Andric   Type *Ty = CI.getType();
20350b57cec5SDimitry Andric   unsigned AS = CI.getPointerAddressSpace();
2036e8d8bef9SDimitry Andric   unsigned TySize = Ty->getScalarSizeInBits();
2037e8d8bef9SDimitry Andric   unsigned PtrSize = DL.getPointerSizeInBits(AS);
2038e8d8bef9SDimitry Andric   if (TySize != PtrSize) {
2039fe6060f1SDimitry Andric     Type *IntPtrTy =
2040fe6060f1SDimitry Andric         SrcTy->getWithNewType(DL.getIntPtrType(CI.getContext(), AS));
2041e8d8bef9SDimitry Andric     Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy);
2042e8d8bef9SDimitry Andric     return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false);
20435ffd83dbSDimitry Andric   }
20440b57cec5SDimitry Andric 
20455f757f3fSDimitry Andric   // (ptrtoint (ptrmask P, M))
20465f757f3fSDimitry Andric   //    -> (and (ptrtoint P), M)
20475f757f3fSDimitry Andric   // This is generally beneficial as `and` is better supported than `ptrmask`.
20485f757f3fSDimitry Andric   Value *Ptr, *Mask;
20495f757f3fSDimitry Andric   if (match(SrcOp, m_OneUse(m_Intrinsic<Intrinsic::ptrmask>(m_Value(Ptr),
20505f757f3fSDimitry Andric                                                             m_Value(Mask)))) &&
20515f757f3fSDimitry Andric       Mask->getType() == Ty)
20525f757f3fSDimitry Andric     return BinaryOperator::CreateAnd(Builder.CreatePtrToInt(Ptr, Ty), Mask);
20535f757f3fSDimitry Andric 
2054*0fca6ea1SDimitry Andric   if (auto *GEP = dyn_cast<GEPOperator>(SrcOp)) {
2055349cc55cSDimitry Andric     // Fold ptrtoint(gep null, x) to multiply + constant if the GEP has one use.
2056349cc55cSDimitry Andric     // While this can increase the number of instructions it doesn't actually
2057349cc55cSDimitry Andric     // increase the overall complexity since the arithmetic is just part of
2058349cc55cSDimitry Andric     // the GEP otherwise.
2059349cc55cSDimitry Andric     if (GEP->hasOneUse() &&
2060349cc55cSDimitry Andric         isa<ConstantPointerNull>(GEP->getPointerOperand())) {
2061349cc55cSDimitry Andric       return replaceInstUsesWith(CI,
2062349cc55cSDimitry Andric                                  Builder.CreateIntCast(EmitGEPOffset(GEP), Ty,
2063349cc55cSDimitry Andric                                                        /*isSigned=*/false));
2064349cc55cSDimitry Andric     }
2065*0fca6ea1SDimitry Andric 
2066*0fca6ea1SDimitry Andric     // (ptrtoint (gep (inttoptr Base), ...)) -> Base + Offset
2067*0fca6ea1SDimitry Andric     Value *Base;
2068*0fca6ea1SDimitry Andric     if (GEP->hasOneUse() &&
2069*0fca6ea1SDimitry Andric         match(GEP->getPointerOperand(), m_OneUse(m_IntToPtr(m_Value(Base)))) &&
2070*0fca6ea1SDimitry Andric         Base->getType() == Ty) {
2071*0fca6ea1SDimitry Andric       Value *Offset = EmitGEPOffset(GEP);
2072*0fca6ea1SDimitry Andric       auto *NewOp = BinaryOperator::CreateAdd(Base, Offset);
2073*0fca6ea1SDimitry Andric       if (GEP->hasNoUnsignedWrap() ||
2074*0fca6ea1SDimitry Andric           (GEP->hasNoUnsignedSignedWrap() &&
2075*0fca6ea1SDimitry Andric            isKnownNonNegative(Offset, SQ.getWithInstruction(&CI))))
2076*0fca6ea1SDimitry Andric         NewOp->setHasNoUnsignedWrap(true);
2077*0fca6ea1SDimitry Andric       return NewOp;
2078*0fca6ea1SDimitry Andric     }
2079349cc55cSDimitry Andric   }
2080349cc55cSDimitry Andric 
2081e8d8bef9SDimitry Andric   Value *Vec, *Scalar, *Index;
2082e8d8bef9SDimitry Andric   if (match(SrcOp, m_OneUse(m_InsertElt(m_IntToPtr(m_Value(Vec)),
2083e8d8bef9SDimitry Andric                                         m_Value(Scalar), m_Value(Index)))) &&
2084e8d8bef9SDimitry Andric       Vec->getType() == Ty) {
2085e8d8bef9SDimitry Andric     assert(Vec->getType()->getScalarSizeInBits() == PtrSize && "Wrong type");
2086e8d8bef9SDimitry Andric     // Convert the scalar to int followed by insert to eliminate one cast:
2087e8d8bef9SDimitry Andric     // p2i (ins (i2p Vec), Scalar, Index --> ins Vec, (p2i Scalar), Index
2088e8d8bef9SDimitry Andric     Value *NewCast = Builder.CreatePtrToInt(Scalar, Ty->getScalarType());
2089e8d8bef9SDimitry Andric     return InsertElementInst::Create(Vec, NewCast, Index);
2090e8d8bef9SDimitry Andric   }
2091e8d8bef9SDimitry Andric 
20925f757f3fSDimitry Andric   return commonCastTransforms(CI);
20930b57cec5SDimitry Andric }
20940b57cec5SDimitry Andric 
20950b57cec5SDimitry Andric /// This input value (which is known to have vector type) is being zero extended
2096480093f4SDimitry Andric /// or truncated to the specified vector type. Since the zext/trunc is done
2097480093f4SDimitry Andric /// using an integer type, we have a (bitcast(cast(bitcast))) pattern,
2098480093f4SDimitry Andric /// endianness will impact which end of the vector that is extended or
2099480093f4SDimitry Andric /// truncated.
2100480093f4SDimitry Andric ///
2101480093f4SDimitry Andric /// A vector is always stored with index 0 at the lowest address, which
2102480093f4SDimitry Andric /// corresponds to the most significant bits for a big endian stored integer and
2103480093f4SDimitry Andric /// the least significant bits for little endian. A trunc/zext of an integer
2104480093f4SDimitry Andric /// impacts the big end of the integer. Thus, we need to add/remove elements at
2105480093f4SDimitry Andric /// the front of the vector for big endian targets, and the back of the vector
2106480093f4SDimitry Andric /// for little endian targets.
2107480093f4SDimitry Andric ///
21080b57cec5SDimitry Andric /// Try to replace it with a shuffle (and vector/vector bitcast) if possible.
21090b57cec5SDimitry Andric ///
21100b57cec5SDimitry Andric /// The source and destination vector types may have different element types.
2111e8d8bef9SDimitry Andric static Instruction *
2112e8d8bef9SDimitry Andric optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy,
2113e8d8bef9SDimitry Andric                                         InstCombinerImpl &IC) {
21140b57cec5SDimitry Andric   // We can only do this optimization if the output is a multiple of the input
21150b57cec5SDimitry Andric   // element size, or the input is a multiple of the output element size.
21160b57cec5SDimitry Andric   // Convert the input type to have the same element type as the output.
21170b57cec5SDimitry Andric   VectorType *SrcTy = cast<VectorType>(InVal->getType());
21180b57cec5SDimitry Andric 
21190b57cec5SDimitry Andric   if (SrcTy->getElementType() != DestTy->getElementType()) {
21200b57cec5SDimitry Andric     // The input types don't need to be identical, but for now they must be the
21210b57cec5SDimitry Andric     // same size.  There is no specific reason we couldn't handle things like
21220b57cec5SDimitry Andric     // <4 x i16> -> <4 x i32> by bitcasting to <2 x i32> but haven't gotten
21230b57cec5SDimitry Andric     // there yet.
21240b57cec5SDimitry Andric     if (SrcTy->getElementType()->getPrimitiveSizeInBits() !=
21250b57cec5SDimitry Andric         DestTy->getElementType()->getPrimitiveSizeInBits())
21260b57cec5SDimitry Andric       return nullptr;
21270b57cec5SDimitry Andric 
21285ffd83dbSDimitry Andric     SrcTy =
2129e8d8bef9SDimitry Andric         FixedVectorType::get(DestTy->getElementType(),
2130e8d8bef9SDimitry Andric                              cast<FixedVectorType>(SrcTy)->getNumElements());
21310b57cec5SDimitry Andric     InVal = IC.Builder.CreateBitCast(InVal, SrcTy);
21320b57cec5SDimitry Andric   }
21330b57cec5SDimitry Andric 
2134480093f4SDimitry Andric   bool IsBigEndian = IC.getDataLayout().isBigEndian();
2135e8d8bef9SDimitry Andric   unsigned SrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
2136e8d8bef9SDimitry Andric   unsigned DestElts = cast<FixedVectorType>(DestTy)->getNumElements();
2137480093f4SDimitry Andric 
2138480093f4SDimitry Andric   assert(SrcElts != DestElts && "Element counts should be different.");
2139480093f4SDimitry Andric 
21400b57cec5SDimitry Andric   // Now that the element types match, get the shuffle mask and RHS of the
21410b57cec5SDimitry Andric   // shuffle to use, which depends on whether we're increasing or decreasing the
21420b57cec5SDimitry Andric   // size of the input.
214381ad6265SDimitry Andric   auto ShuffleMaskStorage = llvm::to_vector<16>(llvm::seq<int>(0, SrcElts));
21445ffd83dbSDimitry Andric   ArrayRef<int> ShuffleMask;
21450b57cec5SDimitry Andric   Value *V2;
21460b57cec5SDimitry Andric 
2147480093f4SDimitry Andric   if (SrcElts > DestElts) {
2148480093f4SDimitry Andric     // If we're shrinking the number of elements (rewriting an integer
2149480093f4SDimitry Andric     // truncate), just shuffle in the elements corresponding to the least
2150349cc55cSDimitry Andric     // significant bits from the input and use poison as the second shuffle
2151480093f4SDimitry Andric     // input.
2152349cc55cSDimitry Andric     V2 = PoisonValue::get(SrcTy);
2153480093f4SDimitry Andric     // Make sure the shuffle mask selects the "least significant bits" by
2154480093f4SDimitry Andric     // keeping elements from back of the src vector for big endian, and from the
2155480093f4SDimitry Andric     // front for little endian.
2156480093f4SDimitry Andric     ShuffleMask = ShuffleMaskStorage;
2157480093f4SDimitry Andric     if (IsBigEndian)
2158480093f4SDimitry Andric       ShuffleMask = ShuffleMask.take_back(DestElts);
2159480093f4SDimitry Andric     else
2160480093f4SDimitry Andric       ShuffleMask = ShuffleMask.take_front(DestElts);
21610b57cec5SDimitry Andric   } else {
2162480093f4SDimitry Andric     // If we're increasing the number of elements (rewriting an integer zext),
2163480093f4SDimitry Andric     // shuffle in all of the elements from InVal. Fill the rest of the result
2164480093f4SDimitry Andric     // elements with zeros from a constant zero.
21650b57cec5SDimitry Andric     V2 = Constant::getNullValue(SrcTy);
2166480093f4SDimitry Andric     // Use first elt from V2 when indicating zero in the shuffle mask.
2167480093f4SDimitry Andric     uint32_t NullElt = SrcElts;
2168480093f4SDimitry Andric     // Extend with null values in the "most significant bits" by adding elements
2169480093f4SDimitry Andric     // in front of the src vector for big endian, and at the back for little
2170480093f4SDimitry Andric     // endian.
2171480093f4SDimitry Andric     unsigned DeltaElts = DestElts - SrcElts;
2172480093f4SDimitry Andric     if (IsBigEndian)
2173480093f4SDimitry Andric       ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt);
2174480093f4SDimitry Andric     else
2175480093f4SDimitry Andric       ShuffleMaskStorage.append(DeltaElts, NullElt);
2176480093f4SDimitry Andric     ShuffleMask = ShuffleMaskStorage;
21770b57cec5SDimitry Andric   }
21780b57cec5SDimitry Andric 
21795ffd83dbSDimitry Andric   return new ShuffleVectorInst(InVal, V2, ShuffleMask);
21800b57cec5SDimitry Andric }
21810b57cec5SDimitry Andric 
21820b57cec5SDimitry Andric static bool isMultipleOfTypeSize(unsigned Value, Type *Ty) {
21830b57cec5SDimitry Andric   return Value % Ty->getPrimitiveSizeInBits() == 0;
21840b57cec5SDimitry Andric }
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric static unsigned getTypeSizeIndex(unsigned Value, Type *Ty) {
21870b57cec5SDimitry Andric   return Value / Ty->getPrimitiveSizeInBits();
21880b57cec5SDimitry Andric }
21890b57cec5SDimitry Andric 
21900b57cec5SDimitry Andric /// V is a value which is inserted into a vector of VecEltTy.
21910b57cec5SDimitry Andric /// Look through the value to see if we can decompose it into
21920b57cec5SDimitry Andric /// insertions into the vector.  See the example in the comment for
21930b57cec5SDimitry Andric /// OptimizeIntegerToVectorInsertions for the pattern this handles.
21940b57cec5SDimitry Andric /// The type of V is always a non-zero multiple of VecEltTy's size.
21950b57cec5SDimitry Andric /// Shift is the number of bits between the lsb of V and the lsb of
21960b57cec5SDimitry Andric /// the vector.
21970b57cec5SDimitry Andric ///
21980b57cec5SDimitry Andric /// This returns false if the pattern can't be matched or true if it can,
21990b57cec5SDimitry Andric /// filling in Elements with the elements found here.
22000b57cec5SDimitry Andric static bool collectInsertionElements(Value *V, unsigned Shift,
22010b57cec5SDimitry Andric                                      SmallVectorImpl<Value *> &Elements,
22020b57cec5SDimitry Andric                                      Type *VecEltTy, bool isBigEndian) {
22030b57cec5SDimitry Andric   assert(isMultipleOfTypeSize(Shift, VecEltTy) &&
22040b57cec5SDimitry Andric          "Shift should be a multiple of the element type size");
22050b57cec5SDimitry Andric 
22060b57cec5SDimitry Andric   // Undef values never contribute useful bits to the result.
22070b57cec5SDimitry Andric   if (isa<UndefValue>(V)) return true;
22080b57cec5SDimitry Andric 
22090b57cec5SDimitry Andric   // If we got down to a value of the right type, we win, try inserting into the
22100b57cec5SDimitry Andric   // right element.
22110b57cec5SDimitry Andric   if (V->getType() == VecEltTy) {
22120b57cec5SDimitry Andric     // Inserting null doesn't actually insert any elements.
22130b57cec5SDimitry Andric     if (Constant *C = dyn_cast<Constant>(V))
22140b57cec5SDimitry Andric       if (C->isNullValue())
22150b57cec5SDimitry Andric         return true;
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric     unsigned ElementIndex = getTypeSizeIndex(Shift, VecEltTy);
22180b57cec5SDimitry Andric     if (isBigEndian)
22190b57cec5SDimitry Andric       ElementIndex = Elements.size() - ElementIndex - 1;
22200b57cec5SDimitry Andric 
22210b57cec5SDimitry Andric     // Fail if multiple elements are inserted into this slot.
22220b57cec5SDimitry Andric     if (Elements[ElementIndex])
22230b57cec5SDimitry Andric       return false;
22240b57cec5SDimitry Andric 
22250b57cec5SDimitry Andric     Elements[ElementIndex] = V;
22260b57cec5SDimitry Andric     return true;
22270b57cec5SDimitry Andric   }
22280b57cec5SDimitry Andric 
22290b57cec5SDimitry Andric   if (Constant *C = dyn_cast<Constant>(V)) {
22300b57cec5SDimitry Andric     // Figure out the # elements this provides, and bitcast it or slice it up
22310b57cec5SDimitry Andric     // as required.
22320b57cec5SDimitry Andric     unsigned NumElts = getTypeSizeIndex(C->getType()->getPrimitiveSizeInBits(),
22330b57cec5SDimitry Andric                                         VecEltTy);
22340b57cec5SDimitry Andric     // If the constant is the size of a vector element, we just need to bitcast
22350b57cec5SDimitry Andric     // it to the right type so it gets properly inserted.
22360b57cec5SDimitry Andric     if (NumElts == 1)
22370b57cec5SDimitry Andric       return collectInsertionElements(ConstantExpr::getBitCast(C, VecEltTy),
22380b57cec5SDimitry Andric                                       Shift, Elements, VecEltTy, isBigEndian);
22390b57cec5SDimitry Andric 
22400b57cec5SDimitry Andric     // Okay, this is a constant that covers multiple elements.  Slice it up into
22410b57cec5SDimitry Andric     // pieces and insert each element-sized piece into the vector.
22420b57cec5SDimitry Andric     if (!isa<IntegerType>(C->getType()))
22430b57cec5SDimitry Andric       C = ConstantExpr::getBitCast(C, IntegerType::get(V->getContext(),
22440b57cec5SDimitry Andric                                        C->getType()->getPrimitiveSizeInBits()));
22450b57cec5SDimitry Andric     unsigned ElementSize = VecEltTy->getPrimitiveSizeInBits();
22460b57cec5SDimitry Andric     Type *ElementIntTy = IntegerType::get(C->getContext(), ElementSize);
22470b57cec5SDimitry Andric 
22480b57cec5SDimitry Andric     for (unsigned i = 0; i != NumElts; ++i) {
2249439352acSDimitry Andric       unsigned ShiftI = i * ElementSize;
22505f757f3fSDimitry Andric       Constant *Piece = ConstantFoldBinaryInstruction(
22515f757f3fSDimitry Andric           Instruction::LShr, C, ConstantInt::get(C->getType(), ShiftI));
22525f757f3fSDimitry Andric       if (!Piece)
22535f757f3fSDimitry Andric         return false;
22545f757f3fSDimitry Andric 
22550b57cec5SDimitry Andric       Piece = ConstantExpr::getTrunc(Piece, ElementIntTy);
2256439352acSDimitry Andric       if (!collectInsertionElements(Piece, ShiftI + Shift, Elements, VecEltTy,
22570b57cec5SDimitry Andric                                     isBigEndian))
22580b57cec5SDimitry Andric         return false;
22590b57cec5SDimitry Andric     }
22600b57cec5SDimitry Andric     return true;
22610b57cec5SDimitry Andric   }
22620b57cec5SDimitry Andric 
22630b57cec5SDimitry Andric   if (!V->hasOneUse()) return false;
22640b57cec5SDimitry Andric 
22650b57cec5SDimitry Andric   Instruction *I = dyn_cast<Instruction>(V);
22660b57cec5SDimitry Andric   if (!I) return false;
22670b57cec5SDimitry Andric   switch (I->getOpcode()) {
22680b57cec5SDimitry Andric   default: return false; // Unhandled case.
22690b57cec5SDimitry Andric   case Instruction::BitCast:
227081ad6265SDimitry Andric     if (I->getOperand(0)->getType()->isVectorTy())
227181ad6265SDimitry Andric       return false;
22720b57cec5SDimitry Andric     return collectInsertionElements(I->getOperand(0), Shift, Elements, VecEltTy,
22730b57cec5SDimitry Andric                                     isBigEndian);
22740b57cec5SDimitry Andric   case Instruction::ZExt:
22750b57cec5SDimitry Andric     if (!isMultipleOfTypeSize(
22760b57cec5SDimitry Andric                           I->getOperand(0)->getType()->getPrimitiveSizeInBits(),
22770b57cec5SDimitry Andric                               VecEltTy))
22780b57cec5SDimitry Andric       return false;
22790b57cec5SDimitry Andric     return collectInsertionElements(I->getOperand(0), Shift, Elements, VecEltTy,
22800b57cec5SDimitry Andric                                     isBigEndian);
22810b57cec5SDimitry Andric   case Instruction::Or:
22820b57cec5SDimitry Andric     return collectInsertionElements(I->getOperand(0), Shift, Elements, VecEltTy,
22830b57cec5SDimitry Andric                                     isBigEndian) &&
22840b57cec5SDimitry Andric            collectInsertionElements(I->getOperand(1), Shift, Elements, VecEltTy,
22850b57cec5SDimitry Andric                                     isBigEndian);
22860b57cec5SDimitry Andric   case Instruction::Shl: {
22870b57cec5SDimitry Andric     // Must be shifting by a constant that is a multiple of the element size.
22880b57cec5SDimitry Andric     ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
22890b57cec5SDimitry Andric     if (!CI) return false;
22900b57cec5SDimitry Andric     Shift += CI->getZExtValue();
22910b57cec5SDimitry Andric     if (!isMultipleOfTypeSize(Shift, VecEltTy)) return false;
22920b57cec5SDimitry Andric     return collectInsertionElements(I->getOperand(0), Shift, Elements, VecEltTy,
22930b57cec5SDimitry Andric                                     isBigEndian);
22940b57cec5SDimitry Andric   }
22950b57cec5SDimitry Andric 
22960b57cec5SDimitry Andric   }
22970b57cec5SDimitry Andric }
22980b57cec5SDimitry Andric 
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric /// If the input is an 'or' instruction, we may be doing shifts and ors to
23010b57cec5SDimitry Andric /// assemble the elements of the vector manually.
23020b57cec5SDimitry Andric /// Try to rip the code out and replace it with insertelements.  This is to
23030b57cec5SDimitry Andric /// optimize code like this:
23040b57cec5SDimitry Andric ///
23050b57cec5SDimitry Andric ///    %tmp37 = bitcast float %inc to i32
23060b57cec5SDimitry Andric ///    %tmp38 = zext i32 %tmp37 to i64
23070b57cec5SDimitry Andric ///    %tmp31 = bitcast float %inc5 to i32
23080b57cec5SDimitry Andric ///    %tmp32 = zext i32 %tmp31 to i64
23090b57cec5SDimitry Andric ///    %tmp33 = shl i64 %tmp32, 32
23100b57cec5SDimitry Andric ///    %ins35 = or i64 %tmp33, %tmp38
23110b57cec5SDimitry Andric ///    %tmp43 = bitcast i64 %ins35 to <2 x float>
23120b57cec5SDimitry Andric ///
23130b57cec5SDimitry Andric /// Into two insertelements that do "buildvector{%inc, %inc5}".
23140b57cec5SDimitry Andric static Value *optimizeIntegerToVectorInsertions(BitCastInst &CI,
2315e8d8bef9SDimitry Andric                                                 InstCombinerImpl &IC) {
2316e8d8bef9SDimitry Andric   auto *DestVecTy = cast<FixedVectorType>(CI.getType());
23170b57cec5SDimitry Andric   Value *IntInput = CI.getOperand(0);
23180b57cec5SDimitry Andric 
23190b57cec5SDimitry Andric   SmallVector<Value*, 8> Elements(DestVecTy->getNumElements());
23200b57cec5SDimitry Andric   if (!collectInsertionElements(IntInput, 0, Elements,
23210b57cec5SDimitry Andric                                 DestVecTy->getElementType(),
23220b57cec5SDimitry Andric                                 IC.getDataLayout().isBigEndian()))
23230b57cec5SDimitry Andric     return nullptr;
23240b57cec5SDimitry Andric 
23250b57cec5SDimitry Andric   // If we succeeded, we know that all of the element are specified by Elements
23260b57cec5SDimitry Andric   // or are zero if Elements has a null entry.  Recast this as a set of
23270b57cec5SDimitry Andric   // insertions.
23280b57cec5SDimitry Andric   Value *Result = Constant::getNullValue(CI.getType());
23290b57cec5SDimitry Andric   for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
23300b57cec5SDimitry Andric     if (!Elements[i]) continue;  // Unset element.
23310b57cec5SDimitry Andric 
23320b57cec5SDimitry Andric     Result = IC.Builder.CreateInsertElement(Result, Elements[i],
23330b57cec5SDimitry Andric                                             IC.Builder.getInt32(i));
23340b57cec5SDimitry Andric   }
23350b57cec5SDimitry Andric 
23360b57cec5SDimitry Andric   return Result;
23370b57cec5SDimitry Andric }
23380b57cec5SDimitry Andric 
23390b57cec5SDimitry Andric /// Canonicalize scalar bitcasts of extracted elements into a bitcast of the
23400b57cec5SDimitry Andric /// vector followed by extract element. The backend tends to handle bitcasts of
23410b57cec5SDimitry Andric /// vectors better than bitcasts of scalars because vector registers are
23420b57cec5SDimitry Andric /// usually not type-specific like scalar integer or scalar floating-point.
23430b57cec5SDimitry Andric static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast,
2344e8d8bef9SDimitry Andric                                               InstCombinerImpl &IC) {
234581ad6265SDimitry Andric   Value *VecOp, *Index;
234681ad6265SDimitry Andric   if (!match(BitCast.getOperand(0),
234781ad6265SDimitry Andric              m_OneUse(m_ExtractElt(m_Value(VecOp), m_Value(Index)))))
23480b57cec5SDimitry Andric     return nullptr;
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric   // The bitcast must be to a vectorizable type, otherwise we can't make a new
23510b57cec5SDimitry Andric   // type to extract from.
23520b57cec5SDimitry Andric   Type *DestType = BitCast.getType();
235381ad6265SDimitry Andric   VectorType *VecType = cast<VectorType>(VecOp->getType());
235481ad6265SDimitry Andric   if (VectorType::isValidElementType(DestType)) {
235581ad6265SDimitry Andric     auto *NewVecType = VectorType::get(DestType, VecType);
235681ad6265SDimitry Andric     auto *NewBC = IC.Builder.CreateBitCast(VecOp, NewVecType, "bc");
235781ad6265SDimitry Andric     return ExtractElementInst::Create(NewBC, Index);
235881ad6265SDimitry Andric   }
23590b57cec5SDimitry Andric 
236081ad6265SDimitry Andric   // Only solve DestType is vector to avoid inverse transform in visitBitCast.
236181ad6265SDimitry Andric   // bitcast (extractelement <1 x elt>, dest) -> bitcast(<1 x elt>, dest)
236281ad6265SDimitry Andric   auto *FixedVType = dyn_cast<FixedVectorType>(VecType);
236381ad6265SDimitry Andric   if (DestType->isVectorTy() && FixedVType && FixedVType->getNumElements() == 1)
236481ad6265SDimitry Andric     return CastInst::Create(Instruction::BitCast, VecOp, DestType);
236581ad6265SDimitry Andric 
236681ad6265SDimitry Andric   return nullptr;
23670b57cec5SDimitry Andric }
23680b57cec5SDimitry Andric 
23690b57cec5SDimitry Andric /// Change the type of a bitwise logic operation if we can eliminate a bitcast.
23700b57cec5SDimitry Andric static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast,
23710b57cec5SDimitry Andric                                             InstCombiner::BuilderTy &Builder) {
23720b57cec5SDimitry Andric   Type *DestTy = BitCast.getType();
23730b57cec5SDimitry Andric   BinaryOperator *BO;
237481ad6265SDimitry Andric 
237581ad6265SDimitry Andric   if (!match(BitCast.getOperand(0), m_OneUse(m_BinOp(BO))) ||
23760b57cec5SDimitry Andric       !BO->isBitwiseLogicOp())
23770b57cec5SDimitry Andric     return nullptr;
23780b57cec5SDimitry Andric 
23790b57cec5SDimitry Andric   // FIXME: This transform is restricted to vector types to avoid backend
23800b57cec5SDimitry Andric   // problems caused by creating potentially illegal operations. If a fix-up is
23810b57cec5SDimitry Andric   // added to handle that situation, we can remove this check.
23820b57cec5SDimitry Andric   if (!DestTy->isVectorTy() || !BO->getType()->isVectorTy())
23830b57cec5SDimitry Andric     return nullptr;
23840b57cec5SDimitry Andric 
238581ad6265SDimitry Andric   if (DestTy->isFPOrFPVectorTy()) {
238681ad6265SDimitry Andric     Value *X, *Y;
238781ad6265SDimitry Andric     // bitcast(logic(bitcast(X), bitcast(Y))) -> bitcast'(logic(bitcast'(X), Y))
238881ad6265SDimitry Andric     if (match(BO->getOperand(0), m_OneUse(m_BitCast(m_Value(X)))) &&
238981ad6265SDimitry Andric         match(BO->getOperand(1), m_OneUse(m_BitCast(m_Value(Y))))) {
239081ad6265SDimitry Andric       if (X->getType()->isFPOrFPVectorTy() &&
239181ad6265SDimitry Andric           Y->getType()->isIntOrIntVectorTy()) {
239281ad6265SDimitry Andric         Value *CastedOp =
239381ad6265SDimitry Andric             Builder.CreateBitCast(BO->getOperand(0), Y->getType());
239481ad6265SDimitry Andric         Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, Y);
239581ad6265SDimitry Andric         return CastInst::CreateBitOrPointerCast(NewBO, DestTy);
239681ad6265SDimitry Andric       }
239781ad6265SDimitry Andric       if (X->getType()->isIntOrIntVectorTy() &&
239881ad6265SDimitry Andric           Y->getType()->isFPOrFPVectorTy()) {
239981ad6265SDimitry Andric         Value *CastedOp =
240081ad6265SDimitry Andric             Builder.CreateBitCast(BO->getOperand(1), X->getType());
240181ad6265SDimitry Andric         Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, X);
240281ad6265SDimitry Andric         return CastInst::CreateBitOrPointerCast(NewBO, DestTy);
240381ad6265SDimitry Andric       }
240481ad6265SDimitry Andric     }
240581ad6265SDimitry Andric     return nullptr;
240681ad6265SDimitry Andric   }
240781ad6265SDimitry Andric 
240881ad6265SDimitry Andric   if (!DestTy->isIntOrIntVectorTy())
240981ad6265SDimitry Andric     return nullptr;
241081ad6265SDimitry Andric 
24110b57cec5SDimitry Andric   Value *X;
24120b57cec5SDimitry Andric   if (match(BO->getOperand(0), m_OneUse(m_BitCast(m_Value(X)))) &&
24130b57cec5SDimitry Andric       X->getType() == DestTy && !isa<Constant>(X)) {
24140b57cec5SDimitry Andric     // bitcast(logic(bitcast(X), Y)) --> logic'(X, bitcast(Y))
24150b57cec5SDimitry Andric     Value *CastedOp1 = Builder.CreateBitCast(BO->getOperand(1), DestTy);
24160b57cec5SDimitry Andric     return BinaryOperator::Create(BO->getOpcode(), X, CastedOp1);
24170b57cec5SDimitry Andric   }
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric   if (match(BO->getOperand(1), m_OneUse(m_BitCast(m_Value(X)))) &&
24200b57cec5SDimitry Andric       X->getType() == DestTy && !isa<Constant>(X)) {
24210b57cec5SDimitry Andric     // bitcast(logic(Y, bitcast(X))) --> logic'(bitcast(Y), X)
24220b57cec5SDimitry Andric     Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);
24230b57cec5SDimitry Andric     return BinaryOperator::Create(BO->getOpcode(), CastedOp0, X);
24240b57cec5SDimitry Andric   }
24250b57cec5SDimitry Andric 
24260b57cec5SDimitry Andric   // Canonicalize vector bitcasts to come before vector bitwise logic with a
24270b57cec5SDimitry Andric   // constant. This eases recognition of special constants for later ops.
24280b57cec5SDimitry Andric   // Example:
24290b57cec5SDimitry Andric   // icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b
24300b57cec5SDimitry Andric   Constant *C;
24310b57cec5SDimitry Andric   if (match(BO->getOperand(1), m_Constant(C))) {
24320b57cec5SDimitry Andric     // bitcast (logic X, C) --> logic (bitcast X, C')
24330b57cec5SDimitry Andric     Value *CastedOp0 = Builder.CreateBitCast(BO->getOperand(0), DestTy);
24345ffd83dbSDimitry Andric     Value *CastedC = Builder.CreateBitCast(C, DestTy);
24350b57cec5SDimitry Andric     return BinaryOperator::Create(BO->getOpcode(), CastedOp0, CastedC);
24360b57cec5SDimitry Andric   }
24370b57cec5SDimitry Andric 
24380b57cec5SDimitry Andric   return nullptr;
24390b57cec5SDimitry Andric }
24400b57cec5SDimitry Andric 
24410b57cec5SDimitry Andric /// Change the type of a select if we can eliminate a bitcast.
24420b57cec5SDimitry Andric static Instruction *foldBitCastSelect(BitCastInst &BitCast,
24430b57cec5SDimitry Andric                                       InstCombiner::BuilderTy &Builder) {
24440b57cec5SDimitry Andric   Value *Cond, *TVal, *FVal;
24450b57cec5SDimitry Andric   if (!match(BitCast.getOperand(0),
24460b57cec5SDimitry Andric              m_OneUse(m_Select(m_Value(Cond), m_Value(TVal), m_Value(FVal)))))
24470b57cec5SDimitry Andric     return nullptr;
24480b57cec5SDimitry Andric 
24490b57cec5SDimitry Andric   // A vector select must maintain the same number of elements in its operands.
24500b57cec5SDimitry Andric   Type *CondTy = Cond->getType();
24510b57cec5SDimitry Andric   Type *DestTy = BitCast.getType();
2452e8d8bef9SDimitry Andric   if (auto *CondVTy = dyn_cast<VectorType>(CondTy))
2453e8d8bef9SDimitry Andric     if (!DestTy->isVectorTy() ||
2454e8d8bef9SDimitry Andric         CondVTy->getElementCount() !=
2455e8d8bef9SDimitry Andric             cast<VectorType>(DestTy)->getElementCount())
24560b57cec5SDimitry Andric       return nullptr;
24570b57cec5SDimitry Andric 
24580b57cec5SDimitry Andric   // FIXME: This transform is restricted from changing the select between
24590b57cec5SDimitry Andric   // scalars and vectors to avoid backend problems caused by creating
24600b57cec5SDimitry Andric   // potentially illegal operations. If a fix-up is added to handle that
24610b57cec5SDimitry Andric   // situation, we can remove this check.
24620b57cec5SDimitry Andric   if (DestTy->isVectorTy() != TVal->getType()->isVectorTy())
24630b57cec5SDimitry Andric     return nullptr;
24640b57cec5SDimitry Andric 
24650b57cec5SDimitry Andric   auto *Sel = cast<Instruction>(BitCast.getOperand(0));
24660b57cec5SDimitry Andric   Value *X;
24670b57cec5SDimitry Andric   if (match(TVal, m_OneUse(m_BitCast(m_Value(X)))) && X->getType() == DestTy &&
24680b57cec5SDimitry Andric       !isa<Constant>(X)) {
24690b57cec5SDimitry Andric     // bitcast(select(Cond, bitcast(X), Y)) --> select'(Cond, X, bitcast(Y))
24700b57cec5SDimitry Andric     Value *CastedVal = Builder.CreateBitCast(FVal, DestTy);
24710b57cec5SDimitry Andric     return SelectInst::Create(Cond, X, CastedVal, "", nullptr, Sel);
24720b57cec5SDimitry Andric   }
24730b57cec5SDimitry Andric 
24740b57cec5SDimitry Andric   if (match(FVal, m_OneUse(m_BitCast(m_Value(X)))) && X->getType() == DestTy &&
24750b57cec5SDimitry Andric       !isa<Constant>(X)) {
24760b57cec5SDimitry Andric     // bitcast(select(Cond, Y, bitcast(X))) --> select'(Cond, bitcast(Y), X)
24770b57cec5SDimitry Andric     Value *CastedVal = Builder.CreateBitCast(TVal, DestTy);
24780b57cec5SDimitry Andric     return SelectInst::Create(Cond, CastedVal, X, "", nullptr, Sel);
24790b57cec5SDimitry Andric   }
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric   return nullptr;
24820b57cec5SDimitry Andric }
24830b57cec5SDimitry Andric 
24840b57cec5SDimitry Andric /// Check if all users of CI are StoreInsts.
24850b57cec5SDimitry Andric static bool hasStoreUsersOnly(CastInst &CI) {
24860b57cec5SDimitry Andric   for (User *U : CI.users()) {
24870b57cec5SDimitry Andric     if (!isa<StoreInst>(U))
24880b57cec5SDimitry Andric       return false;
24890b57cec5SDimitry Andric   }
24900b57cec5SDimitry Andric   return true;
24910b57cec5SDimitry Andric }
24920b57cec5SDimitry Andric 
24930b57cec5SDimitry Andric /// This function handles following case
24940b57cec5SDimitry Andric ///
24950b57cec5SDimitry Andric ///     A  ->  B    cast
24960b57cec5SDimitry Andric ///     PHI
24970b57cec5SDimitry Andric ///     B  ->  A    cast
24980b57cec5SDimitry Andric ///
24990b57cec5SDimitry Andric /// All the related PHI nodes can be replaced by new PHI nodes with type A.
25000b57cec5SDimitry Andric /// The uses of \p CI can be changed to the new PHI node corresponding to \p PN.
2501e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI,
2502e8d8bef9SDimitry Andric                                                       PHINode *PN) {
25030b57cec5SDimitry Andric   // BitCast used by Store can be handled in InstCombineLoadStoreAlloca.cpp.
25040b57cec5SDimitry Andric   if (hasStoreUsersOnly(CI))
25050b57cec5SDimitry Andric     return nullptr;
25060b57cec5SDimitry Andric 
25070b57cec5SDimitry Andric   Value *Src = CI.getOperand(0);
25080b57cec5SDimitry Andric   Type *SrcTy = Src->getType();         // Type B
25090b57cec5SDimitry Andric   Type *DestTy = CI.getType();          // Type A
25100b57cec5SDimitry Andric 
25110b57cec5SDimitry Andric   SmallVector<PHINode *, 4> PhiWorklist;
25120b57cec5SDimitry Andric   SmallSetVector<PHINode *, 4> OldPhiNodes;
25130b57cec5SDimitry Andric 
25140b57cec5SDimitry Andric   // Find all of the A->B casts and PHI nodes.
25150b57cec5SDimitry Andric   // We need to inspect all related PHI nodes, but PHIs can be cyclic, so
25160b57cec5SDimitry Andric   // OldPhiNodes is used to track all known PHI nodes, before adding a new
25170b57cec5SDimitry Andric   // PHI to PhiWorklist, it is checked against and added to OldPhiNodes first.
25180b57cec5SDimitry Andric   PhiWorklist.push_back(PN);
25190b57cec5SDimitry Andric   OldPhiNodes.insert(PN);
25200b57cec5SDimitry Andric   while (!PhiWorklist.empty()) {
25210b57cec5SDimitry Andric     auto *OldPN = PhiWorklist.pop_back_val();
25220b57cec5SDimitry Andric     for (Value *IncValue : OldPN->incoming_values()) {
25230b57cec5SDimitry Andric       if (isa<Constant>(IncValue))
25240b57cec5SDimitry Andric         continue;
25250b57cec5SDimitry Andric 
25260b57cec5SDimitry Andric       if (auto *LI = dyn_cast<LoadInst>(IncValue)) {
25270b57cec5SDimitry Andric         // If there is a sequence of one or more load instructions, each loaded
25280b57cec5SDimitry Andric         // value is used as address of later load instruction, bitcast is
25290b57cec5SDimitry Andric         // necessary to change the value type, don't optimize it. For
25300b57cec5SDimitry Andric         // simplicity we give up if the load address comes from another load.
25310b57cec5SDimitry Andric         Value *Addr = LI->getOperand(0);
25320b57cec5SDimitry Andric         if (Addr == &CI || isa<LoadInst>(Addr))
25330b57cec5SDimitry Andric           return nullptr;
2534fe6060f1SDimitry Andric         // Don't tranform "load <256 x i32>, <256 x i32>*" to
2535fe6060f1SDimitry Andric         // "load x86_amx, x86_amx*", because x86_amx* is invalid.
2536fe6060f1SDimitry Andric         // TODO: Remove this check when bitcast between vector and x86_amx
2537fe6060f1SDimitry Andric         // is replaced with a specific intrinsic.
2538fe6060f1SDimitry Andric         if (DestTy->isX86_AMXTy())
2539fe6060f1SDimitry Andric           return nullptr;
25400b57cec5SDimitry Andric         if (LI->hasOneUse() && LI->isSimple())
25410b57cec5SDimitry Andric           continue;
25420b57cec5SDimitry Andric         // If a LoadInst has more than one use, changing the type of loaded
25430b57cec5SDimitry Andric         // value may create another bitcast.
25440b57cec5SDimitry Andric         return nullptr;
25450b57cec5SDimitry Andric       }
25460b57cec5SDimitry Andric 
25470b57cec5SDimitry Andric       if (auto *PNode = dyn_cast<PHINode>(IncValue)) {
25480b57cec5SDimitry Andric         if (OldPhiNodes.insert(PNode))
25490b57cec5SDimitry Andric           PhiWorklist.push_back(PNode);
25500b57cec5SDimitry Andric         continue;
25510b57cec5SDimitry Andric       }
25520b57cec5SDimitry Andric 
25530b57cec5SDimitry Andric       auto *BCI = dyn_cast<BitCastInst>(IncValue);
25540b57cec5SDimitry Andric       // We can't handle other instructions.
25550b57cec5SDimitry Andric       if (!BCI)
25560b57cec5SDimitry Andric         return nullptr;
25570b57cec5SDimitry Andric 
25580b57cec5SDimitry Andric       // Verify it's a A->B cast.
25590b57cec5SDimitry Andric       Type *TyA = BCI->getOperand(0)->getType();
25600b57cec5SDimitry Andric       Type *TyB = BCI->getType();
25610b57cec5SDimitry Andric       if (TyA != DestTy || TyB != SrcTy)
25620b57cec5SDimitry Andric         return nullptr;
25630b57cec5SDimitry Andric     }
25640b57cec5SDimitry Andric   }
25650b57cec5SDimitry Andric 
2566480093f4SDimitry Andric   // Check that each user of each old PHI node is something that we can
2567480093f4SDimitry Andric   // rewrite, so that all of the old PHI nodes can be cleaned up afterwards.
2568480093f4SDimitry Andric   for (auto *OldPN : OldPhiNodes) {
2569480093f4SDimitry Andric     for (User *V : OldPN->users()) {
2570480093f4SDimitry Andric       if (auto *SI = dyn_cast<StoreInst>(V)) {
2571480093f4SDimitry Andric         if (!SI->isSimple() || SI->getOperand(0) != OldPN)
2572480093f4SDimitry Andric           return nullptr;
2573480093f4SDimitry Andric       } else if (auto *BCI = dyn_cast<BitCastInst>(V)) {
2574480093f4SDimitry Andric         // Verify it's a B->A cast.
2575480093f4SDimitry Andric         Type *TyB = BCI->getOperand(0)->getType();
2576480093f4SDimitry Andric         Type *TyA = BCI->getType();
2577480093f4SDimitry Andric         if (TyA != DestTy || TyB != SrcTy)
2578480093f4SDimitry Andric           return nullptr;
2579480093f4SDimitry Andric       } else if (auto *PHI = dyn_cast<PHINode>(V)) {
2580480093f4SDimitry Andric         // As long as the user is another old PHI node, then even if we don't
2581480093f4SDimitry Andric         // rewrite it, the PHI web we're considering won't have any users
2582480093f4SDimitry Andric         // outside itself, so it'll be dead.
2583349cc55cSDimitry Andric         if (!OldPhiNodes.contains(PHI))
2584480093f4SDimitry Andric           return nullptr;
2585480093f4SDimitry Andric       } else {
2586480093f4SDimitry Andric         return nullptr;
2587480093f4SDimitry Andric       }
2588480093f4SDimitry Andric     }
2589480093f4SDimitry Andric   }
2590480093f4SDimitry Andric 
25910b57cec5SDimitry Andric   // For each old PHI node, create a corresponding new PHI node with a type A.
25920b57cec5SDimitry Andric   SmallDenseMap<PHINode *, PHINode *> NewPNodes;
25930b57cec5SDimitry Andric   for (auto *OldPN : OldPhiNodes) {
25940b57cec5SDimitry Andric     Builder.SetInsertPoint(OldPN);
25950b57cec5SDimitry Andric     PHINode *NewPN = Builder.CreatePHI(DestTy, OldPN->getNumOperands());
25960b57cec5SDimitry Andric     NewPNodes[OldPN] = NewPN;
25970b57cec5SDimitry Andric   }
25980b57cec5SDimitry Andric 
25990b57cec5SDimitry Andric   // Fill in the operands of new PHI nodes.
26000b57cec5SDimitry Andric   for (auto *OldPN : OldPhiNodes) {
26010b57cec5SDimitry Andric     PHINode *NewPN = NewPNodes[OldPN];
26020b57cec5SDimitry Andric     for (unsigned j = 0, e = OldPN->getNumOperands(); j != e; ++j) {
26030b57cec5SDimitry Andric       Value *V = OldPN->getOperand(j);
26040b57cec5SDimitry Andric       Value *NewV = nullptr;
26050b57cec5SDimitry Andric       if (auto *C = dyn_cast<Constant>(V)) {
26060b57cec5SDimitry Andric         NewV = ConstantExpr::getBitCast(C, DestTy);
26070b57cec5SDimitry Andric       } else if (auto *LI = dyn_cast<LoadInst>(V)) {
2608480093f4SDimitry Andric         // Explicitly perform load combine to make sure no opposing transform
2609480093f4SDimitry Andric         // can remove the bitcast in the meantime and trigger an infinite loop.
2610480093f4SDimitry Andric         Builder.SetInsertPoint(LI);
2611480093f4SDimitry Andric         NewV = combineLoadToNewType(*LI, DestTy);
2612480093f4SDimitry Andric         // Remove the old load and its use in the old phi, which itself becomes
2613480093f4SDimitry Andric         // dead once the whole transform finishes.
2614fe6060f1SDimitry Andric         replaceInstUsesWith(*LI, PoisonValue::get(LI->getType()));
2615480093f4SDimitry Andric         eraseInstFromFunction(*LI);
26160b57cec5SDimitry Andric       } else if (auto *BCI = dyn_cast<BitCastInst>(V)) {
26170b57cec5SDimitry Andric         NewV = BCI->getOperand(0);
26180b57cec5SDimitry Andric       } else if (auto *PrevPN = dyn_cast<PHINode>(V)) {
26190b57cec5SDimitry Andric         NewV = NewPNodes[PrevPN];
26200b57cec5SDimitry Andric       }
26210b57cec5SDimitry Andric       assert(NewV);
26220b57cec5SDimitry Andric       NewPN->addIncoming(NewV, OldPN->getIncomingBlock(j));
26230b57cec5SDimitry Andric     }
26240b57cec5SDimitry Andric   }
26250b57cec5SDimitry Andric 
26260b57cec5SDimitry Andric   // Traverse all accumulated PHI nodes and process its users,
26270b57cec5SDimitry Andric   // which are Stores and BitcCasts. Without this processing
26280b57cec5SDimitry Andric   // NewPHI nodes could be replicated and could lead to extra
26290b57cec5SDimitry Andric   // moves generated after DeSSA.
26300b57cec5SDimitry Andric   // If there is a store with type B, change it to type A.
26310b57cec5SDimitry Andric 
26320b57cec5SDimitry Andric 
26330b57cec5SDimitry Andric   // Replace users of BitCast B->A with NewPHI. These will help
26340b57cec5SDimitry Andric   // later to get rid off a closure formed by OldPHI nodes.
26350b57cec5SDimitry Andric   Instruction *RetVal = nullptr;
26360b57cec5SDimitry Andric   for (auto *OldPN : OldPhiNodes) {
26370b57cec5SDimitry Andric     PHINode *NewPN = NewPNodes[OldPN];
2638e8d8bef9SDimitry Andric     for (User *V : make_early_inc_range(OldPN->users())) {
26390b57cec5SDimitry Andric       if (auto *SI = dyn_cast<StoreInst>(V)) {
2640480093f4SDimitry Andric         assert(SI->isSimple() && SI->getOperand(0) == OldPN);
26410b57cec5SDimitry Andric         Builder.SetInsertPoint(SI);
26420b57cec5SDimitry Andric         auto *NewBC =
26430b57cec5SDimitry Andric           cast<BitCastInst>(Builder.CreateBitCast(NewPN, SrcTy));
26440b57cec5SDimitry Andric         SI->setOperand(0, NewBC);
26455ffd83dbSDimitry Andric         Worklist.push(SI);
26460b57cec5SDimitry Andric         assert(hasStoreUsersOnly(*NewBC));
26470b57cec5SDimitry Andric       }
26480b57cec5SDimitry Andric       else if (auto *BCI = dyn_cast<BitCastInst>(V)) {
26490b57cec5SDimitry Andric         Type *TyB = BCI->getOperand(0)->getType();
26500b57cec5SDimitry Andric         Type *TyA = BCI->getType();
2651480093f4SDimitry Andric         assert(TyA == DestTy && TyB == SrcTy);
2652480093f4SDimitry Andric         (void) TyA;
2653480093f4SDimitry Andric         (void) TyB;
26540b57cec5SDimitry Andric         Instruction *I = replaceInstUsesWith(*BCI, NewPN);
26550b57cec5SDimitry Andric         if (BCI == &CI)
26560b57cec5SDimitry Andric           RetVal = I;
2657480093f4SDimitry Andric       } else if (auto *PHI = dyn_cast<PHINode>(V)) {
2658e8d8bef9SDimitry Andric         assert(OldPhiNodes.contains(PHI));
2659480093f4SDimitry Andric         (void) PHI;
2660480093f4SDimitry Andric       } else {
2661480093f4SDimitry Andric         llvm_unreachable("all uses should be handled");
26620b57cec5SDimitry Andric       }
26630b57cec5SDimitry Andric     }
26640b57cec5SDimitry Andric   }
26650b57cec5SDimitry Andric 
26660b57cec5SDimitry Andric   return RetVal;
26670b57cec5SDimitry Andric }
26680b57cec5SDimitry Andric 
2669fe6060f1SDimitry Andric Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) {
2670fe6060f1SDimitry Andric   // If the operands are integer typed then apply the integer transforms,
2671fe6060f1SDimitry Andric   // otherwise just apply the common ones.
2672fe6060f1SDimitry Andric   Value *Src = CI.getOperand(0);
2673fe6060f1SDimitry Andric   Type *SrcTy = Src->getType();
2674fe6060f1SDimitry Andric   Type *DestTy = CI.getType();
2675fe6060f1SDimitry Andric 
2676fe6060f1SDimitry Andric   // Get rid of casts from one type to the same type. These are useless and can
2677fe6060f1SDimitry Andric   // be replaced by the operand.
2678fe6060f1SDimitry Andric   if (DestTy == Src->getType())
2679fe6060f1SDimitry Andric     return replaceInstUsesWith(CI, Src);
2680fe6060f1SDimitry Andric 
26815ffd83dbSDimitry Andric   if (FixedVectorType *DestVTy = dyn_cast<FixedVectorType>(DestTy)) {
26825ffd83dbSDimitry Andric     // Beware: messing with this target-specific oddity may cause trouble.
26835ffd83dbSDimitry Andric     if (DestVTy->getNumElements() == 1 && SrcTy->isX86_MMXTy()) {
26840b57cec5SDimitry Andric       Value *Elem = Builder.CreateBitCast(Src, DestVTy->getElementType());
2685fe6060f1SDimitry Andric       return InsertElementInst::Create(PoisonValue::get(DestTy), Elem,
26860b57cec5SDimitry Andric                      Constant::getNullValue(Type::getInt32Ty(CI.getContext())));
26870b57cec5SDimitry Andric     }
26880b57cec5SDimitry Andric 
26890b57cec5SDimitry Andric     if (isa<IntegerType>(SrcTy)) {
26900b57cec5SDimitry Andric       // If this is a cast from an integer to vector, check to see if the input
26910b57cec5SDimitry Andric       // is a trunc or zext of a bitcast from vector.  If so, we can replace all
26920b57cec5SDimitry Andric       // the casts with a shuffle and (potentially) a bitcast.
26930b57cec5SDimitry Andric       if (isa<TruncInst>(Src) || isa<ZExtInst>(Src)) {
26940b57cec5SDimitry Andric         CastInst *SrcCast = cast<CastInst>(Src);
26950b57cec5SDimitry Andric         if (BitCastInst *BCIn = dyn_cast<BitCastInst>(SrcCast->getOperand(0)))
26960b57cec5SDimitry Andric           if (isa<VectorType>(BCIn->getOperand(0)->getType()))
2697480093f4SDimitry Andric             if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts(
2698480093f4SDimitry Andric                     BCIn->getOperand(0), cast<VectorType>(DestTy), *this))
26990b57cec5SDimitry Andric               return I;
27000b57cec5SDimitry Andric       }
27010b57cec5SDimitry Andric 
27020b57cec5SDimitry Andric       // If the input is an 'or' instruction, we may be doing shifts and ors to
27030b57cec5SDimitry Andric       // assemble the elements of the vector manually.  Try to rip the code out
27040b57cec5SDimitry Andric       // and replace it with insertelements.
27050b57cec5SDimitry Andric       if (Value *V = optimizeIntegerToVectorInsertions(CI, *this))
27060b57cec5SDimitry Andric         return replaceInstUsesWith(CI, V);
27070b57cec5SDimitry Andric     }
27080b57cec5SDimitry Andric   }
27090b57cec5SDimitry Andric 
27105ffd83dbSDimitry Andric   if (FixedVectorType *SrcVTy = dyn_cast<FixedVectorType>(SrcTy)) {
27110b57cec5SDimitry Andric     if (SrcVTy->getNumElements() == 1) {
27120b57cec5SDimitry Andric       // If our destination is not a vector, then make this a straight
27130b57cec5SDimitry Andric       // scalar-scalar cast.
27140b57cec5SDimitry Andric       if (!DestTy->isVectorTy()) {
27150b57cec5SDimitry Andric         Value *Elem =
27160b57cec5SDimitry Andric           Builder.CreateExtractElement(Src,
27170b57cec5SDimitry Andric                      Constant::getNullValue(Type::getInt32Ty(CI.getContext())));
27180b57cec5SDimitry Andric         return CastInst::Create(Instruction::BitCast, Elem, DestTy);
27190b57cec5SDimitry Andric       }
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric       // Otherwise, see if our source is an insert. If so, then use the scalar
27220b57cec5SDimitry Andric       // component directly:
27230b57cec5SDimitry Andric       // bitcast (inselt <1 x elt> V, X, 0) to <n x m> --> bitcast X to <n x m>
27240b57cec5SDimitry Andric       if (auto *InsElt = dyn_cast<InsertElementInst>(Src))
27250b57cec5SDimitry Andric         return new BitCastInst(InsElt->getOperand(1), DestTy);
27260b57cec5SDimitry Andric     }
2727349cc55cSDimitry Andric 
2728349cc55cSDimitry Andric     // Convert an artificial vector insert into more analyzable bitwise logic.
2729349cc55cSDimitry Andric     unsigned BitWidth = DestTy->getScalarSizeInBits();
2730349cc55cSDimitry Andric     Value *X, *Y;
2731349cc55cSDimitry Andric     uint64_t IndexC;
2732349cc55cSDimitry Andric     if (match(Src, m_OneUse(m_InsertElt(m_OneUse(m_BitCast(m_Value(X))),
2733349cc55cSDimitry Andric                                         m_Value(Y), m_ConstantInt(IndexC)))) &&
2734349cc55cSDimitry Andric         DestTy->isIntegerTy() && X->getType() == DestTy &&
27354824e7fdSDimitry Andric         Y->getType()->isIntegerTy() && isDesirableIntType(BitWidth)) {
2736349cc55cSDimitry Andric       // Adjust for big endian - the LSBs are at the high index.
2737349cc55cSDimitry Andric       if (DL.isBigEndian())
2738349cc55cSDimitry Andric         IndexC = SrcVTy->getNumElements() - 1 - IndexC;
2739349cc55cSDimitry Andric 
2740349cc55cSDimitry Andric       // We only handle (endian-normalized) insert to index 0. Any other insert
2741349cc55cSDimitry Andric       // would require a left-shift, so that is an extra instruction.
2742349cc55cSDimitry Andric       if (IndexC == 0) {
2743349cc55cSDimitry Andric         // bitcast (inselt (bitcast X), Y, 0) --> or (and X, MaskC), (zext Y)
2744349cc55cSDimitry Andric         unsigned EltWidth = Y->getType()->getScalarSizeInBits();
2745349cc55cSDimitry Andric         APInt MaskC = APInt::getHighBitsSet(BitWidth, BitWidth - EltWidth);
2746349cc55cSDimitry Andric         Value *AndX = Builder.CreateAnd(X, MaskC);
2747349cc55cSDimitry Andric         Value *ZextY = Builder.CreateZExt(Y, DestTy);
2748349cc55cSDimitry Andric         return BinaryOperator::CreateOr(AndX, ZextY);
2749349cc55cSDimitry Andric       }
2750349cc55cSDimitry Andric     }
27510b57cec5SDimitry Andric   }
27520b57cec5SDimitry Andric 
27538bcb0991SDimitry Andric   if (auto *Shuf = dyn_cast<ShuffleVectorInst>(Src)) {
27540b57cec5SDimitry Andric     // Okay, we have (bitcast (shuffle ..)).  Check to see if this is
27550b57cec5SDimitry Andric     // a bitcast to a vector with the same # elts.
27568bcb0991SDimitry Andric     Value *ShufOp0 = Shuf->getOperand(0);
27578bcb0991SDimitry Andric     Value *ShufOp1 = Shuf->getOperand(1);
2758e8d8bef9SDimitry Andric     auto ShufElts = cast<VectorType>(Shuf->getType())->getElementCount();
2759e8d8bef9SDimitry Andric     auto SrcVecElts = cast<VectorType>(ShufOp0->getType())->getElementCount();
27608bcb0991SDimitry Andric     if (Shuf->hasOneUse() && DestTy->isVectorTy() &&
2761e8d8bef9SDimitry Andric         cast<VectorType>(DestTy)->getElementCount() == ShufElts &&
2762e8d8bef9SDimitry Andric         ShufElts == SrcVecElts) {
27630b57cec5SDimitry Andric       BitCastInst *Tmp;
27640b57cec5SDimitry Andric       // If either of the operands is a cast from CI.getType(), then
27650b57cec5SDimitry Andric       // evaluating the shuffle in the casted destination's type will allow
27660b57cec5SDimitry Andric       // us to eliminate at least one cast.
27678bcb0991SDimitry Andric       if (((Tmp = dyn_cast<BitCastInst>(ShufOp0)) &&
27680b57cec5SDimitry Andric            Tmp->getOperand(0)->getType() == DestTy) ||
27698bcb0991SDimitry Andric           ((Tmp = dyn_cast<BitCastInst>(ShufOp1)) &&
27700b57cec5SDimitry Andric            Tmp->getOperand(0)->getType() == DestTy)) {
27718bcb0991SDimitry Andric         Value *LHS = Builder.CreateBitCast(ShufOp0, DestTy);
27728bcb0991SDimitry Andric         Value *RHS = Builder.CreateBitCast(ShufOp1, DestTy);
27730b57cec5SDimitry Andric         // Return a new shuffle vector.  Use the same element ID's, as we
27740b57cec5SDimitry Andric         // know the vector types match #elts.
27755ffd83dbSDimitry Andric         return new ShuffleVectorInst(LHS, RHS, Shuf->getShuffleMask());
27760b57cec5SDimitry Andric       }
27770b57cec5SDimitry Andric     }
27788bcb0991SDimitry Andric 
2779bdd1243dSDimitry Andric     // A bitcasted-to-scalar and byte/bit reversing shuffle is better recognized
2780bdd1243dSDimitry Andric     // as a byte/bit swap:
2781bdd1243dSDimitry Andric     // bitcast <N x i8> (shuf X, undef, <N, N-1,...0>) -> bswap (bitcast X)
2782bdd1243dSDimitry Andric     // bitcast <N x i1> (shuf X, undef, <N, N-1,...0>) -> bitreverse (bitcast X)
2783bdd1243dSDimitry Andric     if (DestTy->isIntegerTy() && ShufElts.getKnownMinValue() % 2 == 0 &&
2784bdd1243dSDimitry Andric         Shuf->hasOneUse() && Shuf->isReverse()) {
2785bdd1243dSDimitry Andric       unsigned IntrinsicNum = 0;
2786bdd1243dSDimitry Andric       if (DL.isLegalInteger(DestTy->getScalarSizeInBits()) &&
2787bdd1243dSDimitry Andric           SrcTy->getScalarSizeInBits() == 8) {
2788bdd1243dSDimitry Andric         IntrinsicNum = Intrinsic::bswap;
2789bdd1243dSDimitry Andric       } else if (SrcTy->getScalarSizeInBits() == 1) {
2790bdd1243dSDimitry Andric         IntrinsicNum = Intrinsic::bitreverse;
2791bdd1243dSDimitry Andric       }
2792bdd1243dSDimitry Andric       if (IntrinsicNum != 0) {
27938bcb0991SDimitry Andric         assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask");
2794fe6060f1SDimitry Andric         assert(match(ShufOp1, m_Undef()) && "Unexpected shuffle op");
2795bdd1243dSDimitry Andric         Function *BswapOrBitreverse =
2796bdd1243dSDimitry Andric             Intrinsic::getDeclaration(CI.getModule(), IntrinsicNum, DestTy);
27978bcb0991SDimitry Andric         Value *ScalarX = Builder.CreateBitCast(ShufOp0, DestTy);
2798bdd1243dSDimitry Andric         return CallInst::Create(BswapOrBitreverse, {ScalarX});
2799bdd1243dSDimitry Andric       }
28008bcb0991SDimitry Andric     }
28010b57cec5SDimitry Andric   }
28020b57cec5SDimitry Andric 
28030b57cec5SDimitry Andric   // Handle the A->B->A cast, and there is an intervening PHI node.
28040b57cec5SDimitry Andric   if (PHINode *PN = dyn_cast<PHINode>(Src))
28050b57cec5SDimitry Andric     if (Instruction *I = optimizeBitCastFromPhi(CI, PN))
28060b57cec5SDimitry Andric       return I;
28070b57cec5SDimitry Andric 
28080b57cec5SDimitry Andric   if (Instruction *I = canonicalizeBitCastExtElt(CI, *this))
28090b57cec5SDimitry Andric     return I;
28100b57cec5SDimitry Andric 
28110b57cec5SDimitry Andric   if (Instruction *I = foldBitCastBitwiseLogic(CI, Builder))
28120b57cec5SDimitry Andric     return I;
28130b57cec5SDimitry Andric 
28140b57cec5SDimitry Andric   if (Instruction *I = foldBitCastSelect(CI, Builder))
28150b57cec5SDimitry Andric     return I;
28160b57cec5SDimitry Andric 
28170b57cec5SDimitry Andric   return commonCastTransforms(CI);
28180b57cec5SDimitry Andric }
28190b57cec5SDimitry Andric 
2820e8d8bef9SDimitry Andric Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) {
28215f757f3fSDimitry Andric   return commonCastTransforms(CI);
28220b57cec5SDimitry Andric }
2823