//===- InstCombineCasts.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the visit functions for cast operations. // //===----------------------------------------------------------------------===// #include "InstCombineInternal.h" #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/PatternMatch.h" #include "llvm/Support/KnownBits.h" #include "llvm/Transforms/InstCombine/InstCombiner.h" #include <optional> usingnamespacellvm; usingnamespacePatternMatch; #define DEBUG_TYPE … /// Given an expression that CanEvaluateTruncated or CanEvaluateSExtd returns /// true for, actually insert the code to evaluate the expression. Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty, bool isSigned) { … } Instruction::CastOps InstCombinerImpl::isEliminableCastPair(const CastInst *CI1, const CastInst *CI2) { … } /// Implement the transforms common to all CastInst visitors. Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) { … } /// Constants and extensions/truncates from the destination type are always /// free to be evaluated in that type. This is a helper for canEvaluate*. static bool canAlwaysEvaluateInType(Value *V, Type *Ty) { … } /// Filter out values that we can not evaluate in the destination type for free. /// This is a helper for canEvaluate*. static bool canNotEvaluateInType(Value *V, Type *Ty) { … } /// Return true if we can evaluate the specified expression tree as type Ty /// instead of its larger type, and arrive with the same value. /// This is used by code that tries to eliminate truncates. /// /// Ty will always be a type smaller than V. We should return true if trunc(V) /// can be computed by computing V in the smaller type. If V is an instruction, /// then trunc(inst(x,y)) can be computed as inst(trunc(x),trunc(y)), which only /// makes sense if x and y can be efficiently truncated. /// /// This function works on both vectors and scalars. /// static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC, Instruction *CxtI) { … } /// Given a vector that is bitcast to an integer, optionally logically /// right-shifted, and truncated, convert it to an extractelement. /// Example (big endian): /// trunc (lshr (bitcast <4 x i32> %X to i128), 32) to i32 /// ---> /// extractelement <4 x i32> %X, 1 static Instruction *foldVecTruncToExtElt(TruncInst &Trunc, InstCombinerImpl &IC) { … } /// Whenever an element is extracted from a vector, optionally shifted down, and /// then truncated, canonicalize by converting it to a bitcast followed by an /// extractelement. /// /// Examples (little endian): /// trunc (extractelement <4 x i64> %X, 0) to i32 /// ---> /// extractelement <8 x i32> (bitcast <4 x i64> %X to <8 x i32>), i32 0 /// /// trunc (lshr (extractelement <4 x i32> %X, 0), 8) to i8 /// ---> /// extractelement <16 x i8> (bitcast <4 x i32> %X to <16 x i8>), i32 1 static Instruction *foldVecExtTruncToExtElt(TruncInst &Trunc, InstCombinerImpl &IC) { … } /// Funnel/Rotate left/right may occur in a wider type than necessary because of /// type promotion rules. Try to narrow the inputs and convert to funnel shift. Instruction *InstCombinerImpl::narrowFunnelShift(TruncInst &Trunc) { … } /// Try to narrow the width of math or bitwise logic instructions by pulling a /// truncate ahead of binary operators. Instruction *InstCombinerImpl::narrowBinOp(TruncInst &Trunc) { … } /// Try to narrow the width of a splat shuffle. This could be generalized to any /// shuffle with a constant operand, but we limit the transform to avoid /// creating a shuffle type that targets may not be able to lower effectively. static Instruction *shrinkSplatShuffle(TruncInst &Trunc, InstCombiner::BuilderTy &Builder) { … } /// Try to narrow the width of an insert element. This could be generalized for /// any vector constant, but we limit the transform to insertion into undef to /// avoid potential backend problems from unsupported insertion widths. This /// could also be extended to handle the case of inserting a scalar constant /// into a vector variable. static Instruction *shrinkInsertElt(CastInst &Trunc, InstCombiner::BuilderTy &Builder) { … } Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) { … } Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext) { … } /// Determine if the specified value can be computed in the specified wider type /// and produce the same low bits. If not, return false. /// /// If this function returns true, it can also return a non-zero number of bits /// (in BitsToClear) which indicates that the value it computes is correct for /// the zero extend, but that the additional BitsToClear bits need to be zero'd /// out. For example, to promote something like: /// /// %B = trunc i64 %A to i32 /// %C = lshr i32 %B, 8 /// %E = zext i32 %C to i64 /// /// CanEvaluateZExtd for the 'lshr' will return true, and BitsToClear will be /// set to 8 to indicate that the promoted value needs to have bits 24-31 /// cleared in addition to bits 32-63. Since an 'and' will be generated to /// clear the top bits anyway, doing this has no extra cost. /// /// This function works on both vectors and scalars. static bool canEvaluateZExtd(Value *V, Type *Ty, unsigned &BitsToClear, InstCombinerImpl &IC, Instruction *CxtI) { … } Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) { … } /// Transform (sext icmp) to bitwise / integer operations to eliminate the icmp. Instruction *InstCombinerImpl::transformSExtICmp(ICmpInst *Cmp, SExtInst &Sext) { … } /// Return true if we can take the specified value and return it as type Ty /// without inserting any new casts and without changing the value of the common /// low bits. This is used by code that tries to promote integer operations to /// a wider types will allow us to eliminate the extension. /// /// This function works on both vectors and scalars. /// static bool canEvaluateSExtd(Value *V, Type *Ty) { … } Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) { … } /// Return a Constant* for the specified floating-point constant if it fits /// in the specified FP type without changing its value. static bool fitsInFPType(ConstantFP *CFP, const fltSemantics &Sem) { … } static Type *shrinkFPConstant(ConstantFP *CFP, bool PreferBFloat) { … } // Determine if this is a vector of ConstantFPs and if so, return the minimal // type we can safely truncate all elements to. static Type *shrinkFPConstantVector(Value *V, bool PreferBFloat) { … } /// Find the minimum FP type we can safely truncate to. static Type *getMinimumFPType(Value *V, bool PreferBFloat) { … } /// Return true if the cast from integer to FP can be proven to be exact for all /// possible inputs (the conversion does not lose any precision). static bool isKnownExactCastIntToFP(CastInst &I, InstCombinerImpl &IC) { … } Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) { … } Instruction *InstCombinerImpl::visitFPExt(CastInst &FPExt) { … } /// fpto{s/u}i({u/s}itofp(X)) --> X or zext(X) or sext(X) or trunc(X) /// This is safe if the intermediate type has enough bits in its mantissa to /// accurately represent all values of X. For example, this won't work with /// i64 -> float -> i64. Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) { … } static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) { … } Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) { … } Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) { … } Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) { … } Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) { … } Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { … } Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { … } /// This input value (which is known to have vector type) is being zero extended /// or truncated to the specified vector type. Since the zext/trunc is done /// using an integer type, we have a (bitcast(cast(bitcast))) pattern, /// endianness will impact which end of the vector that is extended or /// truncated. /// /// A vector is always stored with index 0 at the lowest address, which /// corresponds to the most significant bits for a big endian stored integer and /// the least significant bits for little endian. A trunc/zext of an integer /// impacts the big end of the integer. Thus, we need to add/remove elements at /// the front of the vector for big endian targets, and the back of the vector /// for little endian targets. /// /// Try to replace it with a shuffle (and vector/vector bitcast) if possible. /// /// The source and destination vector types may have different element types. static Instruction * optimizeVectorResizeWithIntegerBitCasts(Value *InVal, VectorType *DestTy, InstCombinerImpl &IC) { … } static bool isMultipleOfTypeSize(unsigned Value, Type *Ty) { … } static unsigned getTypeSizeIndex(unsigned Value, Type *Ty) { … } /// V is a value which is inserted into a vector of VecEltTy. /// Look through the value to see if we can decompose it into /// insertions into the vector. See the example in the comment for /// OptimizeIntegerToVectorInsertions for the pattern this handles. /// The type of V is always a non-zero multiple of VecEltTy's size. /// Shift is the number of bits between the lsb of V and the lsb of /// the vector. /// /// This returns false if the pattern can't be matched or true if it can, /// filling in Elements with the elements found here. static bool collectInsertionElements(Value *V, unsigned Shift, SmallVectorImpl<Value *> &Elements, Type *VecEltTy, bool isBigEndian) { … } /// If the input is an 'or' instruction, we may be doing shifts and ors to /// assemble the elements of the vector manually. /// Try to rip the code out and replace it with insertelements. This is to /// optimize code like this: /// /// %tmp37 = bitcast float %inc to i32 /// %tmp38 = zext i32 %tmp37 to i64 /// %tmp31 = bitcast float %inc5 to i32 /// %tmp32 = zext i32 %tmp31 to i64 /// %tmp33 = shl i64 %tmp32, 32 /// %ins35 = or i64 %tmp33, %tmp38 /// %tmp43 = bitcast i64 %ins35 to <2 x float> /// /// Into two insertelements that do "buildvector{%inc, %inc5}". static Value *optimizeIntegerToVectorInsertions(BitCastInst &CI, InstCombinerImpl &IC) { … } /// Canonicalize scalar bitcasts of extracted elements into a bitcast of the /// vector followed by extract element. The backend tends to handle bitcasts of /// vectors better than bitcasts of scalars because vector registers are /// usually not type-specific like scalar integer or scalar floating-point. static Instruction *canonicalizeBitCastExtElt(BitCastInst &BitCast, InstCombinerImpl &IC) { … } /// Change the type of a bitwise logic operation if we can eliminate a bitcast. static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder) { … } /// Change the type of a select if we can eliminate a bitcast. static Instruction *foldBitCastSelect(BitCastInst &BitCast, InstCombiner::BuilderTy &Builder) { … } /// Check if all users of CI are StoreInsts. static bool hasStoreUsersOnly(CastInst &CI) { … } /// This function handles following case /// /// A -> B cast /// PHI /// B -> A cast /// /// All the related PHI nodes can be replaced by new PHI nodes with type A. /// The uses of \p CI can be changed to the new PHI node corresponding to \p PN. Instruction *InstCombinerImpl::optimizeBitCastFromPhi(CastInst &CI, PHINode *PN) { … } /// Fold (bitcast (or (and (bitcast X to int), signmask), nneg Y) to fp) to /// copysign((bitcast Y to fp), X) static Value *foldCopySignIdioms(BitCastInst &CI, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ) { … } Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { … } Instruction *InstCombinerImpl::visitAddrSpaceCast(AddrSpaceCastInst &CI) { … }