21#include "llvm/IR/IntrinsicsHexagon.h"
36 "hexagon-widen-short-vector",
54 HexagonGenWideningVecInstr(
const HexagonTargetMachine *TM)
55 : FunctionPass(ID), TM(TM) {
59 StringRef getPassName()
const override {
60 return "Hexagon generate widening vector instructions";
65 void getAnalysisUsage(AnalysisUsage &AU)
const override {
66 FunctionPass::getAnalysisUsage(AU);
71 const HexagonTargetMachine *TM =
nullptr;
72 const HexagonSubtarget *HST =
nullptr;
74 enum OPKind { OP_None = 0, OP_Add, OP_Sub, OP_Mul, OP_Shl };
78 Value *ExtInOP =
nullptr;
80 unsigned ExtInSize = 0;
81 bool IsScalar =
false;
84 bool visitBlock(BasicBlock *
B);
85 bool processInstruction(Instruction *Inst);
86 bool replaceWithIntrinsic(Instruction *Inst, OPKind OPK, OPInfo &OP1Info,
89 bool isExtendedConstant(Constant *
C,
bool IsSigned);
90 unsigned getElementSizeInBits(
Value *V,
bool IsZExt);
94 unsigned NewEltsize,
unsigned NumElts);
96 Intrinsic::ID getIntrinsic(OPKind OPK,
bool IsOP1ZExt,
bool IsOP2ZExt,
97 unsigned NewOpEltSize,
unsigned NewResEltSize,
98 bool IsConstScalar,
int ConstOpNum);
100 std::pair<Value *, Value *> opSplit(
Value *
OP, Instruction *Inst,
104 Value *NewOP2,
Type *ResType,
unsigned NumElts,
106 bool processInstructionForVMPA(Instruction *Inst);
107 bool getVmpaOperandInfo(
Value *V, OPInfo &OPI);
108 void reorderVmpaOperands(OPInfo *OPI);
109 bool replaceWithVmpaIntrinsic(Instruction *Inst, OPInfo *OPI);
110 bool genSaturatingInst(Instruction *Inst);
111 bool getMinMax(Constant *MinC, Constant *MaxC, std::pair<int, int> &MinMax);
112 bool isSaturatingVAsr(Instruction *Inst,
Value *S,
int MinV,
int MaxV,
115 Intrinsic::ID getVAsrIntrinsic(
bool IsInSigned,
bool IsResSigned);
116 Value *createVAsrIntrinsic(Instruction *Inst,
Value *VecOP,
Value *ShiftByVal,
118 bool genVAvg(Instruction *Inst);
119 bool checkConstantVector(
Value *
OP, int64_t &SplatVal,
bool IsOPZExt);
120 void updateMPYConst(
Intrinsic::ID IntId, int64_t SplatVal,
bool IsOPZExt,
128char HexagonGenWideningVecInstr::ID = 0;
132 "widening vector instructions",
137 "widening vector instructions",
141 if (
Value *SplatV =
C->getSplatValue()) {
142 auto *CI = dyn_cast<ConstantInt>(SplatV);
144 return CI->getValue().isNegative();
147 for (
unsigned i = 0, e = NumElts; i != e; ++i) {
150 if (CI->getValue().isNegative())
157bool HexagonGenWideningVecInstr::getOperandInfo(
Value *V, OPInfo &OPI) {
158 using namespace PatternMatch;
160 Value *ExtV =
nullptr;
200 if (!isExtendedConstant(
C,
false) && !isExtendedConstant(
C,
true))
211 OPI.ExtInSize = getElementSizeInBits(OPI.ExtInOP, OPI.IsZExt);
215bool HexagonGenWideningVecInstr::isExtendedConstant(Constant *
C,
219 unsigned HalfSize = EltSize / 2;
220 if (
Value *SplatV =
C->getSplatValue()) {
222 return IsSigned ?
isIntN(HalfSize, CI->getSExtValue())
223 :
isUIntN(HalfSize, CI->getZExtValue());
227 for (
unsigned i = 0, e = NumElts; i !=
e; ++i) {
229 if ((IsSigned && !
isIntN(HalfSize, CI->getSExtValue())) ||
230 (!IsSigned && !
isUIntN(HalfSize, CI->getZExtValue())))
239unsigned HexagonGenWideningVecInstr::getElementSizeInBits(
Value *V,
240 bool IsZExt =
false) {
241 using namespace PatternMatch;
242 Type *ValTy =
V->getType();
248 ->getPrimitiveSizeInBits()
250 unsigned ReducedSize = EltSize / 2;
252 while (ReducedSize >= 8) {
253 for (
unsigned i = 0, e = NumElts; i !=
e; ++i) {
256 if (!
isUIntN(ReducedSize, CI->getZExtValue()))
258 }
else if (!
isIntN(ReducedSize, CI->getSExtValue()))
262 EltSize = ReducedSize;
263 ReducedSize = ReducedSize / 2;
273Value *HexagonGenWideningVecInstr::adjustExtensionForOp(OPInfo &OPI,
278 bool IsZExt = OPI.IsZExt;
279 unsigned EltSize = getElementSizeInBits(OPI.ExtInOP, OPI.IsZExt);
280 Type *EltType = getElementTy(NewExtSize, IRB);
286 if (
V->getType()->isVectorTy()) {
287 if (NewExtSize == EltSize)
298 assert(
I &&
I->getOpcode() == Instruction::ShuffleVector);
300 if (NewExtSize > EltSize)
302 else if (NewExtSize < EltSize)
309 for (
unsigned i = 0; i < NumElts; ++i)
317 OPKind OPK,
bool IsOP1ZExt,
bool IsOP2ZExt,
unsigned InEltSize,
318 unsigned ResEltSize,
bool IsConstScalar,
int ConstOpNum) {
323 assert(IsOP1ZExt == IsOP2ZExt);
324 if (InEltSize == 8 && ResEltSize == 16) {
327 assert(IsOP1ZExt &&
"Operands must be zero-extended");
328 return Intrinsic::hexagon_vadd_uu;
330 if (InEltSize == 16 && ResEltSize == 32)
331 return (IsOP1ZExt) ? Intrinsic::hexagon_vadd_uu
332 : Intrinsic::hexagon_vadd_ss;
338 assert(IsOP1ZExt == IsOP2ZExt);
339 if (InEltSize == 8 && ResEltSize == 16) {
342 assert(IsOP1ZExt &&
"Operands must be zero-extended");
343 return Intrinsic::hexagon_vsub_uu;
345 if (InEltSize == 16 && ResEltSize == 32)
346 return (IsOP1ZExt) ? Intrinsic::hexagon_vsub_uu
347 : Intrinsic::hexagon_vsub_ss;
352 assert(ResEltSize == 2 * InEltSize);
356 if (InEltSize == 8 && ResEltSize == 16) {
359 if (ConstOpNum == 2 && IsOP1ZExt) {
362 return (IsOP2ZExt) ? Intrinsic::hexagon_vmpy_ub_ub
363 : Intrinsic::hexagon_vmpy_ub_b;
364 }
else if (ConstOpNum == 1 && IsOP2ZExt) {
365 return (IsOP1ZExt) ? Intrinsic::hexagon_vmpy_ub_ub
366 : Intrinsic::hexagon_vmpy_ub_b;
371 if (InEltSize == 16 && ResEltSize == 32) {
372 if (IsOP1ZExt && IsOP2ZExt) {
375 return Intrinsic::hexagon_vmpy_uh_uh;
376 }
else if (!IsOP1ZExt && !IsOP2ZExt) {
379 return Intrinsic::hexagon_vmpy_h_h;
384 return IsOP2ZExt ? Intrinsic::hexagon_vmpy_uu
385 : Intrinsic::hexagon_vmpy_us;
387 return IsOP2ZExt ? Intrinsic::hexagon_vmpy_su
388 : Intrinsic::hexagon_vmpy_ss;
394Type *HexagonGenWideningVecInstr::getElementTy(
unsigned size,
408Value *HexagonGenWideningVecInstr::createIntrinsic(
410 Type *ResType,
unsigned NumElts,
bool Interleave =
true) {
417 unsigned HalfElts = NumElts / 2;
418 for (
unsigned i = 0; i < HalfElts; ++i) {
428std::pair<Value *, Value *>
429HexagonGenWideningVecInstr::opSplit(
Value *
OP, Instruction *Inst,
440 assert(NumElts % 2 == 0 &&
"Unexpected Vector Type!!");
441 unsigned HalfElts = NumElts / 2;
444 for (
unsigned i = 0; i < HalfElts; ++i)
446 for (
unsigned i = 0; i < HalfElts; ++i)
453 return std::pair<Value *, Value *>(
Hi,
Lo);
466 return std::pair<Value *, Value *>(
Hi,
Lo);
469bool HexagonGenWideningVecInstr::checkConstantVector(
Value *
OP,
473 if (
Value *SplatV = C1->getSplatValue()) {
476 SplatVal = CI->getZExtValue();
478 SplatVal = CI->getSExtValue();
486void HexagonGenWideningVecInstr::updateMPYConst(
Intrinsic::ID IntId,
487 int64_t SplatVal,
bool IsOPZExt,
489 if ((IntId == Intrinsic::hexagon_vmpy_uu ||
490 IntId == Intrinsic::hexagon_vmpy_us ||
491 IntId == Intrinsic::hexagon_vmpy_su ||
492 IntId == Intrinsic::hexagon_vmpy_ss) &&
493 OP->getType()->isVectorTy()) {
495 Type *VecTy =
OP->getType();
497 ConstantInt::get(VecTy,
static_cast<uint32_t
>(SplatVal));
501 packConstant(IntId, SplatVal,
OP, IRB);
505void HexagonGenWideningVecInstr::packConstant(
Intrinsic::ID IntId,
508 uint32_t Val32 =
static_cast<uint32_t
>(SplatVal);
509 if (IntId == Intrinsic::hexagon_vmpy_ub_ub) {
510 assert(SplatVal >= 0 && SplatVal <= UINT8_MAX);
511 uint32_t
packed = (Val32 << 24) | (Val32 << 16) | (Val32 << 8) | Val32;
513 }
else if (IntId == Intrinsic::hexagon_vmpy_ub_b) {
514 assert(SplatVal >= INT8_MIN && SplatVal <= INT8_MAX);
515 uint32_t
packed = (Val32 << 24) | ((Val32 << 16) & ((1 << 24) - 1)) |
516 ((Val32 << 8) & ((1 << 16) - 1)) |
517 (Val32 & ((1 << 8) - 1));
519 }
else if (IntId == Intrinsic::hexagon_vmpy_uh_uh) {
520 assert(SplatVal >= 0 && SplatVal <= UINT16_MAX);
521 uint32_t
packed = (Val32 << 16) | Val32;
523 }
else if (IntId == Intrinsic::hexagon_vmpy_h_h) {
524 assert(SplatVal >= INT16_MIN && SplatVal <= INT16_MAX);
525 uint32_t
packed = (Val32 << 16) | (Val32 & ((1 << 16) - 1));
530bool HexagonGenWideningVecInstr::replaceWithIntrinsic(Instruction *Inst,
539 bool IsOP1ZExt = OP1Info.IsZExt;
540 bool IsOP2ZExt = OP2Info.IsZExt;
543 bool IsResZExt = (OPK == OP_Mul || OPK == OP_Shl)
544 ? (OP1Info.IsZExt && OP2Info.IsZExt)
547 unsigned MaxEltSize = std::max(OP1Info.ExtInSize, OP2Info.ExtInSize);
548 unsigned NewOpEltSize = MaxEltSize;
549 unsigned NewResEltSize = 2 * MaxEltSize;
557 if (OPK != OP_Mul && OPK != OP_Shl &&
558 (IsOP1ZExt != IsOP2ZExt || (!IsOP1ZExt && NewOpEltSize == 8)))
559 NewOpEltSize = 2 * NewOpEltSize;
561 unsigned ResVLen = NewResEltSize * NumElts;
564 if (NewOpEltSize > 16 || ((ResVLen > HwVLen) && (ResVLen % HwVLen) != 0))
568 Value *NewOP1 = adjustExtensionForOp(OP1Info, IRB, NewOpEltSize, NumElts);
569 Value *NewOP2 = adjustExtensionForOp(OP2Info, IRB, NewOpEltSize, NumElts);
571 if (NewOpEltSize == NewResEltSize) {
572 assert(OPK != OP_Mul && OPK != OP_Shl);
576 if (InstEltSize > NewResEltSize)
582 bool IsConstScalar =
false;
583 int64_t SplatVal = 0;
585 if (OPK == OP_Mul || OPK == OP_Shl) {
586 IsConstScalar = checkConstantVector(NewOP1, SplatVal, IsOP1ZExt);
587 if (!IsConstScalar) {
588 IsConstScalar = checkConstantVector(NewOP2, SplatVal, IsOP2ZExt);
593 if (IsConstScalar && OPK == OP_Shl) {
594 if (((NewOpEltSize == 8) && (SplatVal > 0) && (SplatVal < 8)) ||
595 ((NewOpEltSize == 16) && (SplatVal > 0) && (SplatVal < 16))) {
596 SplatVal = 1LL << SplatVal;
601 }
else if (!IsConstScalar && OPK == OP_Shl) {
605 Intrinsic::ID IntId = getIntrinsic(OPK, IsOP1ZExt, IsOP2ZExt, NewOpEltSize,
606 NewResEltSize, IsConstScalar, ConstOpNum);
609 updateMPYConst(IntId, SplatVal, IsOP2ZExt, NewOP2, IRB);
613 if (ResVLen > 2 * HwVLen) {
614 assert(ResVLen == 4 * HwVLen);
616 unsigned HalfElts = NumElts / 2;
621 std::pair<Value *, Value *> SplitOP1 = opSplit(NewOP1, Inst, NewOpType);
622 std::pair<Value *, Value *> SplitOP2;
623 if (IsConstScalar && (IntId == Intrinsic::hexagon_vmpy_h_h ||
624 IntId == Intrinsic::hexagon_vmpy_uh_uh)) {
625 SplitOP2 = std::pair<Value *, Value *>(NewOP2, NewOP2);
627 SplitOP2 = opSplit(NewOP2, Inst, NewOpType);
629 Value *NewInHi = createIntrinsic(IntId, Inst, SplitOP1.first,
630 SplitOP2.first, ResType, HalfElts,
true);
631 Value *NewInLo = createIntrinsic(IntId, Inst, SplitOP1.second,
632 SplitOP2.second, ResType, HalfElts,
true);
633 assert(InstEltSize == NewResEltSize);
635 for (
unsigned i = 0; i < NumElts; ++i)
648 createIntrinsic(IntId, Inst, NewOP1, NewOP2, ResType, NumElts,
true);
649 if (InstEltSize > NewResEltSize)
650 NewIn = (IsResZExt) ? IRB.
CreateZExt(NewIn, InstTy)
660bool HexagonGenWideningVecInstr::processInstruction(Instruction *Inst) {
671 using namespace PatternMatch;
686 OPInfo OP1Info, OP2Info;
692 if (!OP1Info.ExtInOP || !OP2Info.ExtInOP)
695 return replaceWithIntrinsic(Inst, OPK, OP1Info, OP2Info);
698bool HexagonGenWideningVecInstr::getVmpaOperandInfo(
Value *V, OPInfo &OPI) {
699 using namespace PatternMatch;
716 ConstantInt *
I =
nullptr;
720 uint32_t IValue =
I->getZExtValue();
736bool HexagonGenWideningVecInstr::processInstructionForVMPA(Instruction *Inst) {
737 using namespace PatternMatch;
748 Value *
OP[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
754 for (
unsigned i = 0; i < 4; i++)
755 if (!getVmpaOperandInfo(
OP[i], OP_Info[i]) || !OP_Info[i].ExtInOP)
758 return replaceWithVmpaIntrinsic(Inst, OP_Info);
763void HexagonGenWideningVecInstr::reorderVmpaOperands(OPInfo *OPI) {
764 for (
unsigned i = 0; i < 2; i++)
765 if (!OPI[2 * i].ExtInOP->getType()->isVectorTy()) {
768 OPI[2 * i] = OPI[2 * i + 1];
769 OPI[2 * i + 1] = Temp;
776bool HexagonGenWideningVecInstr::replaceWithVmpaIntrinsic(Instruction *Inst,
778 reorderVmpaOperands(OPI);
782 if (!OPI[1].IsScalar || !OPI[3].IsScalar || OPI[0].IsScalar ||
786 OPInfo SOPI1 = OPI[1];
787 OPInfo SOPI2 = OPI[3];
790 if (SOPI1.ExtInSize != SOPI2.ExtInSize || SOPI1.ExtInSize != 8)
798 unsigned MaxVEltSize = std::max(OPI[0].ExtInSize, OPI[2].ExtInSize);
799 unsigned NewVOpEltSize = MaxVEltSize;
800 unsigned NewResEltSize = 2 * MaxVEltSize;
802 if (NumElts * NewVOpEltSize < HwVLen) {
804 NewVOpEltSize = 2 * NewVOpEltSize;
805 NewResEltSize = 2 * NewResEltSize;
811 Value *NewSOP1 = SOPI1.ExtInOP;
812 Value *NewSOP2 = SOPI2.ExtInOP;
823 Intrinsic::ID CombineIntID = Intrinsic::hexagon_A2_combine_ll;
828 Value *NewVOP1 = adjustExtensionForOp(OPI[0], IRB, NewVOpEltSize, NumElts);
829 Value *NewVOP2 = adjustExtensionForOp(OPI[2], IRB, NewVOpEltSize, NumElts);
832 Intrinsic::ID VCombineIntID = Intrinsic::hexagon_V6_vcombine_128B;
840 ? Intrinsic::hexagon_V6_vmpabus_128B
848 if (InstEltSize > NewResEltSize)
854 unsigned HalfElts = NumElts / 2;
855 for (
unsigned i = 0; i < HalfElts; ++i) {
866bool HexagonGenWideningVecInstr::genSaturatingInst(Instruction *Inst) {
872 using namespace PatternMatch;
874 Value *L1 =
nullptr, *
T1 =
nullptr, *L2 =
nullptr, *T2 =
nullptr,
876 Constant *RC1 =
nullptr, *FC1 =
nullptr, *RC2 =
nullptr, *FC2 =
nullptr,
887 std::pair<int, int> MinMax;
889 if (getMinMax(RC1, RC2, MinMax)) {
892 if (isSaturatingVAsr(Inst, L2, MinMax.first, MinMax.second,
895 ConstantInt *shift_val =
899 createVAsrIntrinsic(Inst, L3, shift_val, IsResSigned);
911 (
T1 != L1 || FC1 != RC1))
916 (T2 != L2 || FC2 != RC2))
923 std::pair<int, int> MinMax;
925 if (!getMinMax(RC1, RC2, MinMax))
927 }
else if (!getMinMax(RC2, RC1, MinMax))
934 Value *
OP1 =
nullptr, *ShiftByVal =
nullptr;
942 if (!isSaturatingVAsr(Inst, S, MinMax.first, MinMax.second, IsResSigned))
945 Value *NewIn = createVAsrIntrinsic(Inst, OP1, ShiftByVal, IsResSigned);
950Value *HexagonGenWideningVecInstr::extendShiftByVal(
Value *ShiftByVal,
952 using namespace PatternMatch;
959bool HexagonGenWideningVecInstr::getMinMax(Constant *MinC, Constant *MaxC,
960 std::pair<int, int> &MinMax) {
973bool HexagonGenWideningVecInstr::isSaturatingVAsr(Instruction *Inst,
Value *S,
984 int MaxRange, MinRange;
986 MaxRange = (1 << (TruncSize - 1)) - 1;
987 MinRange = -(1 << (TruncSize - 1));
988 }
else if (MinV == 0) {
989 MaxRange = (1 << (TruncSize)) - 1;
995 if (MinV != MinRange || MaxV != MaxRange)
999 if (SInst->getOpcode() == Instruction::AShr) {
1000 Type *SInstTy = SInst->getType();
1003 if (SInstEltSize != 2 * TruncSize || TruncSize > 16)
1009Intrinsic::ID HexagonGenWideningVecInstr::getVAsrIntrinsic(
bool IsInSigned,
1012 return (IsInSigned) ? Intrinsic::hexagon_vasrsat_su
1013 : Intrinsic::hexagon_vasrsat_uu;
1014 return Intrinsic::hexagon_vasrsat_ss;
1017Value *HexagonGenWideningVecInstr::createVAsrIntrinsic(Instruction *Inst,
1024 ShiftByVal = extendShiftByVal(ShiftByVal, IRB);
1035 unsigned HalfElts = NumElts / 2;
1037 for (
unsigned i = 0; i < HalfElts; ++i)
1040 for (
unsigned i = 0; i < HalfElts; ++i)
1048 std::pair<Value *, Value *> HiLo = opSplit(VecOP, Inst, InVecOPTy);
1056bool HexagonGenWideningVecInstr::genVAvg(Instruction *Inst) {
1057 using namespace PatternMatch;
1079 unsigned OP1EltSize = getElementSizeInBits(OP1);
1080 unsigned OP2EltSize = getElementSizeInBits(OP2);
1081 unsigned NewEltSize = std::max(OP1EltSize, OP2EltSize);
1089 if (InstEltSize < NewEltSize || (InstLen > 2 * HwVLen))
1092 if ((InstLen > HwVLen) && (InstLen % HwVLen != 0))
1099 if (OP1EltSize < NewEltSize)
1102 if (OP2EltSize < NewEltSize)
1107 (IsSigned) ? Intrinsic::hexagon_vavgs :
Intrinsic::hexagon_vavgu;
1108 Value *NewIn =
nullptr;
1111 if (NewEltSize * NumElts > HwVLen) {
1112 unsigned HalfElts = NumElts / 2;
1115 std::pair<Value *, Value *> SplitOP1 = opSplit(OP1, Inst, ResType);
1116 std::pair<Value *, Value *> SplitOP2 = opSplit(OP2, Inst, ResType);
1117 Value *NewHi = createIntrinsic(AvgIntID, Inst, SplitOP1.first,
1118 SplitOP2.first, ResType, NumElts,
false);
1119 Value *NewLo = createIntrinsic(AvgIntID, Inst, SplitOP1.second,
1120 SplitOP2.second, ResType, NumElts,
false);
1122 for (
unsigned i = 0; i < NumElts; ++i)
1129 createIntrinsic(AvgIntID, Inst, OP1, OP2, AvgInstTy, NumElts,
false);
1131 if (InstEltSize > NewEltSize)
1133 NewIn = (IsSigned) ? IRB.
CreateSExt(NewIn, InstTy)
1139bool HexagonGenWideningVecInstr::visitBlock(BasicBlock *
B) {
1141 for (
auto &
I : *
B) {
1142 Type *InstTy =
I.getType();
1150 Changed |= processInstructionForVMPA(&
I);
1160bool HexagonGenWideningVecInstr::runOnFunction(Function &
F) {
1180 return new HexagonGenWideningVecInstr(&TM);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runOnFunction(Function &F, bool PostInlining)
widening Hexagon generate widening vector static false bool hasNegativeValues(Constant *C)
static cl::opt< bool > WidenShortVector("hexagon-widen-short-vector", cl::desc("Generate widening instructions for short vectors."), cl::Hidden)
Machine Check Debug Module
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static std::optional< OperandInfo > getOperandInfo(const MachineOperand &MO)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
@ ICMP_SLT
signed less than
@ ICMP_SGT
signed greater than
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
LLVM_ABI Constant * getSplatValue(bool AllowPoison=false) const
If all elements of the vector constant have the same value, return that value.
Legacy analysis pass which computes a DominatorTree.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
unsigned getVectorLength() const
bool useHVX128BOps() const
bool isTypeForHVX(Type *VecTy, bool IncludeBool=false) const
const HexagonSubtarget * getSubtargetImpl(const Function &F) const override
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
void push_back(const T &Elt)
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ SHL
Shift and rotation operations.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
support::detail::packed_endian_specific_integral< T, E, support::unaligned > packed
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
void initializeHexagonGenWideningVecInstrPass(PassRegistry &)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
FunctionPass * createHexagonGenWideningVecInstr(const HexagonTargetMachine &)