File indexing completed on 2026-05-10 08:43:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
0018 #define LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
0019
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/ADT/SmallVector.h"
0022 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
0023 #include "llvm/CodeGen/GlobalISel/Utils.h"
0024 #include "llvm/CodeGen/Register.h"
0025 #include "llvm/CodeGenTypes/LowLevelType.h"
0026 #include "llvm/IR/InstrTypes.h"
0027 #include <functional>
0028
0029 namespace llvm {
0030
0031 class GISelChangeObserver;
0032 class APInt;
0033 class ConstantFP;
0034 class GPtrAdd;
0035 class GZExtLoad;
0036 class MachineIRBuilder;
0037 class MachineInstrBuilder;
0038 class MachineRegisterInfo;
0039 class MachineInstr;
0040 class MachineOperand;
0041 class GISelKnownBits;
0042 class MachineDominatorTree;
0043 class LegalizerInfo;
0044 struct LegalityQuery;
0045 class RegisterBank;
0046 class RegisterBankInfo;
0047 class TargetLowering;
0048 class TargetRegisterInfo;
0049
0050 struct PreferredTuple {
0051 LLT Ty;
0052 unsigned ExtendOpcode;
0053 MachineInstr *MI;
0054 };
0055
0056 struct IndexedLoadStoreMatchInfo {
0057 Register Addr;
0058 Register Base;
0059 Register Offset;
0060 bool RematOffset = false;
0061
0062 bool IsPre = false;
0063 };
0064
0065 struct PtrAddChain {
0066 int64_t Imm;
0067 Register Base;
0068 const RegisterBank *Bank;
0069 };
0070
0071 struct RegisterImmPair {
0072 Register Reg;
0073 int64_t Imm;
0074 };
0075
0076 struct ShiftOfShiftedLogic {
0077 MachineInstr *Logic;
0078 MachineInstr *Shift2;
0079 Register LogicNonShiftReg;
0080 uint64_t ValSum;
0081 };
0082
0083 using BuildFnTy = std::function<void(MachineIRBuilder &)>;
0084
0085 using OperandBuildSteps =
0086 SmallVector<std::function<void(MachineInstrBuilder &)>, 4>;
0087 struct InstructionBuildSteps {
0088 unsigned Opcode = 0;
0089 OperandBuildSteps OperandFns;
0090 InstructionBuildSteps() = default;
0091 InstructionBuildSteps(unsigned Opcode, const OperandBuildSteps &OperandFns)
0092 : Opcode(Opcode), OperandFns(OperandFns) {}
0093 };
0094
0095 struct InstructionStepsMatchInfo {
0096
0097 SmallVector<InstructionBuildSteps, 2> InstrsToBuild;
0098 InstructionStepsMatchInfo() = default;
0099 InstructionStepsMatchInfo(
0100 std::initializer_list<InstructionBuildSteps> InstrsToBuild)
0101 : InstrsToBuild(InstrsToBuild) {}
0102 };
0103
0104 class CombinerHelper {
0105 protected:
0106 MachineIRBuilder &Builder;
0107 MachineRegisterInfo &MRI;
0108 GISelChangeObserver &Observer;
0109 GISelKnownBits *KB;
0110 MachineDominatorTree *MDT;
0111 bool IsPreLegalize;
0112 const LegalizerInfo *LI;
0113 const RegisterBankInfo *RBI;
0114 const TargetRegisterInfo *TRI;
0115
0116 public:
0117 CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
0118 bool IsPreLegalize,
0119 GISelKnownBits *KB = nullptr,
0120 MachineDominatorTree *MDT = nullptr,
0121 const LegalizerInfo *LI = nullptr);
0122
0123 GISelKnownBits *getKnownBits() const {
0124 return KB;
0125 }
0126
0127 MachineIRBuilder &getBuilder() const {
0128 return Builder;
0129 }
0130
0131 const TargetLowering &getTargetLowering() const;
0132
0133 const MachineFunction &getMachineFunction() const;
0134
0135 const DataLayout &getDataLayout() const;
0136
0137 LLVMContext &getContext() const;
0138
0139
0140 bool isPreLegalize() const;
0141
0142
0143 bool isLegal(const LegalityQuery &Query) const;
0144
0145
0146
0147 bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const;
0148
0149
0150
0151 bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const;
0152
0153
0154 void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
0155
0156
0157
0158 void replaceRegOpWith(MachineRegisterInfo &MRI, MachineOperand &FromRegOp,
0159 Register ToReg) const;
0160
0161
0162
0163 void replaceOpcodeWith(MachineInstr &FromMI, unsigned ToOpcode) const;
0164
0165
0166
0167
0168
0169
0170 const RegisterBank *getRegBank(Register Reg) const;
0171
0172
0173
0174
0175 void setRegBank(Register Reg, const RegisterBank *RegBank) const;
0176
0177
0178
0179 bool tryCombineCopy(MachineInstr &MI) const;
0180 bool matchCombineCopy(MachineInstr &MI) const;
0181 void applyCombineCopy(MachineInstr &MI) const;
0182
0183
0184
0185 bool isPredecessor(const MachineInstr &DefMI,
0186 const MachineInstr &UseMI) const;
0187
0188
0189
0190
0191
0192
0193
0194 bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI) const;
0195
0196
0197
0198 bool tryCombineExtendingLoads(MachineInstr &MI) const;
0199 bool matchCombineExtendingLoads(MachineInstr &MI,
0200 PreferredTuple &MatchInfo) const;
0201 void applyCombineExtendingLoads(MachineInstr &MI,
0202 PreferredTuple &MatchInfo) const;
0203
0204
0205 bool matchCombineLoadWithAndMask(MachineInstr &MI,
0206 BuildFnTy &MatchInfo) const;
0207
0208
0209
0210 bool matchCombineExtractedVectorLoad(MachineInstr &MI,
0211 BuildFnTy &MatchInfo) const;
0212
0213 bool matchCombineIndexedLoadStore(MachineInstr &MI,
0214 IndexedLoadStoreMatchInfo &MatchInfo) const;
0215 void applyCombineIndexedLoadStore(MachineInstr &MI,
0216 IndexedLoadStoreMatchInfo &MatchInfo) const;
0217
0218 bool matchSextTruncSextLoad(MachineInstr &MI) const;
0219 void applySextTruncSextLoad(MachineInstr &MI) const;
0220
0221
0222 bool matchSextInRegOfLoad(MachineInstr &MI,
0223 std::tuple<Register, unsigned> &MatchInfo) const;
0224 void applySextInRegOfLoad(MachineInstr &MI,
0225 std::tuple<Register, unsigned> &MatchInfo) const;
0226
0227
0228
0229 bool matchCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI) const;
0230 void applyCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI) const;
0231
0232
0233
0234 bool matchOptBrCondByInvertingCond(MachineInstr &MI,
0235 MachineInstr *&BrCond) const;
0236 void applyOptBrCondByInvertingCond(MachineInstr &MI,
0237 MachineInstr *&BrCond) const;
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 bool matchCombineConcatVectors(MachineInstr &MI,
0254 SmallVector<Register> &Ops) const;
0255
0256
0257 void applyCombineConcatVectors(MachineInstr &MI,
0258 SmallVector<Register> &Ops) const;
0259
0260 bool matchCombineShuffleConcat(MachineInstr &MI,
0261 SmallVector<Register> &Ops) const;
0262
0263
0264 void applyCombineShuffleConcat(MachineInstr &MI,
0265 SmallVector<Register> &Ops) const;
0266
0267
0268
0269
0270
0271 bool tryCombineShuffleVector(MachineInstr &MI) const;
0272
0273
0274
0275
0276
0277
0278 bool matchCombineShuffleVector(MachineInstr &MI,
0279 SmallVectorImpl<Register> &Ops) const;
0280
0281 void applyCombineShuffleVector(MachineInstr &MI,
0282 const ArrayRef<Register> Ops) const;
0283 bool matchShuffleToExtract(MachineInstr &MI) const;
0284 void applyShuffleToExtract(MachineInstr &MI) const;
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 bool tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen = 0) const;
0317
0318 bool matchPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo) const;
0319 void applyPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo) const;
0320
0321
0322 bool matchShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo) const;
0323 void applyShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo) const;
0324
0325
0326
0327
0328 bool matchShiftOfShiftedLogic(MachineInstr &MI,
0329 ShiftOfShiftedLogic &MatchInfo) const;
0330 void applyShiftOfShiftedLogic(MachineInstr &MI,
0331 ShiftOfShiftedLogic &MatchInfo) const;
0332
0333 bool matchCommuteShift(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0334
0335
0336 bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal) const;
0337 void applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal) const;
0338
0339
0340 bool matchCombineSubToAdd(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0341
0342
0343
0344 bool matchCombineShlOfExtend(MachineInstr &MI,
0345 RegisterImmPair &MatchData) const;
0346 void applyCombineShlOfExtend(MachineInstr &MI,
0347 const RegisterImmPair &MatchData) const;
0348
0349
0350 bool matchCombineMergeUnmerge(MachineInstr &MI, Register &MatchInfo) const;
0351
0352
0353
0354 bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
0355 unsigned &ShiftVal) const;
0356 void applyCombineShiftToUnmerge(MachineInstr &MI,
0357 const unsigned &ShiftVal) const;
0358 bool tryCombineShiftToUnmerge(MachineInstr &MI,
0359 unsigned TargetShiftAmount) const;
0360
0361
0362 bool matchCombineUnmergeMergeToPlainValues(
0363 MachineInstr &MI, SmallVectorImpl<Register> &Operands) const;
0364 void applyCombineUnmergeMergeToPlainValues(
0365 MachineInstr &MI, SmallVectorImpl<Register> &Operands) const;
0366
0367
0368 bool matchCombineUnmergeConstant(MachineInstr &MI,
0369 SmallVectorImpl<APInt> &Csts) const;
0370 void applyCombineUnmergeConstant(MachineInstr &MI,
0371 SmallVectorImpl<APInt> &Csts) const;
0372
0373
0374 bool matchCombineUnmergeUndef(
0375 MachineInstr &MI,
0376 std::function<void(MachineIRBuilder &)> &MatchInfo) const;
0377
0378
0379 bool matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) const;
0380 void applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) const;
0381
0382
0383 bool matchCombineUnmergeZExtToZExt(MachineInstr &MI) const;
0384 void applyCombineUnmergeZExtToZExt(MachineInstr &MI) const;
0385
0386
0387 void applyCombineConstantFoldFpUnary(MachineInstr &MI,
0388 const ConstantFP *Cst) const;
0389
0390
0391 bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg) const;
0392 void applyCombineI2PToP2I(MachineInstr &MI, Register &Reg) const;
0393
0394
0395 void applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) const;
0396
0397
0398
0399 bool
0400 matchCombineAddP2IToPtrAdd(MachineInstr &MI,
0401 std::pair<Register, bool> &PtrRegAndCommute) const;
0402 void
0403 applyCombineAddP2IToPtrAdd(MachineInstr &MI,
0404 std::pair<Register, bool> &PtrRegAndCommute) const;
0405
0406
0407 bool matchCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst) const;
0408 void applyCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst) const;
0409
0410
0411 bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) const;
0412
0413
0414 bool matchCombineZextTrunc(MachineInstr &MI, Register &Reg) const;
0415
0416
0417
0418
0419
0420
0421
0422
0423 bool
0424 matchCombineTruncOfShift(MachineInstr &MI,
0425 std::pair<MachineInstr *, LLT> &MatchInfo) const;
0426 void
0427 applyCombineTruncOfShift(MachineInstr &MI,
0428 std::pair<MachineInstr *, LLT> &MatchInfo) const;
0429
0430
0431
0432 bool matchAnyExplicitUseIsUndef(MachineInstr &MI) const;
0433
0434
0435
0436 bool matchAllExplicitUsesAreUndef(MachineInstr &MI) const;
0437
0438
0439 bool matchUndefShuffleVectorMask(MachineInstr &MI) const;
0440
0441
0442 bool matchUndefStore(MachineInstr &MI) const;
0443
0444
0445 bool matchUndefSelectCmp(MachineInstr &MI) const;
0446
0447
0448 bool matchInsertExtractVecEltOutOfBounds(MachineInstr &MI) const;
0449
0450
0451
0452 bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) const;
0453
0454
0455 void replaceInstWithFConstant(MachineInstr &MI, double C) const;
0456
0457
0458 void replaceInstWithFConstant(MachineInstr &MI, ConstantFP *CFP) const;
0459
0460
0461 void replaceInstWithConstant(MachineInstr &MI, int64_t C) const;
0462
0463
0464 void replaceInstWithConstant(MachineInstr &MI, APInt C) const;
0465
0466
0467 void replaceInstWithUndef(MachineInstr &MI) const;
0468
0469
0470 void replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx) const;
0471
0472
0473 void replaceSingleDefInstWithReg(MachineInstr &MI,
0474 Register Replacement) const;
0475
0476
0477
0478 void applyFunnelShiftConstantModulo(MachineInstr &MI) const;
0479
0480
0481
0482 bool matchEqualDefs(const MachineOperand &MOP1,
0483 const MachineOperand &MOP2) const;
0484
0485
0486
0487 bool matchConstantOp(const MachineOperand &MOP, int64_t C) const;
0488
0489
0490
0491 bool matchConstantFPOp(const MachineOperand &MOP, double C) const;
0492
0493
0494
0495 bool matchConstantLargerBitWidth(MachineInstr &MI, unsigned ConstIdx) const;
0496
0497
0498 bool matchSelectSameVal(MachineInstr &MI) const;
0499
0500
0501 bool matchBinOpSameVal(MachineInstr &MI) const;
0502
0503
0504 bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx) const;
0505
0506
0507 bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) const;
0508
0509
0510 bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
0511 unsigned OpIdx) const;
0512
0513
0514 void eraseInst(MachineInstr &MI) const;
0515
0516
0517 bool matchSimplifyAddToSub(MachineInstr &MI,
0518 std::tuple<Register, Register> &MatchInfo) const;
0519 void applySimplifyAddToSub(MachineInstr &MI,
0520 std::tuple<Register, Register> &MatchInfo) const;
0521
0522
0523 bool matchHoistLogicOpWithSameOpcodeHands(
0524 MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) const;
0525
0526
0527 void applyBuildInstructionSteps(MachineInstr &MI,
0528 InstructionStepsMatchInfo &MatchInfo) const;
0529
0530
0531 bool matchAshrShlToSextInreg(MachineInstr &MI,
0532 std::tuple<Register, int64_t> &MatchInfo) const;
0533 void applyAshShlToSextInreg(MachineInstr &MI,
0534 std::tuple<Register, int64_t> &MatchInfo) const;
0535
0536
0537 bool matchOverlappingAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0538
0539
0540
0541
0542
0543
0544
0545 bool matchRedundantAnd(MachineInstr &MI, Register &Replacement) const;
0546
0547
0548
0549
0550
0551
0552
0553
0554 bool matchRedundantOr(MachineInstr &MI, Register &Replacement) const;
0555
0556
0557 bool matchRedundantSExtInReg(MachineInstr &MI) const;
0558
0559
0560 bool matchNotCmp(MachineInstr &MI,
0561 SmallVectorImpl<Register> &RegsToNegate) const;
0562 void applyNotCmp(MachineInstr &MI,
0563 SmallVectorImpl<Register> &RegsToNegate) const;
0564
0565
0566
0567 bool matchXorOfAndWithSameReg(MachineInstr &MI,
0568 std::pair<Register, Register> &MatchInfo) const;
0569 void applyXorOfAndWithSameReg(MachineInstr &MI,
0570 std::pair<Register, Register> &MatchInfo) const;
0571
0572
0573
0574 bool matchPtrAddZero(MachineInstr &MI) const;
0575 void applyPtrAddZero(MachineInstr &MI) const;
0576
0577
0578 void applySimplifyURemByPow2(MachineInstr &MI) const;
0579
0580
0581
0582
0583
0584 bool matchFoldBinOpIntoSelect(MachineInstr &MI, unsigned &SelectOpNo) const;
0585 void applyFoldBinOpIntoSelect(MachineInstr &MI,
0586 const unsigned &SelectOpNo) const;
0587
0588 bool matchCombineInsertVecElts(MachineInstr &MI,
0589 SmallVectorImpl<Register> &MatchInfo) const;
0590
0591 void applyCombineInsertVecElts(MachineInstr &MI,
0592 SmallVectorImpl<Register> &MatchInfo) const;
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603 bool matchLoadOrCombine(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0604
0605 bool matchExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI) const;
0606 void applyExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI) const;
0607
0608 bool matchExtractVecEltBuildVec(MachineInstr &MI, Register &Reg) const;
0609 void applyExtractVecEltBuildVec(MachineInstr &MI, Register &Reg) const;
0610
0611 bool matchExtractAllEltsFromBuildVector(
0612 MachineInstr &MI,
0613 SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo) const;
0614 void applyExtractAllEltsFromBuildVector(
0615 MachineInstr &MI,
0616 SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo) const;
0617
0618
0619
0620 void applyBuildFn(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0621
0622
0623 void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0624
0625 bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0626 bool matchFunnelShiftToRotate(MachineInstr &MI) const;
0627 void applyFunnelShiftToRotate(MachineInstr &MI) const;
0628 bool matchRotateOutOfRange(MachineInstr &MI) const;
0629 void applyRotateOutOfRange(MachineInstr &MI) const;
0630
0631 bool matchUseVectorTruncate(MachineInstr &MI, Register &MatchInfo) const;
0632 void applyUseVectorTruncate(MachineInstr &MI, Register &MatchInfo) const;
0633
0634
0635
0636 bool matchICmpToTrueFalseKnownBits(MachineInstr &MI,
0637 int64_t &MatchInfo) const;
0638
0639
0640
0641 bool matchICmpToLHSKnownBits(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0642
0643
0644 bool matchAndOrDisjointMask(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0645
0646 bool matchBitfieldExtractFromSExtInReg(MachineInstr &MI,
0647 BuildFnTy &MatchInfo) const;
0648
0649 bool matchBitfieldExtractFromAnd(MachineInstr &MI,
0650 BuildFnTy &MatchInfo) const;
0651
0652
0653 bool matchBitfieldExtractFromShr(MachineInstr &MI,
0654 BuildFnTy &MatchInfo) const;
0655
0656
0657 bool matchBitfieldExtractFromShrAnd(MachineInstr &MI,
0658 BuildFnTy &MatchInfo) const;
0659
0660
0661 bool matchReassocConstantInnerRHS(GPtrAdd &MI, MachineInstr *RHS,
0662 BuildFnTy &MatchInfo) const;
0663 bool matchReassocFoldConstantsInSubTree(GPtrAdd &MI, MachineInstr *LHS,
0664 MachineInstr *RHS,
0665 BuildFnTy &MatchInfo) const;
0666 bool matchReassocConstantInnerLHS(GPtrAdd &MI, MachineInstr *LHS,
0667 MachineInstr *RHS,
0668 BuildFnTy &MatchInfo) const;
0669
0670
0671 bool matchReassocPtrAdd(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0672
0673
0674 bool tryReassocBinOp(unsigned Opc, Register DstReg, Register Op0,
0675 Register Op1, BuildFnTy &MatchInfo) const;
0676
0677 bool matchReassocCommBinOp(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0678
0679
0680 bool matchConstantFoldCastOp(MachineInstr &MI, APInt &MatchInfo) const;
0681
0682
0683 bool matchConstantFoldBinOp(MachineInstr &MI, APInt &MatchInfo) const;
0684
0685
0686 bool matchConstantFoldFPBinOp(MachineInstr &MI, ConstantFP *&MatchInfo) const;
0687
0688
0689 bool matchConstantFoldFMA(MachineInstr &MI, ConstantFP *&MatchInfo) const;
0690
0691
0692
0693 bool matchNarrowBinopFeedingAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0694
0695
0696
0697
0698 MachineInstr *buildUDivUsingMul(MachineInstr &MI) const;
0699
0700 bool matchUDivByConst(MachineInstr &MI) const;
0701 void applyUDivByConst(MachineInstr &MI) const;
0702
0703
0704
0705
0706 MachineInstr *buildSDivUsingMul(MachineInstr &MI) const;
0707 bool matchSDivByConst(MachineInstr &MI) const;
0708 void applySDivByConst(MachineInstr &MI) const;
0709
0710
0711
0712 bool matchDivByPow2(MachineInstr &MI, bool IsSigned) const;
0713 void applySDivByPow2(MachineInstr &MI) const;
0714
0715
0716 void applyUDivByPow2(MachineInstr &MI) const;
0717
0718
0719 bool matchUMulHToLShr(MachineInstr &MI) const;
0720 void applyUMulHToLShr(MachineInstr &MI) const;
0721
0722
0723
0724 bool tryCombine(MachineInstr &MI) const;
0725
0726
0727
0728
0729
0730 bool tryEmitMemcpyInline(MachineInstr &MI) const;
0731
0732
0733
0734
0735 bool matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0736
0737
0738
0739 bool matchMulOBy0(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0740
0741
0742
0743
0744 bool matchAddEToAddO(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0745
0746
0747
0748
0749
0750
0751
0752
0753 bool matchRedundantNegOperands(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0754
0755 bool matchFsubToFneg(MachineInstr &MI, Register &MatchInfo) const;
0756 void applyFsubToFneg(MachineInstr &MI, Register &MatchInfo) const;
0757
0758 bool canCombineFMadOrFMA(MachineInstr &MI, bool &AllowFusionGlobally,
0759 bool &HasFMAD, bool &Aggressive,
0760 bool CanReassociate = false) const;
0761
0762
0763
0764 bool matchCombineFAddFMulToFMadOrFMA(MachineInstr &MI,
0765 BuildFnTy &MatchInfo) const;
0766
0767
0768
0769 bool matchCombineFAddFpExtFMulToFMadOrFMA(MachineInstr &MI,
0770 BuildFnTy &MatchInfo) const;
0771
0772
0773
0774 bool matchCombineFAddFMAFMulToFMadOrFMA(MachineInstr &MI,
0775 BuildFnTy &MatchInfo) const;
0776
0777
0778
0779
0780
0781 bool
0782 matchCombineFAddFpExtFMulToFMadOrFMAAggressive(MachineInstr &MI,
0783 BuildFnTy &MatchInfo) const;
0784
0785
0786
0787 bool matchCombineFSubFMulToFMadOrFMA(MachineInstr &MI,
0788 BuildFnTy &MatchInfo) const;
0789
0790
0791
0792 bool matchCombineFSubFNegFMulToFMadOrFMA(MachineInstr &MI,
0793 BuildFnTy &MatchInfo) const;
0794
0795
0796
0797
0798
0799 bool matchCombineFSubFpExtFMulToFMadOrFMA(MachineInstr &MI,
0800 BuildFnTy &MatchInfo) const;
0801
0802
0803
0804
0805
0806 bool matchCombineFSubFpExtFNegFMulToFMadOrFMA(MachineInstr &MI,
0807 BuildFnTy &MatchInfo) const;
0808
0809 bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info) const;
0810
0811
0812
0813 bool matchAddSubSameReg(MachineInstr &MI, Register &Src) const;
0814
0815 bool matchBuildVectorIdentityFold(MachineInstr &MI,
0816 Register &MatchInfo) const;
0817 bool matchTruncBuildVectorFold(MachineInstr &MI, Register &MatchInfo) const;
0818 bool matchTruncLshrBuildVectorFold(MachineInstr &MI,
0819 Register &MatchInfo) const;
0820
0821
0822
0823
0824
0825
0826 bool matchSubAddSameReg(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0827
0828
0829
0830 bool matchSimplifySelectToMinMax(MachineInstr &MI,
0831 BuildFnTy &MatchInfo) const;
0832
0833
0834
0835
0836
0837
0838
0839
0840 bool matchRedundantBinOpInEquality(MachineInstr &MI,
0841 BuildFnTy &MatchInfo) const;
0842
0843
0844
0845 bool matchShiftsTooBig(MachineInstr &MI,
0846 std::optional<int64_t> &MatchInfo) const;
0847
0848
0849 bool matchCommuteConstantToRHS(MachineInstr &MI) const;
0850
0851
0852 bool matchSextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0853
0854
0855 bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0856
0857
0858 bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0859
0860
0861 bool matchCommuteFPConstantToRHS(MachineInstr &MI) const;
0862
0863
0864 void applyCommuteBinOpOperands(MachineInstr &MI) const;
0865
0866
0867 bool matchSelectIMinMax(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0868
0869
0870 bool matchSimplifyNegMinMax(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0871
0872
0873 bool matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0874
0875
0876 bool matchAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0877
0878
0879 bool matchOr(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0880
0881
0882 bool matchNarrowBinop(const MachineInstr &TruncMI,
0883 const MachineInstr &BinopMI,
0884 BuildFnTy &MatchInfo) const;
0885
0886 bool matchCastOfInteger(const MachineInstr &CastMI, APInt &MatchInfo) const;
0887
0888
0889 bool matchAddOverflow(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0890
0891
0892 bool matchExtractVectorElement(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0893
0894
0895 bool matchExtractVectorElementWithBuildVector(const MachineInstr &MI,
0896 const MachineInstr &MI2,
0897 BuildFnTy &MatchInfo) const;
0898
0899
0900
0901 bool
0902 matchExtractVectorElementWithBuildVectorTrunc(const MachineOperand &MO,
0903 BuildFnTy &MatchInfo) const;
0904
0905
0906
0907 bool matchExtractVectorElementWithShuffleVector(const MachineInstr &MI,
0908 const MachineInstr &MI2,
0909 BuildFnTy &MatchInfo) const;
0910
0911
0912
0913 bool
0914 matchExtractVectorElementWithDifferentIndices(const MachineOperand &MO,
0915 BuildFnTy &MatchInfo) const;
0916
0917
0918 bool matchShuffleUndefRHS(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0919
0920
0921
0922 bool matchShuffleDisjointMask(MachineInstr &MI, BuildFnTy &MatchInfo) const;
0923
0924
0925
0926 void applyBuildFnMO(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0927
0928
0929 bool matchFPowIExpansion(MachineInstr &MI, int64_t Exponent) const;
0930
0931
0932
0933 void applyExpandFPowI(MachineInstr &MI, int64_t Exponent) const;
0934
0935
0936 bool matchInsertVectorElementOOB(MachineInstr &MI,
0937 BuildFnTy &MatchInfo) const;
0938
0939 bool matchFreezeOfSingleMaybePoisonOperand(MachineInstr &MI,
0940 BuildFnTy &MatchInfo) const;
0941
0942 bool matchAddOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0943
0944 bool matchMulOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0945
0946 bool matchSubOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0947
0948 bool matchShlOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const;
0949
0950
0951 bool matchTruncateOfExt(const MachineInstr &Root, const MachineInstr &ExtMI,
0952 BuildFnTy &MatchInfo) const;
0953
0954 bool matchCastOfSelect(const MachineInstr &Cast, const MachineInstr &SelectMI,
0955 BuildFnTy &MatchInfo) const;
0956 bool matchFoldAPlusC1MinusC2(const MachineInstr &MI,
0957 BuildFnTy &MatchInfo) const;
0958
0959 bool matchFoldC2MinusAPlusC1(const MachineInstr &MI,
0960 BuildFnTy &MatchInfo) const;
0961
0962 bool matchFoldAMinusC1MinusC2(const MachineInstr &MI,
0963 BuildFnTy &MatchInfo) const;
0964
0965 bool matchFoldC1Minus2MinusC2(const MachineInstr &MI,
0966 BuildFnTy &MatchInfo) const;
0967
0968
0969 bool matchFoldAMinusC1PlusC2(const MachineInstr &MI,
0970 BuildFnTy &MatchInfo) const;
0971
0972 bool matchExtOfExt(const MachineInstr &FirstMI, const MachineInstr &SecondMI,
0973 BuildFnTy &MatchInfo) const;
0974
0975 bool matchCastOfBuildVector(const MachineInstr &CastMI,
0976 const MachineInstr &BVMI,
0977 BuildFnTy &MatchInfo) const;
0978
0979 bool matchCanonicalizeICmp(const MachineInstr &MI,
0980 BuildFnTy &MatchInfo) const;
0981 bool matchCanonicalizeFCmp(const MachineInstr &MI,
0982 BuildFnTy &MatchInfo) const;
0983
0984
0985 bool matchUnmergeValuesAnyExtBuildVector(const MachineInstr &MI,
0986 BuildFnTy &MatchInfo) const;
0987
0988
0989 bool matchMergeXAndUndef(const MachineInstr &MI, BuildFnTy &MatchInfo) const;
0990
0991
0992 bool matchMergeXAndZero(const MachineInstr &MI, BuildFnTy &MatchInfo) const;
0993
0994
0995 bool matchSuboCarryOut(const MachineInstr &MI, BuildFnTy &MatchInfo) const;
0996
0997 private:
0998
0999 bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
1000
1001
1002
1003
1004 bool findPostIndexCandidate(GLoadStore &MI, Register &Addr, Register &Base,
1005 Register &Offset, bool &RematOffset) const;
1006
1007
1008
1009
1010
1011 bool findPreIndexCandidate(GLoadStore &MI, Register &Addr, Register &Base,
1012 Register &Offset) const;
1013
1014
1015
1016
1017
1018
1019
1020 std::optional<SmallVector<Register, 8>>
1021 findCandidatesForLoadOrCombine(const MachineInstr *Root) const;
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034 std::optional<std::tuple<GZExtLoad *, int64_t, GZExtLoad *>>
1035 findLoadOffsetsForLoadOrCombine(
1036 SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
1037 const SmallVector<Register, 8> &RegsToVisit,
1038 const unsigned MemSizeInBits) const;
1039
1040
1041
1042
1043 bool reassociationCanBreakAddressingModePattern(MachineInstr &PtrAdd) const;
1044
1045
1046
1047 enum class SelectPatternNaNBehaviour {
1048 NOT_APPLICABLE = 0,
1049 RETURNS_NAN,
1050 RETURNS_OTHER,
1051 RETURNS_ANY
1052
1053 };
1054
1055
1056
1057
1058
1059
1060 SelectPatternNaNBehaviour
1061 computeRetValAgainstNaN(Register LHS, Register RHS,
1062 bool IsOrderedComparison) const;
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076 unsigned getFPMinMaxOpcForSelect(CmpInst::Predicate Pred, LLT DstTy,
1077 SelectPatternNaNBehaviour VsNaNRetVal) const;
1078
1079
1080
1081
1082
1083
1084
1085 bool matchFPSelectToMinMax(Register Dst, Register Cond, Register TrueVal,
1086 Register FalseVal, BuildFnTy &MatchInfo) const;
1087
1088
1089 bool tryFoldBoolSelectToLogic(GSelect *Select, BuildFnTy &MatchInfo) const;
1090
1091 bool tryFoldSelectOfConstants(GSelect *Select, BuildFnTy &MatchInfo) const;
1092
1093 bool isOneOrOneSplat(Register Src, bool AllowUndefs) const;
1094 bool isZeroOrZeroSplat(Register Src, bool AllowUndefs) const;
1095 bool isConstantSplatVector(Register Src, int64_t SplatValue,
1096 bool AllowUndefs) const;
1097 bool isConstantOrConstantVectorI(Register Src) const;
1098
1099 std::optional<APInt> getConstantOrConstantSplatVector(Register Src) const;
1100
1101
1102
1103
1104 bool tryFoldAndOrOrICmpsUsingRanges(GLogicalBinOp *Logic,
1105 BuildFnTy &MatchInfo) const;
1106
1107
1108 bool tryFoldLogicOfFCmps(GLogicalBinOp *Logic, BuildFnTy &MatchInfo) const;
1109
1110 bool isCastFree(unsigned Opcode, LLT ToTy, LLT FromTy) const;
1111
1112 bool constantFoldICmp(const GICmp &ICmp, const GIConstant &LHSCst,
1113 const GIConstant &RHSCst, BuildFnTy &MatchInfo) const;
1114 bool constantFoldFCmp(const GFCmp &FCmp, const GFConstant &LHSCst,
1115 const GFConstant &RHSCst, BuildFnTy &MatchInfo) const;
1116 };
1117 }
1118
1119 #endif