CombinerHelper.h 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- llvm/CodeGen/GlobalISel/CombinerHelper.h --------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===--------------------------------------------------------------------===//
  13. /// \file
  14. /// This contains common combine transformations that may be used in a combine
  15. /// pass,or by the target elsewhere.
  16. /// Targets can pick individual opcode transformations from the helper or use
  17. /// tryCombine which invokes all transformations. All of the transformations
  18. /// return true if the MachineInstruction changed and false otherwise.
  19. ///
  20. //===--------------------------------------------------------------------===//
  21. #ifndef LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
  22. #define LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
  23. #include "llvm/ADT/DenseMap.h"
  24. #include "llvm/ADT/SmallVector.h"
  25. #include "llvm/CodeGen/Register.h"
  26. #include "llvm/Support/LowLevelTypeImpl.h"
  27. #include "llvm/IR/InstrTypes.h"
  28. #include <functional>
  29. namespace llvm {
  30. class GISelChangeObserver;
  31. class APFloat;
  32. class APInt;
  33. class GPtrAdd;
  34. class GStore;
  35. class GZExtLoad;
  36. class MachineIRBuilder;
  37. class MachineInstrBuilder;
  38. class MachineRegisterInfo;
  39. class MachineInstr;
  40. class MachineOperand;
  41. class GISelKnownBits;
  42. class MachineDominatorTree;
  43. class LegalizerInfo;
  44. struct LegalityQuery;
  45. class RegisterBank;
  46. class RegisterBankInfo;
  47. class TargetLowering;
  48. class TargetRegisterInfo;
  49. struct PreferredTuple {
  50. LLT Ty; // The result type of the extend.
  51. unsigned ExtendOpcode; // G_ANYEXT/G_SEXT/G_ZEXT
  52. MachineInstr *MI;
  53. };
  54. struct IndexedLoadStoreMatchInfo {
  55. Register Addr;
  56. Register Base;
  57. Register Offset;
  58. bool IsPre;
  59. };
  60. struct PtrAddChain {
  61. int64_t Imm;
  62. Register Base;
  63. const RegisterBank *Bank;
  64. };
  65. struct RegisterImmPair {
  66. Register Reg;
  67. int64_t Imm;
  68. };
  69. struct ShiftOfShiftedLogic {
  70. MachineInstr *Logic;
  71. MachineInstr *Shift2;
  72. Register LogicNonShiftReg;
  73. uint64_t ValSum;
  74. };
  75. using BuildFnTy = std::function<void(MachineIRBuilder &)>;
  76. struct MergeTruncStoresInfo {
  77. SmallVector<GStore *> FoundStores;
  78. GStore *LowestIdxStore = nullptr;
  79. Register WideSrcVal;
  80. bool NeedBSwap = false;
  81. bool NeedRotate = false;
  82. };
  83. using OperandBuildSteps =
  84. SmallVector<std::function<void(MachineInstrBuilder &)>, 4>;
  85. struct InstructionBuildSteps {
  86. unsigned Opcode = 0; /// The opcode for the produced instruction.
  87. OperandBuildSteps OperandFns; /// Operands to be added to the instruction.
  88. InstructionBuildSteps() = default;
  89. InstructionBuildSteps(unsigned Opcode, const OperandBuildSteps &OperandFns)
  90. : Opcode(Opcode), OperandFns(OperandFns) {}
  91. };
  92. struct InstructionStepsMatchInfo {
  93. /// Describes instructions to be built during a combine.
  94. SmallVector<InstructionBuildSteps, 2> InstrsToBuild;
  95. InstructionStepsMatchInfo() = default;
  96. InstructionStepsMatchInfo(
  97. std::initializer_list<InstructionBuildSteps> InstrsToBuild)
  98. : InstrsToBuild(InstrsToBuild) {}
  99. };
  100. class CombinerHelper {
  101. protected:
  102. MachineIRBuilder &Builder;
  103. MachineRegisterInfo &MRI;
  104. GISelChangeObserver &Observer;
  105. GISelKnownBits *KB;
  106. MachineDominatorTree *MDT;
  107. bool IsPreLegalize;
  108. const LegalizerInfo *LI;
  109. const RegisterBankInfo *RBI;
  110. const TargetRegisterInfo *TRI;
  111. public:
  112. CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
  113. bool IsPreLegalize,
  114. GISelKnownBits *KB = nullptr,
  115. MachineDominatorTree *MDT = nullptr,
  116. const LegalizerInfo *LI = nullptr);
  117. GISelKnownBits *getKnownBits() const {
  118. return KB;
  119. }
  120. MachineIRBuilder &getBuilder() const {
  121. return Builder;
  122. }
  123. const TargetLowering &getTargetLowering() const;
  124. /// \returns true if the combiner is running pre-legalization.
  125. bool isPreLegalize() const;
  126. /// \returns true if \p Query is legal on the target.
  127. bool isLegal(const LegalityQuery &Query) const;
  128. /// \return true if the combine is running prior to legalization, or if \p
  129. /// Query is legal on the target.
  130. bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const;
  131. /// \return true if the combine is running prior to legalization, or if \p Ty
  132. /// is a legal integer constant type on the target.
  133. bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const;
  134. /// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
  135. void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
  136. /// Replace a single register operand with a new register and inform the
  137. /// observer of the changes.
  138. void replaceRegOpWith(MachineRegisterInfo &MRI, MachineOperand &FromRegOp,
  139. Register ToReg) const;
  140. /// Replace the opcode in instruction with a new opcode and inform the
  141. /// observer of the changes.
  142. void replaceOpcodeWith(MachineInstr &FromMI, unsigned ToOpcode) const;
  143. /// Get the register bank of \p Reg.
  144. /// If Reg has not been assigned a register, a register class,
  145. /// or a register bank, then this returns nullptr.
  146. ///
  147. /// \pre Reg.isValid()
  148. const RegisterBank *getRegBank(Register Reg) const;
  149. /// Set the register bank of \p Reg.
  150. /// Does nothing if the RegBank is null.
  151. /// This is the counterpart to getRegBank.
  152. void setRegBank(Register Reg, const RegisterBank *RegBank);
  153. /// If \p MI is COPY, try to combine it.
  154. /// Returns true if MI changed.
  155. bool tryCombineCopy(MachineInstr &MI);
  156. bool matchCombineCopy(MachineInstr &MI);
  157. void applyCombineCopy(MachineInstr &MI);
  158. /// Returns true if \p DefMI precedes \p UseMI or they are the same
  159. /// instruction. Both must be in the same basic block.
  160. bool isPredecessor(const MachineInstr &DefMI, const MachineInstr &UseMI);
  161. /// Returns true if \p DefMI dominates \p UseMI. By definition an
  162. /// instruction dominates itself.
  163. ///
  164. /// If we haven't been provided with a MachineDominatorTree during
  165. /// construction, this function returns a conservative result that tracks just
  166. /// a single basic block.
  167. bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI);
  168. /// If \p MI is extend that consumes the result of a load, try to combine it.
  169. /// Returns true if MI changed.
  170. bool tryCombineExtendingLoads(MachineInstr &MI);
  171. bool matchCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo);
  172. void applyCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo);
  173. /// Match (and (load x), mask) -> zextload x
  174. bool matchCombineLoadWithAndMask(MachineInstr &MI, BuildFnTy &MatchInfo);
  175. /// Combine \p MI into a pre-indexed or post-indexed load/store operation if
  176. /// legal and the surrounding code makes it useful.
  177. bool tryCombineIndexedLoadStore(MachineInstr &MI);
  178. bool matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
  179. void applyCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
  180. bool matchSextTruncSextLoad(MachineInstr &MI);
  181. void applySextTruncSextLoad(MachineInstr &MI);
  182. /// Match sext_inreg(load p), imm -> sextload p
  183. bool matchSextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
  184. void applySextInRegOfLoad(MachineInstr &MI, std::tuple<Register, unsigned> &MatchInfo);
  185. /// Try to combine G_[SU]DIV and G_[SU]REM into a single G_[SU]DIVREM
  186. /// when their source operands are identical.
  187. bool matchCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI);
  188. void applyCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI);
  189. /// If a brcond's true block is not the fallthrough, make it so by inverting
  190. /// the condition and swapping operands.
  191. bool matchOptBrCondByInvertingCond(MachineInstr &MI, MachineInstr *&BrCond);
  192. void applyOptBrCondByInvertingCond(MachineInstr &MI, MachineInstr *&BrCond);
  193. /// If \p MI is G_CONCAT_VECTORS, try to combine it.
  194. /// Returns true if MI changed.
  195. /// Right now, we support:
  196. /// - concat_vector(undef, undef) => undef
  197. /// - concat_vector(build_vector(A, B), build_vector(C, D)) =>
  198. /// build_vector(A, B, C, D)
  199. ///
  200. /// \pre MI.getOpcode() == G_CONCAT_VECTORS.
  201. bool tryCombineConcatVectors(MachineInstr &MI);
  202. /// Check if the G_CONCAT_VECTORS \p MI is undef or if it
  203. /// can be flattened into a build_vector.
  204. /// In the first case \p IsUndef will be true.
  205. /// In the second case \p Ops will contain the operands needed
  206. /// to produce the flattened build_vector.
  207. ///
  208. /// \pre MI.getOpcode() == G_CONCAT_VECTORS.
  209. bool matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
  210. SmallVectorImpl<Register> &Ops);
  211. /// Replace \p MI with a flattened build_vector with \p Ops or an
  212. /// implicit_def if IsUndef is true.
  213. void applyCombineConcatVectors(MachineInstr &MI, bool IsUndef,
  214. const ArrayRef<Register> Ops);
  215. /// Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
  216. /// Returns true if MI changed.
  217. ///
  218. /// \pre MI.getOpcode() == G_SHUFFLE_VECTOR.
  219. bool tryCombineShuffleVector(MachineInstr &MI);
  220. /// Check if the G_SHUFFLE_VECTOR \p MI can be replaced by a
  221. /// concat_vectors.
  222. /// \p Ops will contain the operands needed to produce the flattened
  223. /// concat_vectors.
  224. ///
  225. /// \pre MI.getOpcode() == G_SHUFFLE_VECTOR.
  226. bool matchCombineShuffleVector(MachineInstr &MI,
  227. SmallVectorImpl<Register> &Ops);
  228. /// Replace \p MI with a concat_vectors with \p Ops.
  229. void applyCombineShuffleVector(MachineInstr &MI,
  230. const ArrayRef<Register> Ops);
  231. /// Optimize memcpy intrinsics et al, e.g. constant len calls.
  232. /// /p MaxLen if non-zero specifies the max length of a mem libcall to inline.
  233. ///
  234. /// For example (pre-indexed):
  235. ///
  236. /// $addr = G_PTR_ADD $base, $offset
  237. /// [...]
  238. /// $val = G_LOAD $addr
  239. /// [...]
  240. /// $whatever = COPY $addr
  241. ///
  242. /// -->
  243. ///
  244. /// $val, $addr = G_INDEXED_LOAD $base, $offset, 1 (IsPre)
  245. /// [...]
  246. /// $whatever = COPY $addr
  247. ///
  248. /// or (post-indexed):
  249. ///
  250. /// G_STORE $val, $base
  251. /// [...]
  252. /// $addr = G_PTR_ADD $base, $offset
  253. /// [...]
  254. /// $whatever = COPY $addr
  255. ///
  256. /// -->
  257. ///
  258. /// $addr = G_INDEXED_STORE $val, $base, $offset
  259. /// [...]
  260. /// $whatever = COPY $addr
  261. bool tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen = 0);
  262. bool matchPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
  263. void applyPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
  264. /// Fold (shift (shift base, x), y) -> (shift base (x+y))
  265. bool matchShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
  266. void applyShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo);
  267. /// If we have a shift-by-constant of a bitwise logic op that itself has a
  268. /// shift-by-constant operand with identical opcode, we may be able to convert
  269. /// that into 2 independent shifts followed by the logic op.
  270. bool matchShiftOfShiftedLogic(MachineInstr &MI,
  271. ShiftOfShiftedLogic &MatchInfo);
  272. void applyShiftOfShiftedLogic(MachineInstr &MI,
  273. ShiftOfShiftedLogic &MatchInfo);
  274. /// Transform a multiply by a power-of-2 value to a left shift.
  275. bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
  276. void applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
  277. // Transform a G_SHL with an extended source into a narrower shift if
  278. // possible.
  279. bool matchCombineShlOfExtend(MachineInstr &MI, RegisterImmPair &MatchData);
  280. void applyCombineShlOfExtend(MachineInstr &MI,
  281. const RegisterImmPair &MatchData);
  282. /// Fold away a merge of an unmerge of the corresponding values.
  283. bool matchCombineMergeUnmerge(MachineInstr &MI, Register &MatchInfo);
  284. /// Reduce a shift by a constant to an unmerge and a shift on a half sized
  285. /// type. This will not produce a shift smaller than \p TargetShiftSize.
  286. bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
  287. unsigned &ShiftVal);
  288. void applyCombineShiftToUnmerge(MachineInstr &MI, const unsigned &ShiftVal);
  289. bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount);
  290. /// Transform <ty,...> G_UNMERGE(G_MERGE ty X, Y, Z) -> ty X, Y, Z.
  291. bool
  292. matchCombineUnmergeMergeToPlainValues(MachineInstr &MI,
  293. SmallVectorImpl<Register> &Operands);
  294. void
  295. applyCombineUnmergeMergeToPlainValues(MachineInstr &MI,
  296. SmallVectorImpl<Register> &Operands);
  297. /// Transform G_UNMERGE Constant -> Constant1, Constant2, ...
  298. bool matchCombineUnmergeConstant(MachineInstr &MI,
  299. SmallVectorImpl<APInt> &Csts);
  300. void applyCombineUnmergeConstant(MachineInstr &MI,
  301. SmallVectorImpl<APInt> &Csts);
  302. /// Transform G_UNMERGE G_IMPLICIT_DEF -> G_IMPLICIT_DEF, G_IMPLICIT_DEF, ...
  303. bool
  304. matchCombineUnmergeUndef(MachineInstr &MI,
  305. std::function<void(MachineIRBuilder &)> &MatchInfo);
  306. /// Transform X, Y<dead> = G_UNMERGE Z -> X = G_TRUNC Z.
  307. bool matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
  308. void applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI);
  309. /// Transform X, Y = G_UNMERGE(G_ZEXT(Z)) -> X = G_ZEXT(Z); Y = G_CONSTANT 0
  310. bool matchCombineUnmergeZExtToZExt(MachineInstr &MI);
  311. void applyCombineUnmergeZExtToZExt(MachineInstr &MI);
  312. /// Transform fp_instr(cst) to constant result of the fp operation.
  313. bool matchCombineConstantFoldFpUnary(MachineInstr &MI,
  314. std::optional<APFloat> &Cst);
  315. void applyCombineConstantFoldFpUnary(MachineInstr &MI,
  316. std::optional<APFloat> &Cst);
  317. /// Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space.
  318. bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg);
  319. void applyCombineI2PToP2I(MachineInstr &MI, Register &Reg);
  320. /// Transform PtrToInt(IntToPtr(x)) to x.
  321. void applyCombineP2IToI2P(MachineInstr &MI, Register &Reg);
  322. /// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
  323. /// Transform G_ADD y, (G_PTRTOINT x) -> G_PTRTOINT (G_PTR_ADD x, y)
  324. bool matchCombineAddP2IToPtrAdd(MachineInstr &MI,
  325. std::pair<Register, bool> &PtrRegAndCommute);
  326. void applyCombineAddP2IToPtrAdd(MachineInstr &MI,
  327. std::pair<Register, bool> &PtrRegAndCommute);
  328. // Transform G_PTR_ADD (G_PTRTOINT C1), C2 -> C1 + C2
  329. bool matchCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst);
  330. void applyCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst);
  331. /// Transform anyext(trunc(x)) to x.
  332. bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
  333. void applyCombineAnyExtTrunc(MachineInstr &MI, Register &Reg);
  334. /// Transform zext(trunc(x)) to x.
  335. bool matchCombineZextTrunc(MachineInstr &MI, Register &Reg);
  336. /// Transform [asz]ext([asz]ext(x)) to [asz]ext x.
  337. bool matchCombineExtOfExt(MachineInstr &MI,
  338. std::tuple<Register, unsigned> &MatchInfo);
  339. void applyCombineExtOfExt(MachineInstr &MI,
  340. std::tuple<Register, unsigned> &MatchInfo);
  341. /// Transform fabs(fabs(x)) to fabs(x).
  342. void applyCombineFAbsOfFAbs(MachineInstr &MI, Register &Src);
  343. /// Transform fabs(fneg(x)) to fabs(x).
  344. bool matchCombineFAbsOfFNeg(MachineInstr &MI, BuildFnTy &MatchInfo);
  345. /// Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
  346. bool matchCombineTruncOfExt(MachineInstr &MI,
  347. std::pair<Register, unsigned> &MatchInfo);
  348. void applyCombineTruncOfExt(MachineInstr &MI,
  349. std::pair<Register, unsigned> &MatchInfo);
  350. /// Transform trunc (shl x, K) to shl (trunc x), K
  351. /// if K < VT.getScalarSizeInBits().
  352. ///
  353. /// Transforms trunc ([al]shr x, K) to (trunc ([al]shr (MidVT (trunc x)), K))
  354. /// if K <= (MidVT.getScalarSizeInBits() - VT.getScalarSizeInBits())
  355. /// MidVT is obtained by finding a legal type between the trunc's src and dst
  356. /// types.
  357. bool matchCombineTruncOfShift(MachineInstr &MI,
  358. std::pair<MachineInstr *, LLT> &MatchInfo);
  359. void applyCombineTruncOfShift(MachineInstr &MI,
  360. std::pair<MachineInstr *, LLT> &MatchInfo);
  361. /// Transform G_MUL(x, -1) to G_SUB(0, x)
  362. void applyCombineMulByNegativeOne(MachineInstr &MI);
  363. /// Return true if any explicit use operand on \p MI is defined by a
  364. /// G_IMPLICIT_DEF.
  365. bool matchAnyExplicitUseIsUndef(MachineInstr &MI);
  366. /// Return true if all register explicit use operands on \p MI are defined by
  367. /// a G_IMPLICIT_DEF.
  368. bool matchAllExplicitUsesAreUndef(MachineInstr &MI);
  369. /// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
  370. bool matchUndefShuffleVectorMask(MachineInstr &MI);
  371. /// Return true if a G_STORE instruction \p MI is storing an undef value.
  372. bool matchUndefStore(MachineInstr &MI);
  373. /// Return true if a G_SELECT instruction \p MI has an undef comparison.
  374. bool matchUndefSelectCmp(MachineInstr &MI);
  375. /// Return true if a G_{EXTRACT,INSERT}_VECTOR_ELT has an out of range index.
  376. bool matchInsertExtractVecEltOutOfBounds(MachineInstr &MI);
  377. /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
  378. /// true, \p OpIdx will store the operand index of the known selected value.
  379. bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
  380. /// Replace an instruction with a G_FCONSTANT with value \p C.
  381. bool replaceInstWithFConstant(MachineInstr &MI, double C);
  382. /// Replace an instruction with a G_CONSTANT with value \p C.
  383. bool replaceInstWithConstant(MachineInstr &MI, int64_t C);
  384. /// Replace an instruction with a G_CONSTANT with value \p C.
  385. bool replaceInstWithConstant(MachineInstr &MI, APInt C);
  386. /// Replace an instruction with a G_IMPLICIT_DEF.
  387. bool replaceInstWithUndef(MachineInstr &MI);
  388. /// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
  389. bool replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx);
  390. /// Delete \p MI and replace all of its uses with \p Replacement.
  391. bool replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement);
  392. /// Return true if \p MOP1 and \p MOP2 are register operands are defined by
  393. /// equivalent instructions.
  394. bool matchEqualDefs(const MachineOperand &MOP1, const MachineOperand &MOP2);
  395. /// Return true if \p MOP is defined by a G_CONSTANT with a value equal to
  396. /// \p C.
  397. bool matchConstantOp(const MachineOperand &MOP, int64_t C);
  398. /// Optimize (cond ? x : x) -> x
  399. bool matchSelectSameVal(MachineInstr &MI);
  400. /// Optimize (x op x) -> x
  401. bool matchBinOpSameVal(MachineInstr &MI);
  402. /// Check if operand \p OpIdx is zero.
  403. bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx);
  404. /// Check if operand \p OpIdx is undef.
  405. bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx);
  406. /// Check if operand \p OpIdx is known to be a power of 2.
  407. bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI, unsigned OpIdx);
  408. /// Erase \p MI
  409. bool eraseInst(MachineInstr &MI);
  410. /// Return true if MI is a G_ADD which can be simplified to a G_SUB.
  411. bool matchSimplifyAddToSub(MachineInstr &MI,
  412. std::tuple<Register, Register> &MatchInfo);
  413. void applySimplifyAddToSub(MachineInstr &MI,
  414. std::tuple<Register, Register> &MatchInfo);
  415. /// Match (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
  416. bool
  417. matchHoistLogicOpWithSameOpcodeHands(MachineInstr &MI,
  418. InstructionStepsMatchInfo &MatchInfo);
  419. /// Replace \p MI with a series of instructions described in \p MatchInfo.
  420. void applyBuildInstructionSteps(MachineInstr &MI,
  421. InstructionStepsMatchInfo &MatchInfo);
  422. /// Match ashr (shl x, C), C -> sext_inreg (C)
  423. bool matchAshrShlToSextInreg(MachineInstr &MI,
  424. std::tuple<Register, int64_t> &MatchInfo);
  425. void applyAshShlToSextInreg(MachineInstr &MI,
  426. std::tuple<Register, int64_t> &MatchInfo);
  427. /// Fold and(and(x, C1), C2) -> C1&C2 ? and(x, C1&C2) : 0
  428. bool matchOverlappingAnd(MachineInstr &MI,
  429. BuildFnTy &MatchInfo);
  430. /// \return true if \p MI is a G_AND instruction whose operands are x and y
  431. /// where x & y == x or x & y == y. (E.g., one of operands is all-ones value.)
  432. ///
  433. /// \param [in] MI - The G_AND instruction.
  434. /// \param [out] Replacement - A register the G_AND should be replaced with on
  435. /// success.
  436. bool matchRedundantAnd(MachineInstr &MI, Register &Replacement);
  437. /// \return true if \p MI is a G_OR instruction whose operands are x and y
  438. /// where x | y == x or x | y == y. (E.g., one of operands is all-zeros
  439. /// value.)
  440. ///
  441. /// \param [in] MI - The G_OR instruction.
  442. /// \param [out] Replacement - A register the G_OR should be replaced with on
  443. /// success.
  444. bool matchRedundantOr(MachineInstr &MI, Register &Replacement);
  445. /// \return true if \p MI is a G_SEXT_INREG that can be erased.
  446. bool matchRedundantSExtInReg(MachineInstr &MI);
  447. /// Combine inverting a result of a compare into the opposite cond code.
  448. bool matchNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
  449. void applyNotCmp(MachineInstr &MI, SmallVectorImpl<Register> &RegsToNegate);
  450. /// Fold (xor (and x, y), y) -> (and (not x), y)
  451. ///{
  452. bool matchXorOfAndWithSameReg(MachineInstr &MI,
  453. std::pair<Register, Register> &MatchInfo);
  454. void applyXorOfAndWithSameReg(MachineInstr &MI,
  455. std::pair<Register, Register> &MatchInfo);
  456. ///}
  457. /// Combine G_PTR_ADD with nullptr to G_INTTOPTR
  458. bool matchPtrAddZero(MachineInstr &MI);
  459. void applyPtrAddZero(MachineInstr &MI);
  460. /// Combine G_UREM x, (known power of 2) to an add and bitmasking.
  461. void applySimplifyURemByPow2(MachineInstr &MI);
  462. /// Push a binary operator through a select on constants.
  463. ///
  464. /// binop (select cond, K0, K1), K2 ->
  465. /// select cond, (binop K0, K2), (binop K1, K2)
  466. bool matchFoldBinOpIntoSelect(MachineInstr &MI, unsigned &SelectOpNo);
  467. bool applyFoldBinOpIntoSelect(MachineInstr &MI, const unsigned &SelectOpNo);
  468. bool matchCombineInsertVecElts(MachineInstr &MI,
  469. SmallVectorImpl<Register> &MatchInfo);
  470. void applyCombineInsertVecElts(MachineInstr &MI,
  471. SmallVectorImpl<Register> &MatchInfo);
  472. /// Match expression trees of the form
  473. ///
  474. /// \code
  475. /// sN *a = ...
  476. /// sM val = a[0] | (a[1] << N) | (a[2] << 2N) | (a[3] << 3N) ...
  477. /// \endcode
  478. ///
  479. /// And check if the tree can be replaced with a M-bit load + possibly a
  480. /// bswap.
  481. bool matchLoadOrCombine(MachineInstr &MI, BuildFnTy &MatchInfo);
  482. bool matchTruncStoreMerge(MachineInstr &MI, MergeTruncStoresInfo &MatchInfo);
  483. void applyTruncStoreMerge(MachineInstr &MI, MergeTruncStoresInfo &MatchInfo);
  484. bool matchExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI);
  485. void applyExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI);
  486. bool matchExtractVecEltBuildVec(MachineInstr &MI, Register &Reg);
  487. void applyExtractVecEltBuildVec(MachineInstr &MI, Register &Reg);
  488. bool matchExtractAllEltsFromBuildVector(
  489. MachineInstr &MI,
  490. SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo);
  491. void applyExtractAllEltsFromBuildVector(
  492. MachineInstr &MI,
  493. SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo);
  494. /// Use a function which takes in a MachineIRBuilder to perform a combine.
  495. /// By default, it erases the instruction \p MI from the function.
  496. void applyBuildFn(MachineInstr &MI, BuildFnTy &MatchInfo);
  497. /// Use a function which takes in a MachineIRBuilder to perform a combine.
  498. /// This variant does not erase \p MI after calling the build function.
  499. void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo);
  500. bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo);
  501. bool matchFunnelShiftToRotate(MachineInstr &MI);
  502. void applyFunnelShiftToRotate(MachineInstr &MI);
  503. bool matchRotateOutOfRange(MachineInstr &MI);
  504. void applyRotateOutOfRange(MachineInstr &MI);
  505. /// \returns true if a G_ICMP instruction \p MI can be replaced with a true
  506. /// or false constant based off of KnownBits information.
  507. bool matchICmpToTrueFalseKnownBits(MachineInstr &MI, int64_t &MatchInfo);
  508. /// \returns true if a G_ICMP \p MI can be replaced with its LHS based off of
  509. /// KnownBits information.
  510. bool
  511. matchICmpToLHSKnownBits(MachineInstr &MI,
  512. BuildFnTy &MatchInfo);
  513. /// \returns true if (and (or x, c1), c2) can be replaced with (and x, c2)
  514. bool matchAndOrDisjointMask(MachineInstr &MI, BuildFnTy &MatchInfo);
  515. bool matchBitfieldExtractFromSExtInReg(MachineInstr &MI,
  516. BuildFnTy &MatchInfo);
  517. /// Match: and (lshr x, cst), mask -> ubfx x, cst, width
  518. bool matchBitfieldExtractFromAnd(MachineInstr &MI, BuildFnTy &MatchInfo);
  519. /// Match: shr (shl x, n), k -> sbfx/ubfx x, pos, width
  520. bool matchBitfieldExtractFromShr(MachineInstr &MI, BuildFnTy &MatchInfo);
  521. /// Match: shr (and x, n), k -> ubfx x, pos, width
  522. bool matchBitfieldExtractFromShrAnd(MachineInstr &MI, BuildFnTy &MatchInfo);
  523. // Helpers for reassociation:
  524. bool matchReassocConstantInnerRHS(GPtrAdd &MI, MachineInstr *RHS,
  525. BuildFnTy &MatchInfo);
  526. bool matchReassocFoldConstantsInSubTree(GPtrAdd &MI, MachineInstr *LHS,
  527. MachineInstr *RHS,
  528. BuildFnTy &MatchInfo);
  529. bool matchReassocConstantInnerLHS(GPtrAdd &MI, MachineInstr *LHS,
  530. MachineInstr *RHS, BuildFnTy &MatchInfo);
  531. /// Reassociate pointer calculations with G_ADD involved, to allow better
  532. /// addressing mode usage.
  533. bool matchReassocPtrAdd(MachineInstr &MI, BuildFnTy &MatchInfo);
  534. /// Do constant folding when opportunities are exposed after MIR building.
  535. bool matchConstantFold(MachineInstr &MI, APInt &MatchInfo);
  536. /// \returns true if it is possible to narrow the width of a scalar binop
  537. /// feeding a G_AND instruction \p MI.
  538. bool matchNarrowBinopFeedingAnd(MachineInstr &MI, BuildFnTy &MatchInfo);
  539. /// Given an G_UDIV \p MI expressing a divide by constant, return an
  540. /// expression that implements it by multiplying by a magic number.
  541. /// Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's Guide".
  542. MachineInstr *buildUDivUsingMul(MachineInstr &MI);
  543. /// Combine G_UDIV by constant into a multiply by magic constant.
  544. bool matchUDivByConst(MachineInstr &MI);
  545. void applyUDivByConst(MachineInstr &MI);
  546. /// Given an G_SDIV \p MI expressing a signed divide by constant, return an
  547. /// expression that implements it by multiplying by a magic number.
  548. /// Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's Guide".
  549. MachineInstr *buildSDivUsingMul(MachineInstr &MI);
  550. bool matchSDivByConst(MachineInstr &MI);
  551. void applySDivByConst(MachineInstr &MI);
  552. // G_UMULH x, (1 << c)) -> x >> (bitwidth - c)
  553. bool matchUMulHToLShr(MachineInstr &MI);
  554. void applyUMulHToLShr(MachineInstr &MI);
  555. /// Try to transform \p MI by using all of the above
  556. /// combine functions. Returns true if changed.
  557. bool tryCombine(MachineInstr &MI);
  558. /// Emit loads and stores that perform the given memcpy.
  559. /// Assumes \p MI is a G_MEMCPY_INLINE
  560. /// TODO: implement dynamically sized inline memcpy,
  561. /// and rename: s/bool tryEmit/void emit/
  562. bool tryEmitMemcpyInline(MachineInstr &MI);
  563. /// Match:
  564. /// (G_UMULO x, 2) -> (G_UADDO x, x)
  565. /// (G_SMULO x, 2) -> (G_SADDO x, x)
  566. bool matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo);
  567. /// Match:
  568. /// (G_*MULO x, 0) -> 0 + no carry out
  569. bool matchMulOBy0(MachineInstr &MI, BuildFnTy &MatchInfo);
  570. /// Match:
  571. /// (G_*ADDO x, 0) -> x + no carry out
  572. bool matchAddOBy0(MachineInstr &MI, BuildFnTy &MatchInfo);
  573. /// Match:
  574. /// (G_*ADDE x, y, 0) -> (G_*ADDO x, y)
  575. /// (G_*SUBE x, y, 0) -> (G_*SUBO x, y)
  576. bool matchAddEToAddO(MachineInstr &MI, BuildFnTy &MatchInfo);
  577. /// Transform (fadd x, fneg(y)) -> (fsub x, y)
  578. /// (fadd fneg(x), y) -> (fsub y, x)
  579. /// (fsub x, fneg(y)) -> (fadd x, y)
  580. /// (fmul fneg(x), fneg(y)) -> (fmul x, y)
  581. /// (fdiv fneg(x), fneg(y)) -> (fdiv x, y)
  582. /// (fmad fneg(x), fneg(y), z) -> (fmad x, y, z)
  583. /// (fma fneg(x), fneg(y), z) -> (fma x, y, z)
  584. bool matchRedundantNegOperands(MachineInstr &MI, BuildFnTy &MatchInfo);
  585. bool matchFsubToFneg(MachineInstr &MI, Register &MatchInfo);
  586. void applyFsubToFneg(MachineInstr &MI, Register &MatchInfo);
  587. bool canCombineFMadOrFMA(MachineInstr &MI, bool &AllowFusionGlobally,
  588. bool &HasFMAD, bool &Aggressive,
  589. bool CanReassociate = false);
  590. /// Transform (fadd (fmul x, y), z) -> (fma x, y, z)
  591. /// (fadd (fmul x, y), z) -> (fmad x, y, z)
  592. bool matchCombineFAddFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo);
  593. /// Transform (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)
  594. /// (fadd (fpext (fmul x, y)), z) -> (fmad (fpext x), (fpext y), z)
  595. bool matchCombineFAddFpExtFMulToFMadOrFMA(MachineInstr &MI,
  596. BuildFnTy &MatchInfo);
  597. /// Transform (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y, (fma u, v, z))
  598. /// (fadd (fmad x, y, (fmul u, v)), z) -> (fmad x, y, (fmad u, v, z))
  599. bool matchCombineFAddFMAFMulToFMadOrFMA(MachineInstr &MI,
  600. BuildFnTy &MatchInfo);
  601. // Transform (fadd (fma x, y, (fpext (fmul u, v))), z)
  602. // -> (fma x, y, (fma (fpext u), (fpext v), z))
  603. // (fadd (fmad x, y, (fpext (fmul u, v))), z)
  604. // -> (fmad x, y, (fmad (fpext u), (fpext v), z))
  605. bool matchCombineFAddFpExtFMulToFMadOrFMAAggressive(MachineInstr &MI,
  606. BuildFnTy &MatchInfo);
  607. /// Transform (fsub (fmul x, y), z) -> (fma x, y, -z)
  608. /// (fsub (fmul x, y), z) -> (fmad x, y, -z)
  609. bool matchCombineFSubFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo);
  610. /// Transform (fsub (fneg (fmul, x, y)), z) -> (fma (fneg x), y, (fneg z))
  611. /// (fsub (fneg (fmul, x, y)), z) -> (fmad (fneg x), y, (fneg z))
  612. bool matchCombineFSubFNegFMulToFMadOrFMA(MachineInstr &MI,
  613. BuildFnTy &MatchInfo);
  614. /// Transform (fsub (fpext (fmul x, y)), z)
  615. /// -> (fma (fpext x), (fpext y), (fneg z))
  616. /// (fsub (fpext (fmul x, y)), z)
  617. /// -> (fmad (fpext x), (fpext y), (fneg z))
  618. bool matchCombineFSubFpExtFMulToFMadOrFMA(MachineInstr &MI,
  619. BuildFnTy &MatchInfo);
  620. /// Transform (fsub (fpext (fneg (fmul x, y))), z)
  621. /// -> (fneg (fma (fpext x), (fpext y), z))
  622. /// (fsub (fpext (fneg (fmul x, y))), z)
  623. /// -> (fneg (fmad (fpext x), (fpext y), z))
  624. bool matchCombineFSubFpExtFNegFMulToFMadOrFMA(MachineInstr &MI,
  625. BuildFnTy &MatchInfo);
  626. /// Fold boolean selects to logical operations.
  627. bool matchSelectToLogical(MachineInstr &MI, BuildFnTy &MatchInfo);
  628. bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info);
  629. /// Transform G_ADD(x, G_SUB(y, x)) to y.
  630. /// Transform G_ADD(G_SUB(y, x), x) to y.
  631. bool matchAddSubSameReg(MachineInstr &MI, Register &Src);
  632. bool matchBuildVectorIdentityFold(MachineInstr &MI, Register &MatchInfo);
  633. bool matchTruncBuildVectorFold(MachineInstr &MI, Register &MatchInfo);
  634. bool matchTruncLshrBuildVectorFold(MachineInstr &MI, Register &MatchInfo);
  635. /// Transform:
  636. /// (x + y) - y -> x
  637. /// (x + y) - x -> y
  638. /// x - (y + x) -> 0 - y
  639. /// x - (x + z) -> 0 - z
  640. bool matchSubAddSameReg(MachineInstr &MI, BuildFnTy &MatchInfo);
  641. /// \returns true if it is possible to simplify a select instruction \p MI
  642. /// to a min/max instruction of some sort.
  643. bool matchSimplifySelectToMinMax(MachineInstr &MI, BuildFnTy &MatchInfo);
  644. /// Transform:
  645. /// (X + Y) == X -> Y == 0
  646. /// (X - Y) == X -> Y == 0
  647. /// (X ^ Y) == X -> Y == 0
  648. /// (X + Y) != X -> Y != 0
  649. /// (X - Y) != X -> Y != 0
  650. /// (X ^ Y) != X -> Y != 0
  651. bool matchRedundantBinOpInEquality(MachineInstr &MI, BuildFnTy &MatchInfo);
  652. private:
  653. /// Given a non-indexed load or store instruction \p MI, find an offset that
  654. /// can be usefully and legally folded into it as a post-indexing operation.
  655. ///
  656. /// \returns true if a candidate is found.
  657. bool findPostIndexCandidate(MachineInstr &MI, Register &Addr, Register &Base,
  658. Register &Offset);
  659. /// Given a non-indexed load or store instruction \p MI, find an offset that
  660. /// can be usefully and legally folded into it as a pre-indexing operation.
  661. ///
  662. /// \returns true if a candidate is found.
  663. bool findPreIndexCandidate(MachineInstr &MI, Register &Addr, Register &Base,
  664. Register &Offset);
  665. /// Helper function for matchLoadOrCombine. Searches for Registers
  666. /// which may have been produced by a load instruction + some arithmetic.
  667. ///
  668. /// \param [in] Root - The search root.
  669. ///
  670. /// \returns The Registers found during the search.
  671. std::optional<SmallVector<Register, 8>>
  672. findCandidatesForLoadOrCombine(const MachineInstr *Root) const;
  673. /// Helper function for matchLoadOrCombine.
  674. ///
  675. /// Checks if every register in \p RegsToVisit is defined by a load
  676. /// instruction + some arithmetic.
  677. ///
  678. /// \param [out] MemOffset2Idx - Maps the byte positions each load ends up
  679. /// at to the index of the load.
  680. /// \param [in] MemSizeInBits - The number of bits each load should produce.
  681. ///
  682. /// \returns On success, a 3-tuple containing lowest-index load found, the
  683. /// lowest index, and the last load in the sequence.
  684. std::optional<std::tuple<GZExtLoad *, int64_t, GZExtLoad *>>
  685. findLoadOffsetsForLoadOrCombine(
  686. SmallDenseMap<int64_t, int64_t, 8> &MemOffset2Idx,
  687. const SmallVector<Register, 8> &RegsToVisit,
  688. const unsigned MemSizeInBits);
  689. /// Examines the G_PTR_ADD instruction \p PtrAdd and determines if performing
  690. /// a re-association of its operands would break an existing legal addressing
  691. /// mode that the address computation currently represents.
  692. bool reassociationCanBreakAddressingModePattern(MachineInstr &PtrAdd);
  693. /// Behavior when a floating point min/max is given one NaN and one
  694. /// non-NaN as input.
  695. enum class SelectPatternNaNBehaviour {
  696. NOT_APPLICABLE = 0, /// NaN behavior not applicable.
  697. RETURNS_NAN, /// Given one NaN input, returns the NaN.
  698. RETURNS_OTHER, /// Given one NaN input, returns the non-NaN.
  699. RETURNS_ANY /// Given one NaN input, can return either (or both operands are
  700. /// known non-NaN.)
  701. };
  702. /// \returns which of \p LHS and \p RHS would be the result of a non-equality
  703. /// floating point comparison where one of \p LHS and \p RHS may be NaN.
  704. ///
  705. /// If both \p LHS and \p RHS may be NaN, returns
  706. /// SelectPatternNaNBehaviour::NOT_APPLICABLE.
  707. SelectPatternNaNBehaviour
  708. computeRetValAgainstNaN(Register LHS, Register RHS,
  709. bool IsOrderedComparison) const;
  710. /// Determines the floating point min/max opcode which should be used for
  711. /// a G_SELECT fed by a G_FCMP with predicate \p Pred.
  712. ///
  713. /// \returns 0 if this G_SELECT should not be combined to a floating point
  714. /// min or max. If it should be combined, returns one of
  715. ///
  716. /// * G_FMAXNUM
  717. /// * G_FMAXIMUM
  718. /// * G_FMINNUM
  719. /// * G_FMINIMUM
  720. ///
  721. /// Helper function for matchFPSelectToMinMax.
  722. unsigned getFPMinMaxOpcForSelect(CmpInst::Predicate Pred, LLT DstTy,
  723. SelectPatternNaNBehaviour VsNaNRetVal) const;
  724. /// Handle floating point cases for matchSimplifySelectToMinMax.
  725. ///
  726. /// E.g.
  727. ///
  728. /// select (fcmp uge x, 1.0) x, 1.0 -> fmax x, 1.0
  729. /// select (fcmp uge x, 1.0) 1.0, x -> fminnm x, 1.0
  730. bool matchFPSelectToMinMax(Register Dst, Register Cond, Register TrueVal,
  731. Register FalseVal, BuildFnTy &MatchInfo);
  732. };
  733. } // namespace llvm
  734. #endif
  735. #ifdef __GNUC__
  736. #pragma GCC diagnostic pop
  737. #endif