LLVM 23.0.0git
CombinerHelper.h
Go to the documentation of this file.
1//===-- llvm/CodeGen/GlobalISel/CombinerHelper.h --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===--------------------------------------------------------------------===//
8/// \file
9/// This contains common combine transformations that may be used in a combine
10/// pass,or by the target elsewhere.
11/// Targets can pick individual opcode transformations from the helper or use
12/// tryCombine which invokes all transformations. All of the transformations
13/// return true if the MachineInstruction changed and false otherwise.
14///
15//===--------------------------------------------------------------------===//
16
17#ifndef LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
18#define LLVM_CODEGEN_GLOBALISEL_COMBINERHELPER_H
19
20#include "llvm/ADT/DenseMap.h"
26#include "llvm/IR/InstrTypes.h"
27#include <functional>
28
29namespace llvm {
30
32class APInt;
33class ConstantFP;
34class GPtrAdd;
35class GZExtLoad;
39class MachineInstr;
40class MachineOperand;
43class LegalizerInfo;
44struct LegalityQuery;
45class RegisterBank;
47class TargetInstrInfo;
48class TargetLowering;
50
52 LLT Ty; // The result type of the extend.
53 unsigned ExtendOpcode; // G_ANYEXT/G_SEXT/G_ZEXT
55};
56
61 bool RematOffset = false; // True if Offset is a constant that needs to be
62 // rematerialized before the new load/store.
63 bool IsPre = false;
64};
65
67 int64_t Imm;
70 unsigned Flags;
71};
72
75 int64_t Imm;
76};
77
84
93
94using BuildFnTy = std::function<void(MachineIRBuilder &)>;
95
97 SmallVector<std::function<void(MachineInstrBuilder &)>, 4>;
99 unsigned Opcode = 0; /// The opcode for the produced instruction.
100 OperandBuildSteps OperandFns; /// Operands to be added to the instruction.
104};
105
107 /// Describes instructions to be built during a combine.
111 std::initializer_list<InstructionBuildSteps> InstrsToBuild)
113};
114
116protected:
127
128public:
130 bool IsPreLegalize, GISelValueTracking *VT = nullptr,
131 MachineDominatorTree *MDT = nullptr,
132 const LegalizerInfo *LI = nullptr);
133
135
137 return Builder;
138 }
139
140 const TargetInstrInfo &getTII() const { return *TII; }
141
142 const TargetRegisterInfo &getTRI() const { return *TRI; }
143
144 const RegisterBankInfo &getRBI() const { return *RBI; }
145
147
149
150 LLVM_ABI const DataLayout &getDataLayout() const;
151
153
154 /// \returns true if the combiner is running pre-legalization.
155 LLVM_ABI bool isPreLegalize() const;
156
157 /// \returns true if \p Query is legal on the target.
158 LLVM_ABI bool isLegal(const LegalityQuery &Query) const;
159
160 /// \return true if the combine is running prior to legalization, or if \p
161 /// Query is legal on the target.
162 LLVM_ABI bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const;
163
164 /// \return true if \p Query is legal on the target, or if \p Query will
165 /// perform WidenScalar action on the target.
166 LLVM_ABI bool isLegalOrHasWidenScalar(const LegalityQuery &Query) const;
167
168 /// \return true if \p Query is legal on the target, or if \p Query will
169 /// perform a FewerElements action on the target.
170 LLVM_ABI bool isLegalOrHasFewerElements(const LegalityQuery &Query) const;
171
172 /// \return true if the combine is running prior to legalization, or if \p Ty
173 /// is a legal integer constant type on the target.
174 LLVM_ABI bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const;
175
176 /// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
178 Register ToReg) const;
179
180 /// Replace a single register operand with a new register and inform the
181 /// observer of the changes.
183 MachineOperand &FromRegOp,
184 Register ToReg) const;
185
186 /// Replace the opcode in instruction with a new opcode and inform the
187 /// observer of the changes.
189 unsigned ToOpcode) const;
190
191 /// Get the register bank of \p Reg.
192 /// If Reg has not been assigned a register, a register class,
193 /// or a register bank, then this returns nullptr.
194 ///
195 /// \pre Reg.isValid()
197
198 /// Set the register bank of \p Reg.
199 /// Does nothing if the RegBank is null.
200 /// This is the counterpart to getRegBank.
201 LLVM_ABI void setRegBank(Register Reg, const RegisterBank *RegBank) const;
202
203 /// If \p MI is COPY, try to combine it.
204 /// Returns true if MI changed.
208
209 /// Returns true if \p DefMI precedes \p UseMI or they are the same
210 /// instruction. Both must be in the same basic block.
212 const MachineInstr &UseMI) const;
213
214 /// Returns true if \p DefMI dominates \p UseMI. By definition an
215 /// instruction dominates itself.
216 ///
217 /// If we haven't been provided with a MachineDominatorTree during
218 /// construction, this function returns a conservative result that tracks just
219 /// a single basic block.
221 const MachineInstr &UseMI) const;
222
223 /// If \p MI is extend that consumes the result of a load, try to combine it.
224 /// Returns true if MI changed.
227 PreferredTuple &MatchInfo) const;
229 PreferredTuple &MatchInfo) const;
230
231 /// Match (and (load x), mask) -> zextload x
233 BuildFnTy &MatchInfo) const;
234
235 /// Combine a G_EXTRACT_VECTOR_ELT of a load into a narrowed
236 /// load.
238 BuildFnTy &MatchInfo) const;
239
240 LLVM_ABI bool
242 IndexedLoadStoreMatchInfo &MatchInfo) const;
243 LLVM_ABI void
245 IndexedLoadStoreMatchInfo &MatchInfo) const;
246
249
250 /// Match sext_inreg(load p), imm -> sextload p
251 LLVM_ABI bool
253 std::tuple<Register, unsigned> &MatchInfo) const;
254 LLVM_ABI void
256 std::tuple<Register, unsigned> &MatchInfo) const;
257
258 /// Try to combine G_[SU]DIV and G_[SU]REM into a single G_[SU]DIVREM
259 /// when their source operands are identical.
261 MachineInstr *&OtherMI) const;
263 MachineInstr *&OtherMI) const;
264
265 /// If a brcond's true block is not the fallthrough, make it so by inverting
266 /// the condition and swapping operands.
268 MachineInstr *&BrCond) const;
270 MachineInstr *&BrCond) const;
271
272 /// If \p MI is G_CONCAT_VECTORS, try to combine it.
273 /// Returns true if MI changed.
274 /// Right now, we support:
275 /// - concat_vector(undef, undef) => undef
276 /// - concat_vector(build_vector(A, B), build_vector(C, D)) =>
277 /// build_vector(A, B, C, D)
278 /// ==========================================================
279 /// Check if the G_CONCAT_VECTORS \p MI is undef or if it
280 /// can be flattened into a build_vector.
281 /// In the first case \p Ops will be empty
282 /// In the second case \p Ops will contain the operands
283 /// needed to produce the flattened build_vector.
284 ///
285 /// \pre MI.getOpcode() == G_CONCAT_VECTORS.
288 /// Replace \p MI with a flattened build_vector with \p Ops
289 /// or an implicit_def if \p Ops is empty.
292
295 /// Replace \p MI with a flattened build_vector with \p Ops
296 /// or an implicit_def if \p Ops is empty.
299
300 /// Replace \p MI with a build_vector.
302
303 /// Combine G_BUILD_VECTOR(G_UNMERGE(G_BITCAST), Undef) to
304 /// G_BITCAST(G_BUILD_VECTOR(..))
305 LLVM_ABI bool
308 LLVM_ABI void
311
312 /// Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
313 /// Returns true if MI changed.
314 ///
315 /// \pre MI.getOpcode() == G_SHUFFLE_VECTOR.
317 /// Check if the G_SHUFFLE_VECTOR \p MI can be replaced by a
318 /// concat_vectors.
319 /// \p Ops will contain the operands needed to produce the flattened
320 /// concat_vectors.
321 ///
322 /// \pre MI.getOpcode() == G_SHUFFLE_VECTOR.
325 /// Replace \p MI with a concat_vectors with \p Ops.
327 ArrayRef<Register> Ops) const;
328
329 /// Optimize memcpy intrinsics et al, e.g. constant len calls.
330 /// /p MaxLen if non-zero specifies the max length of a mem libcall to inline.
331 ///
332 /// For example (pre-indexed):
333 ///
334 /// $addr = G_PTR_ADD $base, $offset
335 /// [...]
336 /// $val = G_LOAD $addr
337 /// [...]
338 /// $whatever = COPY $addr
339 ///
340 /// -->
341 ///
342 /// $val, $addr = G_INDEXED_LOAD $base, $offset, 1 (IsPre)
343 /// [...]
344 /// $whatever = COPY $addr
345 ///
346 /// or (post-indexed):
347 ///
348 /// G_STORE $val, $base
349 /// [...]
350 /// $addr = G_PTR_ADD $base, $offset
351 /// [...]
352 /// $whatever = COPY $addr
353 ///
354 /// -->
355 ///
356 /// $addr = G_INDEXED_STORE $val, $base, $offset
357 /// [...]
358 /// $whatever = COPY $addr
360 unsigned MaxLen = 0) const;
361
363 PtrAddChain &MatchInfo) const;
365 PtrAddChain &MatchInfo) const;
366
367 /// Fold (shift (shift base, x), y) -> (shift base (x+y))
369 RegisterImmPair &MatchInfo) const;
371 RegisterImmPair &MatchInfo) const;
372
373 /// If we have a shift-by-constant of a bitwise logic op that itself has a
374 /// shift-by-constant operand with identical opcode, we may be able to convert
375 /// that into 2 independent shifts followed by the logic op.
377 ShiftOfShiftedLogic &MatchInfo) const;
379 ShiftOfShiftedLogic &MatchInfo) const;
380
381 LLVM_ABI bool matchCommuteShift(MachineInstr &MI, BuildFnTy &MatchInfo) const;
382
383 /// Fold (lshr (trunc (lshr x, C1)), C2) -> trunc (shift x, (C1 + C2))
385 LshrOfTruncOfLshr &MatchInfo,
386 MachineInstr &ShiftMI) const;
388 LshrOfTruncOfLshr &MatchInfo) const;
389
390 /// Transform a multiply by a power-of-2 value to a left shift.
392 unsigned &ShiftVal) const;
394 unsigned &ShiftVal) const;
395
396 // Transform a G_SUB with constant on the RHS to G_ADD.
398 BuildFnTy &MatchInfo) const;
399
400 // Transform a G_SHL with an extended source into a narrower shift if
401 // possible.
403 RegisterImmPair &MatchData) const;
405 const RegisterImmPair &MatchData) const;
406
407 /// Fold away a merge of an unmerge of the corresponding values.
409 Register &MatchInfo) const;
410
411 /// Reduce a shift by a constant to an unmerge and a shift on a half sized
412 /// type. This will not produce a shift smaller than \p TargetShiftSize.
414 unsigned TargetShiftSize,
415 unsigned &ShiftVal) const;
417 const unsigned &ShiftVal) const;
419 unsigned TargetShiftAmount) const;
420
421 /// Transform <ty,...> G_UNMERGE(G_MERGE ty X, Y, Z) -> ty X, Y, Z.
423 MachineInstr &MI, SmallVectorImpl<Register> &Operands) const;
425 MachineInstr &MI, SmallVectorImpl<Register> &Operands) const;
426
427 /// Transform G_UNMERGE Constant -> Constant1, Constant2, ...
429 SmallVectorImpl<APInt> &Csts) const;
431 SmallVectorImpl<APInt> &Csts) const;
432
433 /// Transform G_UNMERGE G_IMPLICIT_DEF -> G_IMPLICIT_DEF, G_IMPLICIT_DEF, ...
436 std::function<void(MachineIRBuilder &)> &MatchInfo) const;
437
438 /// Transform X, Y<dead> = G_UNMERGE Z -> X = G_TRUNC Z.
441
442 /// Transform X, Y = G_UNMERGE(G_ZEXT(Z)) -> X = G_ZEXT(Z); Y = G_CONSTANT 0
445
446 /// Transform fp_instr(cst) to constant result of the fp operation.
448 const ConstantFP *Cst) const;
449
450 /// Constant fold a unary integer op (G_CTLZ, G_CTTZ, G_CTPOP and their
451 /// _ZERO_POISON variants, G_ABS, G_BSWAP, G_BITREVERSE) when the operand is
452 /// a scalar constant or a G_BUILD_VECTOR of constants.
454 BuildFnTy &MatchInfo) const;
455
456 /// Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space.
459
460 /// Transform PtrToInt(IntToPtr(x)) to x.
462
463 /// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
464 /// Transform G_ADD y, (G_PTRTOINT x) -> G_PTRTOINT (G_PTR_ADD x, y)
465 LLVM_ABI bool
467 std::pair<Register, bool> &PtrRegAndCommute) const;
468 LLVM_ABI void
470 std::pair<Register, bool> &PtrRegAndCommute) const;
471
472 // Transform G_PTR_ADD (G_PTRTOINT C1), C2 -> C1 + C2
474 APInt &NewCst) const;
476 APInt &NewCst) const;
477
478 /// Transform anyext(trunc(x)) to x.
480
481 /// Transform zext(trunc(x)) to x.
483
484 /// Transform trunc (shl x, K) to shl (trunc x), K
485 /// if K < VT.getScalarSizeInBits().
486 ///
487 /// Transforms trunc ([al]shr x, K) to (trunc ([al]shr (MidVT (trunc x)), K))
488 /// if K <= (MidVT.getScalarSizeInBits() - VT.getScalarSizeInBits())
489 /// MidVT is obtained by finding a legal type between the trunc's src and dst
490 /// types.
491 LLVM_ABI bool
493 std::pair<MachineInstr *, LLT> &MatchInfo) const;
494 LLVM_ABI void
496 std::pair<MachineInstr *, LLT> &MatchInfo) const;
497
498 /// Return true if any explicit use operand on \p MI is defined by a
499 /// G_IMPLICIT_DEF.
501
502 /// Return true if all register explicit use operands on \p MI are defined by
503 /// a G_IMPLICIT_DEF.
505
506 /// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
508
509 /// Return true if a G_STORE instruction \p MI is storing an undef value.
511
512 /// Return true if a G_SELECT instruction \p MI has an undef comparison.
514
515 /// Return true if a G_{EXTRACT,INSERT}_VECTOR_ELT has an out of range index.
517
518 /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
519 /// true, \p OpIdx will store the operand index of the known selected value.
520 LLVM_ABI bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) const;
521
522 /// Replace an instruction with a G_FCONSTANT with value \p C.
524
525 /// Replace an instruction with an G_FCONSTANT with value \p CFP.
527 ConstantFP *CFP) const;
528
529 /// Replace an instruction with a G_CONSTANT with value \p C.
530 LLVM_ABI void replaceInstWithConstant(MachineInstr &MI, int64_t C) const;
531
532 /// Replace an instruction with a G_CONSTANT with value \p C.
534
535 /// Replace an instruction with a G_IMPLICIT_DEF.
537
538 /// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
540 unsigned OpIdx) const;
541
542 /// Delete \p MI and replace all of its uses with \p Replacement.
544 Register Replacement) const;
545
546 /// @brief Replaces the shift amount in \p MI with ShiftAmt % BW
547 /// @param MI
549
550 /// Return true if \p MOP1 and \p MOP2 are register operands are defined by
551 /// equivalent instructions.
552 LLVM_ABI bool matchEqualDefs(const MachineOperand &MOP1,
553 const MachineOperand &MOP2) const;
554
555 /// Return true if \p MOP is defined by a G_CONSTANT or splat with a value equal to
556 /// \p C.
557 LLVM_ABI bool matchConstantOp(const MachineOperand &MOP, int64_t C) const;
558
559 /// Return true if \p MOP is defined by a G_FCONSTANT or splat with a value exactly
560 /// equal to \p C.
561 LLVM_ABI bool matchConstantFPOp(const MachineOperand &MOP, double C) const;
562
563 /// @brief Checks if constant at \p ConstIdx is larger than \p MI 's bitwidth
564 /// @param ConstIdx Index of the constant
566 unsigned ConstIdx) const;
567
568 /// Optimize (cond ? x : x) -> x
570
571 /// Optimize (x op x) -> x
573
574 /// Check if operand \p OpIdx is undef.
575 LLVM_ABI bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) const;
576
577 /// Check if operand \p MO is known to be a power of 2. When \p OrNegative
578 /// is true, also match operands whose negation is a power of 2 (i.e. whose
579 /// absolute value is a power of 2).
580 LLVM_ABI bool
582 bool OrNegative = false) const;
583
584 /// Erase \p MI
585 LLVM_ABI void eraseInst(MachineInstr &MI) const;
586
587 /// Return true if MI is a G_ADD which can be simplified to a G_SUB.
588 LLVM_ABI bool
590 std::tuple<Register, Register> &MatchInfo) const;
591 LLVM_ABI void
593 std::tuple<Register, Register> &MatchInfo) const;
594
595 /// Fold `a bitwiseop (~b +/- c)` -> `a bitwiseop ~(b -/+ c)`
596 LLVM_ABI bool matchBinopWithNeg(MachineInstr &MI, BuildFnTy &MatchInfo) const;
597
598 /// Match (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
600 MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) const;
601
602 /// Replace \p MI with a series of instructions described in \p MatchInfo.
603 LLVM_ABI void
605 InstructionStepsMatchInfo &MatchInfo) const;
606
607 /// Match ashr (shl x, C), C -> sext_inreg (C)
608 LLVM_ABI bool
610 std::tuple<Register, int64_t> &MatchInfo) const;
611 LLVM_ABI void
613 std::tuple<Register, int64_t> &MatchInfo) const;
614
615 /// Fold and(and(x, C1), C2) -> C1&C2 ? and(x, C1&C2) : 0
617 BuildFnTy &MatchInfo) const;
618
619 /// \return true if \p MI is a G_AND instruction whose operands are x and y
620 /// where x & y == x or x & y == y. (E.g., one of operands is all-ones value.)
621 ///
622 /// \param [in] MI - The G_AND instruction.
623 /// \param [out] Replacement - A register the G_AND should be replaced with on
624 /// success.
626 Register &Replacement) const;
627
628 /// \return true if \p MI is a G_OR instruction whose operands are x and y
629 /// where x | y == x or x | y == y. (E.g., one of operands is all-zeros
630 /// value.)
631 ///
632 /// \param [in] MI - The G_OR instruction.
633 /// \param [out] Replacement - A register the G_OR should be replaced with on
634 /// success.
635 LLVM_ABI bool matchRedundantOr(MachineInstr &MI, Register &Replacement) const;
636
637 /// \return true if \p MI is a G_SEXT_INREG that can be erased.
639
640 /// Combine inverting a result of a compare into the opposite cond code.
642 SmallVectorImpl<Register> &RegsToNegate) const;
644 SmallVectorImpl<Register> &RegsToNegate) const;
645
646 /// Fold (xor (and x, y), y) -> (and (not x), y)
647 ///{
648 LLVM_ABI bool
650 std::pair<Register, Register> &MatchInfo) const;
651 LLVM_ABI void
653 std::pair<Register, Register> &MatchInfo) const;
654 ///}
655
656 /// Combine G_PTR_ADD with nullptr to G_INTTOPTR
659
660 /// Combine G_UREM x, (known power of 2) to an add and bitmasking.
662
663 /// Push a binary operator through a select on constants.
664 ///
665 /// binop (select cond, K0, K1), K2 ->
666 /// select cond, (binop K0, K2), (binop K1, K2)
668 unsigned &SelectOpNo) const;
670 const unsigned &SelectOpNo) const;
671
672 LLVM_ABI bool
674 SmallVectorImpl<Register> &MatchInfo) const;
675
676 LLVM_ABI void
678 SmallVectorImpl<Register> &MatchInfo) const;
679
680 /// Match expression trees of the form
681 ///
682 /// \code
683 /// sN *a = ...
684 /// sM val = a[0] | (a[1] << N) | (a[2] << 2N) | (a[3] << 3N) ...
685 /// \endcode
686 ///
687 /// And check if the tree can be replaced with a M-bit load + possibly a
688 /// bswap.
690 BuildFnTy &MatchInfo) const;
691
693 MachineInstr *&ExtMI) const;
695 MachineInstr *&ExtMI) const;
696
698 Register &Reg) const;
700 Register &Reg) const;
701
704 SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo) const;
707 SmallVectorImpl<std::pair<Register, MachineInstr *>> &MatchInfo) const;
708
709 /// Use a function which takes in a MachineIRBuilder to perform a combine.
710 /// By default, it erases the instruction \p MI from the function.
711 LLVM_ABI void applyBuildFn(MachineInstr &MI, BuildFnTy &MatchInfo) const;
712 /// Use a function which takes in a MachineIRBuilder to perform a combine.
713 /// This variant does not erase \p MI after calling the build function.
715 BuildFnTy &MatchInfo) const;
716
718 bool AllowScalarConstants,
719 BuildFnTy &MatchInfo) const;
724
727 Register &UnmergeSrc) const;
731 Register &UnmergeSrc) const;
732
734 Register &MatchInfo) const;
736 Register &MatchInfo) const;
737
738 /// \returns true if a G_ICMP instruction \p MI can be replaced with a true
739 /// or false constant based off of KnownBits information.
741 int64_t &MatchInfo) const;
742
743 /// \returns true if a G_ICMP \p MI can be replaced with its LHS based off of
744 /// KnownBits information.
746 BuildFnTy &MatchInfo) const;
747
748 /// \returns true if (and (or x, c1), c2) can be replaced with (and x, c2)
750 BuildFnTy &MatchInfo) const;
751
753 BuildFnTy &MatchInfo) const;
754 /// Match: and (lshr x, cst), mask -> ubfx x, cst, width
756 BuildFnTy &MatchInfo) const;
757
758 /// Match: shr (shl x, n), k -> sbfx/ubfx x, pos, width
760 BuildFnTy &MatchInfo) const;
761
762 /// Match: shr (and x, n), k -> ubfx x, pos, width
764 BuildFnTy &MatchInfo) const;
765
766 // Helpers for reassociation:
768 BuildFnTy &MatchInfo) const;
772 BuildFnTy &MatchInfo) const;
775 BuildFnTy &MatchInfo) const;
776 /// Reassociate pointer calculations with G_ADD involved, to allow better
777 /// addressing mode usage.
779 BuildFnTy &MatchInfo) const;
780
781 /// Try to reassociate to reassociate operands of a commutative binop.
782 LLVM_ABI bool tryReassocBinOp(unsigned Opc, Register DstReg, Register Op0,
783 Register Op1, BuildFnTy &MatchInfo) const;
784 /// Reassociate commutative binary operations like G_ADD.
786 BuildFnTy &MatchInfo) const;
787
788 /// Do constant folding when opportunities are exposed after MIR building.
790 APInt &MatchInfo) const;
791
792 /// Do constant folding when opportunities are exposed after MIR building.
794 APInt &MatchInfo) const;
795
796 /// Do constant FP folding when opportunities are exposed after MIR building.
798 ConstantFP *&MatchInfo) const;
799
800 /// Constant fold G_FMA/G_FMAD.
802 ConstantFP *&MatchInfo) const;
803
804 /// \returns true if it is possible to narrow the width of a scalar binop
805 /// feeding a G_AND instruction \p MI.
807 BuildFnTy &MatchInfo) const;
808
809 /// Given an G_UDIV \p MI or G_UREM \p MI expressing a divide by constant,
810 /// return an expression that implements it by multiplying by a magic number.
811 /// Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's Guide".
813 /// Combine G_UDIV or G_UREM by constant into a multiply by magic constant.
816
817 /// Given an G_SDIV \p MI or G_SREM \p MI expressing a signed divide by
818 /// constant, return an expression that implements it by multiplying by a
819 /// magic number. Ref: "Hacker's Delight" or "The PowerPC Compiler Writer's
820 /// Guide".
822 /// Combine G_SDIV or G_SREM by constant into a multiply by magic constant.
825
826 /// Given an G_SDIV \p MI expressing a signed divided by a pow2 constant,
827 /// return expressions that implements it by shifting.
828 LLVM_ABI bool matchDivByPow2(MachineInstr &MI, bool IsSigned) const;
830 /// Given an G_UDIV \p MI expressing an unsigned divided by a pow2 constant,
831 /// return expressions that implements it by shifting.
833
834 /// Combine G_SREM x, (+/-2^k) to a bias-and-mask sequence.
836
837 // G_UMULH x, (1 << c)) -> x >> (bitwidth - c)
840
841 // Combine trunc(smin(smax(x, C1), C2)) -> truncssat_s(x)
842 // or trunc(smax(smin(x, C2), C1)) -> truncssat_s(x).
843 LLVM_ABI bool matchTruncSSatS(MachineInstr &MI, Register &MatchInfo) const;
844 LLVM_ABI void applyTruncSSatS(MachineInstr &MI, Register &MatchInfo) const;
845
846 // Combine trunc(smin(smax(x, 0), C)) -> truncssat_u(x)
847 // or trunc(smax(smin(x, C), 0)) -> truncssat_u(x)
848 // or trunc(umin(smax(x, 0), C)) -> truncssat_u(x)
849 LLVM_ABI bool matchTruncSSatU(MachineInstr &MI, Register &MatchInfo) const;
850 LLVM_ABI void applyTruncSSatU(MachineInstr &MI, Register &MatchInfo) const;
851
852 // Combine trunc(umin(x, C)) -> truncusat_u(x).
854
855 // Combine truncusat_u(fptoui(x)) -> fptoui_sat(x)
857 MachineInstr &SrcMI) const;
858
859 /// Try to transform \p MI by using all of the above
860 /// combine functions. Returns true if changed.
862
863 /// Emit loads and stores that perform the given memcpy.
864 /// Assumes \p MI is a G_MEMCPY_INLINE
865 /// TODO: implement dynamically sized inline memcpy,
866 /// and rename: s/bool tryEmit/void emit/
868
869 /// Match:
870 /// (G_UMULO x, 2) -> (G_UADDO x, x)
871 /// (G_SMULO x, 2) -> (G_SADDO x, x)
872 LLVM_ABI bool matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo) const;
873
874 /// Match:
875 /// (G_*MULO x, 0) -> 0 + no carry out
876 LLVM_ABI bool matchMulOBy0(MachineInstr &MI, BuildFnTy &MatchInfo) const;
877
878 /// Match:
879 /// (G_*ADDE x, y, 0) -> (G_*ADDO x, y)
880 /// (G_*SUBE x, y, 0) -> (G_*SUBO x, y)
881 LLVM_ABI bool matchAddEToAddO(MachineInstr &MI, BuildFnTy &MatchInfo) const;
882
883 /// Transform (fadd x, fneg(y)) -> (fsub x, y)
884 /// (fadd fneg(x), y) -> (fsub y, x)
885 /// (fsub x, fneg(y)) -> (fadd x, y)
886 /// (fmul fneg(x), fneg(y)) -> (fmul x, y)
887 /// (fdiv fneg(x), fneg(y)) -> (fdiv x, y)
888 /// (fmad fneg(x), fneg(y), z) -> (fmad x, y, z)
889 /// (fma fneg(x), fneg(y), z) -> (fma x, y, z)
891 BuildFnTy &MatchInfo) const;
892
893 LLVM_ABI bool matchFsubToFneg(MachineInstr &MI, Register &MatchInfo) const;
894 LLVM_ABI void applyFsubToFneg(MachineInstr &MI, Register &MatchInfo) const;
895
896 LLVM_ABI bool canCombineFMadOrFMA(MachineInstr &MI, bool &AllowFusionGlobally,
897 bool &HasFMAD, bool &Aggressive,
898 bool CanReassociate = false) const;
899
900 /// Transform (fadd (fmul x, y), z) -> (fma x, y, z)
901 /// (fadd (fmul x, y), z) -> (fmad x, y, z)
903 BuildFnTy &MatchInfo) const;
904
905 /// Transform (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)
906 /// (fadd (fpext (fmul x, y)), z) -> (fmad (fpext x), (fpext y), z)
907 LLVM_ABI bool
909 BuildFnTy &MatchInfo) const;
910
911 /// Transform (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y, (fma u, v, z))
912 /// (fadd (fmad x, y, (fmul u, v)), z) -> (fmad x, y, (fmad u, v, z))
914 BuildFnTy &MatchInfo) const;
915
916 // Transform (fadd (fma x, y, (fpext (fmul u, v))), z)
917 // -> (fma x, y, (fma (fpext u), (fpext v), z))
918 // (fadd (fmad x, y, (fpext (fmul u, v))), z)
919 // -> (fmad x, y, (fmad (fpext u), (fpext v), z))
920 LLVM_ABI bool
922 BuildFnTy &MatchInfo) const;
923
924 /// Transform (fsub (fmul x, y), z) -> (fma x, y, -z)
925 /// (fsub (fmul x, y), z) -> (fmad x, y, -z)
927 BuildFnTy &MatchInfo) const;
928
929 /// Transform (fsub (fneg (fmul, x, y)), z) -> (fma (fneg x), y, (fneg z))
930 /// (fsub (fneg (fmul, x, y)), z) -> (fmad (fneg x), y, (fneg z))
932 BuildFnTy &MatchInfo) const;
933
934 /// Transform (fsub (fpext (fmul x, y)), z)
935 /// -> (fma (fpext x), (fpext y), (fneg z))
936 /// (fsub (fpext (fmul x, y)), z)
937 /// -> (fmad (fpext x), (fpext y), (fneg z))
938 LLVM_ABI bool
940 BuildFnTy &MatchInfo) const;
941
942 /// Transform (fsub (fpext (fneg (fmul x, y))), z)
943 /// -> (fneg (fma (fpext x), (fpext y), z))
944 /// (fsub (fpext (fneg (fmul x, y))), z)
945 /// -> (fneg (fmad (fpext x), (fpext y), z))
946 LLVM_ABI bool
948 BuildFnTy &MatchInfo) const;
949
950 LLVM_ABI bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info) const;
951
952 LLVM_ABI bool
954 SmallVector<MachineInstr *> &MatchInfo) const;
955 LLVM_ABI void
957
958 /// Transform G_ADD(x, G_SUB(y, x)) to y.
959 /// Transform G_ADD(G_SUB(y, x), x) to y.
961
963 Register &MatchInfo) const;
965 Register &MatchInfo) const;
967 Register &MatchInfo) const;
968
969 /// Transform:
970 /// (x + y) - y -> x
971 /// (x + y) - x -> y
972 /// x - (y + x) -> 0 - y
973 /// x - (x + z) -> 0 - z
975 BuildFnTy &MatchInfo) const;
976
977 /// \returns true if it is possible to simplify a select instruction \p MI
978 /// to a min/max instruction of some sort.
980 BuildFnTy &MatchInfo) const;
981
982 /// Transform:
983 /// (X + Y) == X -> Y == 0
984 /// (X - Y) == X -> Y == 0
985 /// (X ^ Y) == X -> Y == 0
986 /// (X + Y) != X -> Y != 0
987 /// (X - Y) != X -> Y != 0
988 /// (X ^ Y) != X -> Y != 0
990 BuildFnTy &MatchInfo) const;
991
992 /// Match shifts greater or equal to the range (the bitwidth of the result
993 /// datatype, or the effective bitwidth of the source value).
995 std::optional<int64_t> &MatchInfo) const;
996
997 /// Match constant LHS ops that should be commuted.
999
1000 /// Combine sext of trunc.
1002 BuildFnTy &MatchInfo) const;
1003
1004 /// Combine zext of trunc.
1006 BuildFnTy &MatchInfo) const;
1007
1008 /// Combine zext nneg to sext.
1010 BuildFnTy &MatchInfo) const;
1011
1012 /// Match constant LHS FP ops that should be commuted.
1014
1015 // Given a binop \p MI, commute operands 1 and 2.
1017
1018 /// Combine select to integer min/max.
1020 BuildFnTy &MatchInfo) const;
1021
1022 /// Tranform (neg (min/max x, (neg x))) into (max/min x, (neg x)).
1024 BuildFnTy &MatchInfo) const;
1025
1026 /// Combine selects.
1027 LLVM_ABI bool matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) const;
1028
1029 /// Combine ands.
1030 LLVM_ABI bool matchAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const;
1031
1032 /// Combine ors.
1033 LLVM_ABI bool matchOr(MachineInstr &MI, BuildFnTy &MatchInfo) const;
1034
1035 /// trunc (binop X, C) --> binop (trunc X, trunc C).
1036 LLVM_ABI bool matchNarrowBinop(const MachineInstr &TruncMI,
1037 const MachineInstr &BinopMI,
1038 BuildFnTy &MatchInfo) const;
1039
1040 LLVM_ABI bool matchCastOfInteger(const MachineInstr &CastMI,
1041 APInt &MatchInfo) const;
1042
1043 /// Combine addos.
1044 LLVM_ABI bool matchAddOverflow(MachineInstr &MI, BuildFnTy &MatchInfo) const;
1045
1046 /// Combine extract vector element.
1048 BuildFnTy &MatchInfo) const;
1049
1050 /// Combine extract vector element with a build vector on the vector register.
1051 LLVM_ABI bool
1053 const MachineInstr &MI2,
1054 BuildFnTy &MatchInfo) const;
1055
1056 /// Combine extract vector element with a build vector trunc on the vector
1057 /// register.
1058 LLVM_ABI bool
1060 BuildFnTy &MatchInfo) const;
1061
1062 /// Combine extract vector element with a shuffle vector on the vector
1063 /// register.
1064 LLVM_ABI bool
1066 const MachineInstr &MI2,
1067 BuildFnTy &MatchInfo) const;
1068
1069 /// Combine extract vector element with a insert vector element on the vector
1070 /// register and different indices.
1071 LLVM_ABI bool
1073 BuildFnTy &MatchInfo) const;
1074
1075 /// Remove references to rhs if it is undef
1077 BuildFnTy &MatchInfo) const;
1078
1079 /// Turn shuffle a, b, mask -> shuffle undef, b, mask iff mask does not
1080 /// reference a.
1082 BuildFnTy &MatchInfo) const;
1083
1084 /// Use a function which takes in a MachineIRBuilder to perform a combine.
1085 /// By default, it erases the instruction def'd on \p MO from the function.
1086 LLVM_ABI void applyBuildFnMO(const MachineOperand &MO,
1087 BuildFnTy &MatchInfo) const;
1088
1089 /// Match FPOWI if it's safe to extend it into a series of multiplications.
1090 LLVM_ABI bool matchFPowIExpansion(MachineInstr &MI, int64_t Exponent) const;
1091
1092 /// Expands FPOWI into a series of multiplications and a division if the
1093 /// exponent is negative.
1094 LLVM_ABI void applyExpandFPowI(MachineInstr &MI, int64_t Exponent) const;
1095
1096 /// Combine insert vector element OOB.
1098 BuildFnTy &MatchInfo) const;
1099
1100 LLVM_ABI bool
1102 BuildFnTy &MatchInfo) const;
1103
1105 BuildFnTy &MatchInfo) const;
1106
1108 BuildFnTy &MatchInfo) const;
1109
1111 BuildFnTy &MatchInfo) const;
1112
1114 BuildFnTy &MatchInfo) const;
1115
1116 /// Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
1117 LLVM_ABI bool matchTruncateOfExt(const MachineInstr &Root,
1118 const MachineInstr &ExtMI,
1119 BuildFnTy &MatchInfo) const;
1120
1121 LLVM_ABI bool matchCastOfSelect(const MachineInstr &Cast,
1122 const MachineInstr &SelectMI,
1123 BuildFnTy &MatchInfo) const;
1125 BuildFnTy &MatchInfo) const;
1126
1128 BuildFnTy &MatchInfo) const;
1129
1131 BuildFnTy &MatchInfo) const;
1132
1134 BuildFnTy &MatchInfo) const;
1135
1136 // fold ((A-C1)+C2) -> (A+(C2-C1))
1138 BuildFnTy &MatchInfo) const;
1139
1140 LLVM_ABI bool matchExtOfExt(const MachineInstr &FirstMI,
1141 const MachineInstr &SecondMI,
1142 BuildFnTy &MatchInfo) const;
1143
1144 LLVM_ABI bool matchCastOfBuildVector(const MachineInstr &CastMI,
1145 const MachineInstr &BVMI,
1146 BuildFnTy &MatchInfo) const;
1147
1149 BuildFnTy &MatchInfo) const;
1151 BuildFnTy &MatchInfo) const;
1152
1153 // unmerge_values(anyext(build vector)) -> build vector(anyext)
1155 BuildFnTy &MatchInfo) const;
1156
1157 // merge_values(_, undef) -> anyext
1159 BuildFnTy &MatchInfo) const;
1160
1161 // merge_values(_, zero) -> zext
1163 BuildFnTy &MatchInfo) const;
1164
1165 // overflow sub
1167 BuildFnTy &MatchInfo) const;
1168
1169 // (sext_inreg (sext_inreg x, K0), K1)
1171 BuildFnTy &MatchInfo) const;
1172
1173 // (ctlz (xor x, (sra x, bitwidth-1))) -> (add (ctls x), 1) or
1174 // (ctlz (or (shl (xor x, (sra x, bitwidth-1)), 1), 1) -> (ctls x)
1175 LLVM_ABI bool matchCtls(MachineInstr &CtlzMI, BuildFnTy &MatchInfo) const;
1176
1178 Register Y, unsigned TargetOpc) const;
1179
1180private:
1181 /// Checks for legality of an indexed variant of \p LdSt.
1182 bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
1183
1184 /// Helper function for matchBinopWithNeg: tries to match one commuted form
1185 /// of `a bitwiseop (~b +/- c)` -> `a bitwiseop ~(b -/+ c)`.
1186 bool matchBinopWithNegInner(Register MInner, Register Other, unsigned RootOpc,
1187 Register Dst, LLT Ty, BuildFnTy &MatchInfo) const;
1188 /// Given a non-indexed load or store instruction \p MI, find an offset that
1189 /// can be usefully and legally folded into it as a post-indexing operation.
1190 ///
1191 /// \returns true if a candidate is found.
1192 bool findPostIndexCandidate(GLoadStore &MI, Register &Addr, Register &Base,
1193 Register &Offset, bool &RematOffset) const;
1194
1195 /// Given a non-indexed load or store instruction \p MI, find an offset that
1196 /// can be usefully and legally folded into it as a pre-indexing operation.
1197 ///
1198 /// \returns true if a candidate is found.
1199 bool findPreIndexCandidate(GLoadStore &MI, Register &Addr, Register &Base,
1200 Register &Offset) const;
1201
1202 /// Helper function for matchLoadOrCombine. Searches for Registers
1203 /// which may have been produced by a load instruction + some arithmetic.
1204 ///
1205 /// \param [in] Root - The search root.
1206 ///
1207 /// \returns The Registers found during the search.
1208 std::optional<SmallVector<Register, 8>>
1209 findCandidatesForLoadOrCombine(const MachineInstr *Root) const;
1210
1211 /// Helper function for matchLoadOrCombine.
1212 ///
1213 /// Checks if every register in \p RegsToVisit is defined by a load
1214 /// instruction + some arithmetic.
1215 ///
1216 /// \param [out] MemOffset2Idx - Maps the byte positions each load ends up
1217 /// at to the index of the load.
1218 /// \param [in] MemSizeInBits - The number of bits each load should produce.
1219 ///
1220 /// \returns On success, a 3-tuple containing lowest-index load found, the
1221 /// lowest index, and the last load in the sequence.
1222 std::optional<std::tuple<GZExtLoad *, int64_t, GZExtLoad *>>
1223 findLoadOffsetsForLoadOrCombine(
1225 const SmallVector<Register, 8> &RegsToVisit,
1226 const unsigned MemSizeInBits) const;
1227
1228 /// Examines the G_PTR_ADD instruction \p PtrAdd and determines if performing
1229 /// a re-association of its operands would break an existing legal addressing
1230 /// mode that the address computation currently represents.
1231 bool reassociationCanBreakAddressingModePattern(MachineInstr &PtrAdd) const;
1232
1233 /// Behavior when a floating point min/max is given one NaN and one
1234 /// non-NaN as input.
1235 enum class SelectPatternNaNBehaviour {
1236 NOT_APPLICABLE = 0, /// NaN behavior not applicable.
1237 RETURNS_NAN, /// Given one NaN input, returns the NaN.
1238 RETURNS_OTHER, /// Given one NaN input, returns the non-NaN.
1239 RETURNS_ANY /// Given one NaN input, can return either (or both operands are
1240 /// known non-NaN.)
1241 };
1242
1243 /// \returns which of \p LHS and \p RHS would be the result of a non-equality
1244 /// floating point comparison where one of \p LHS and \p RHS may be NaN.
1245 ///
1246 /// If both \p LHS and \p RHS may be NaN, returns
1247 /// SelectPatternNaNBehaviour::NOT_APPLICABLE.
1248 SelectPatternNaNBehaviour
1249 computeRetValAgainstNaN(Register LHS, Register RHS,
1250 bool IsOrderedComparison) const;
1251
1252 /// Determines the floating point min/max opcode which should be used for
1253 /// a G_SELECT fed by a G_FCMP with predicate \p Pred.
1254 ///
1255 /// \returns 0 if this G_SELECT should not be combined to a floating point
1256 /// min or max. If it should be combined, returns one of
1257 ///
1258 /// * G_FMAXNUM
1259 /// * G_FMAXIMUM
1260 /// * G_FMINNUM
1261 /// * G_FMINIMUM
1262 ///
1263 /// Helper function for matchFPSelectToMinMax.
1264 unsigned getFPMinMaxOpcForSelect(CmpInst::Predicate Pred, LLT DstTy,
1265 SelectPatternNaNBehaviour VsNaNRetVal) const;
1266
1267 /// Handle floating point cases for matchSimplifySelectToMinMax.
1268 ///
1269 /// E.g.
1270 ///
1271 /// select (fcmp uge x, 1.0) x, 1.0 -> fmax x, 1.0
1272 /// select (fcmp uge x, 1.0) 1.0, x -> fminnm x, 1.0
1273 bool matchFPSelectToMinMax(Register Dst, Register Cond, Register TrueVal,
1274 Register FalseVal, BuildFnTy &MatchInfo) const;
1275
1276 /// Try to fold selects to logical operations.
1277 bool tryFoldBoolSelectToLogic(GSelect *Select, BuildFnTy &MatchInfo) const;
1278
1279 bool tryFoldSelectOfConstants(GSelect *Select, BuildFnTy &MatchInfo) const;
1280
1281 bool isOneOrOneSplat(Register Src, bool AllowUndefs) const;
1282 bool isZeroOrZeroSplat(Register Src, bool AllowUndefs) const;
1283 bool isConstantSplatVector(Register Src, int64_t SplatValue,
1284 bool AllowUndefs) const;
1285 bool isConstantOrConstantVectorI(Register Src) const;
1286
1287 std::optional<APInt> getConstantOrConstantSplatVector(Register Src) const;
1288
1289 /// Fold (icmp Pred1 V1, C1) && (icmp Pred2 V2, C2)
1290 /// or (icmp Pred1 V1, C1) || (icmp Pred2 V2, C2)
1291 /// into a single comparison using range-based reasoning.
1292 bool tryFoldAndOrOrICmpsUsingRanges(GLogicalBinOp *Logic,
1293 BuildFnTy &MatchInfo) const;
1294
1295 // Simplify (cmp cc0 x, y) (&& or ||) (cmp cc1 x, y) -> cmp cc2 x, y.
1296 bool tryFoldLogicOfFCmps(GLogicalBinOp *Logic, BuildFnTy &MatchInfo) const;
1297
1298 bool isCastFree(unsigned Opcode, LLT ToTy, LLT FromTy) const;
1299
1300 bool constantFoldICmp(const GICmp &ICmp, const GIConstant &LHSCst,
1301 const GIConstant &RHSCst, BuildFnTy &MatchInfo) const;
1302 bool constantFoldFCmp(const GFCmp &FCmp, const GFConstant &LHSCst,
1303 const GFConstant &RHSCst, BuildFnTy &MatchInfo) const;
1304};
1305} // namespace llvm
1306
1307#endif
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
AMDGPU Register Bank Select
#define X(NUM, ENUM, NAME)
Definition ELF.h:853
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
This file defines the DenseMap class.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isConstantSplatVector(SDValue N, APInt &SplatValue, unsigned MinSizeInBits)
Implement a low-level type suitable for MachineInstr level instruction selection.
Register Reg
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
LLVM_ABI void applyCombineBuildVectorOfBitcast(MachineInstr &MI, SmallVector< Register > &Ops) const
LLVM_ABI void applyCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo) const
LLVM_ABI bool matchCommuteShift(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchRepeatedFPDivisor(MachineInstr &MI, SmallVector< MachineInstr * > &MatchInfo) const
LLVM_ABI bool matchFoldC2MinusAPlusC1(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchLoadOrCombine(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match expression trees of the form.
LLVM_ABI const RegisterBank * getRegBank(Register Reg) const
Get the register bank of Reg.
LLVM_ABI void applyPtrAddZero(MachineInstr &MI) const
LLVM_ABI bool matchEqualDefs(const MachineOperand &MOP1, const MachineOperand &MOP2) const
Return true if MOP1 and MOP2 are register operands are defined by equivalent instructions.
LLVM_ABI void applyUDivOrURemByConst(MachineInstr &MI) const
LLVM_ABI bool matchConstantFoldBinOp(MachineInstr &MI, APInt &MatchInfo) const
Do constant folding when opportunities are exposed after MIR building.
LLVM_ABI void applyCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) const
LLVM_ABI bool matchUnmergeValuesAnyExtBuildVector(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchCtls(MachineInstr &CtlzMI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchSelectSameVal(MachineInstr &MI) const
Optimize (cond ? x : x) -> x.
LLVM_ABI bool matchAddEToAddO(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match: (G_*ADDE x, y, 0) -> (G_*ADDO x, y) (G_*SUBE x, y, 0) -> (G_*SUBO x, y)
LLVM_ABI bool matchReassocConstantInnerRHS(GPtrAdd &MI, MachineInstr *RHS, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchAVG(MachineInstr &MI, MachineRegisterInfo &MRI, Register X, Register Y, unsigned TargetOpc) const
LLVM_ABI bool matchBitfieldExtractFromShr(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match: shr (shl x, n), k -> sbfx/ubfx x, pos, width.
LLVM_ABI bool matchFoldAMinusC1PlusC2(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchTruncSSatU(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI void applySimplifyURemByPow2(MachineInstr &MI) const
Combine G_UREM x, (known power of 2) to an add and bitmasking.
LLVM_ABI bool matchCombineUnmergeZExtToZExt(MachineInstr &MI) const
Transform X, Y = G_UNMERGE(G_ZEXT(Z)) -> X = G_ZEXT(Z); Y = G_CONSTANT 0.
LLVM_ABI bool matchPtrAddZero(MachineInstr &MI) const
}
const TargetInstrInfo * TII
LLVM_ABI void applyCombineConcatVectors(MachineInstr &MI, SmallVector< Register > &Ops) const
Replace MI with a flattened build_vector with Ops or an implicit_def if Ops is empty.
LLVM_ABI void applyXorOfAndWithSameReg(MachineInstr &MI, std::pair< Register, Register > &MatchInfo) const
LLVM_ABI bool canCombineFMadOrFMA(MachineInstr &MI, bool &AllowFusionGlobally, bool &HasFMAD, bool &Aggressive, bool CanReassociate=false) const
LLVM_ABI bool matchFoldAPlusC1MinusC2(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchExtractVecEltBuildVec(MachineInstr &MI, Register &Reg) const
LLVM_ABI void applyCombineUnmergeConstant(MachineInstr &MI, SmallVectorImpl< APInt > &Csts) const
LLVM_ABI bool matchShiftsTooBig(MachineInstr &MI, std::optional< int64_t > &MatchInfo) const
Match shifts greater or equal to the range (the bitwidth of the result datatype, or the effective bit...
LLVM_ABI bool matchCombineFAddFpExtFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z) (fadd (fpext (fmul x,...
LLVM_ABI bool matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo) const
LLVM_ABI void applyCombineShuffleConcat(MachineInstr &MI, SmallVector< Register > &Ops) const
Replace MI with a flattened build_vector with Ops or an implicit_def if Ops is empty.
LLVM_ABI void replaceSingleDefInstWithReg(MachineInstr &MI, Register Replacement) const
Delete MI and replace all of its uses with Replacement.
LLVM_ABI void applyCombineShuffleToBuildVector(MachineInstr &MI) const
Replace MI with a build_vector.
LLVM_ABI bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine zext of trunc.
LLVM_ABI bool matchCombineExtractedVectorLoad(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine a G_EXTRACT_VECTOR_ELT of a load into a narrowed load.
LLVM_ABI void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const
MachineRegisterInfo::replaceRegWith() and inform the observer of the changes.
LLVM_ABI void replaceRegOpWith(MachineRegisterInfo &MRI, MachineOperand &FromRegOp, Register ToReg) const
Replace a single register operand with a new register and inform the observer of the changes.
LLVM_ABI bool matchReassocCommBinOp(MachineInstr &MI, BuildFnTy &MatchInfo) const
Reassociate commutative binary operations like G_ADD.
LLVM_ABI bool matchExtractVectorElementWithBuildVectorTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine extract vector element with a build vector trunc on the vector register.
LLVM_ABI void applyBuildFnMO(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Use a function which takes in a MachineIRBuilder to perform a combine.
LLVM_ABI bool matchCommuteConstantToRHS(MachineInstr &MI) const
Match constant LHS ops that should be commuted.
LLVM_ABI const DataLayout & getDataLayout() const
LLVM_ABI bool matchBinOpSameVal(MachineInstr &MI) const
Optimize (x op x) -> x.
LLVM_ABI bool matchSimplifyNegMinMax(MachineInstr &MI, BuildFnTy &MatchInfo) const
Tranform (neg (min/max x, (neg x))) into (max/min x, (neg x)).
LLVM_ABI bool matchCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI) const
Try to combine G_[SU]DIV and G_[SU]REM into a single G_[SU]DIVREM when their source operands are iden...
LLVM_ABI bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine zext nneg to sext.
LLVM_ABI void applyUMulHToLShr(MachineInstr &MI) const
LLVM_ABI void applyNotCmp(MachineInstr &MI, SmallVectorImpl< Register > &RegsToNegate) const
LLVM_ABI bool isLegalOrHasFewerElements(const LegalityQuery &Query) const
LLVM_ABI bool matchShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo) const
Fold (shift (shift base, x), y) -> (shift base (x+y))
LLVM_ABI void applyCombineI2PToP2I(MachineInstr &MI, Register &Reg) const
LLVM_ABI bool matchTruncLshrBuildVectorFold(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchAllExplicitUsesAreUndef(MachineInstr &MI) const
Return true if all register explicit use operands on MI are defined by a G_IMPLICIT_DEF.
LLVM_ABI bool isPredecessor(const MachineInstr &DefMI, const MachineInstr &UseMI) const
Returns true if DefMI precedes UseMI or they are the same instruction.
LLVM_ABI bool matchPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo) const
LLVM_ABI bool matchTruncSSatS(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI const TargetLowering & getTargetLowering() const
LLVM_ABI bool matchExtractVectorElementWithDifferentIndices(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine extract vector element with a insert vector element on the vector register and different indi...
LLVM_ABI bool matchShuffleUndefRHS(MachineInstr &MI, BuildFnTy &MatchInfo) const
Remove references to rhs if it is undef.
LLVM_ABI void applyBuildInstructionSteps(MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) const
Replace MI with a series of instructions described in MatchInfo.
LLVM_ABI void applySDivByPow2(MachineInstr &MI) const
LLVM_ABI void applySimplifyAddToSub(MachineInstr &MI, std::tuple< Register, Register > &MatchInfo) const
LLVM_ABI void applyUDivByPow2(MachineInstr &MI) const
Given an G_UDIV MI expressing an unsigned divided by a pow2 constant, return expressions that impleme...
LLVM_ABI bool matchOr(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine ors.
LLVM_ABI bool matchLshrOfTruncOfLshr(MachineInstr &MI, LshrOfTruncOfLshr &MatchInfo, MachineInstr &ShiftMI) const
Fold (lshr (trunc (lshr x, C1)), C2) -> trunc (shift x, (C1 + C2))
LLVM_ABI bool matchInsertVectorElementOOB(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine insert vector element OOB.
LLVM_ABI bool matchSimplifyAddToSub(MachineInstr &MI, std::tuple< Register, Register > &MatchInfo) const
Return true if MI is a G_ADD which can be simplified to a G_SUB.
LLVM_ABI void replaceInstWithConstant(MachineInstr &MI, int64_t C) const
Replace an instruction with a G_CONSTANT with value C.
LLVM_ABI bool tryEmitMemcpyInline(MachineInstr &MI) const
Emit loads and stores that perform the given memcpy.
LLVM_ABI bool matchCombineFSubFpExtFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fsub (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), (fneg z)) (fsub (fpext (fmul x,...
LLVM_ABI void applyFsubToFneg(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchConstantLargerBitWidth(MachineInstr &MI, unsigned ConstIdx) const
Checks if constant at ConstIdx is larger than MI 's bitwidth.
GISelValueTracking * getValueTracking() const
LLVM_ABI void applyCombineCopy(MachineInstr &MI) const
LLVM_ABI bool matchExtractVectorElement(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine extract vector element.
LLVM_ABI bool matchSextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine sext of trunc.
LLVM_ABI bool matchAddSubSameReg(MachineInstr &MI, Register &Src) const
Transform G_ADD(x, G_SUB(y, x)) to y.
LLVM_ABI bool matchCombineShlOfExtend(MachineInstr &MI, RegisterImmPair &MatchData) const
LLVM_ABI bool matchMergeXAndZero(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI void applyCombineAddP2IToPtrAdd(MachineInstr &MI, std::pair< Register, bool > &PtrRegAndCommute) const
LLVM_ABI bool matchCombineFSubFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fsub (fmul x, y), z) -> (fma x, y, -z) (fsub (fmul x, y), z) -> (fmad x,...
LLVM_ABI bool matchCombineFAddFMAFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y, (fma u, v, z)) (fadd (fmad x,...
LLVM_ABI bool matchSextTruncSextLoad(MachineInstr &MI) const
LLVM_ABI bool matchMulOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchCombineMergeUnmerge(MachineInstr &MI, Register &MatchInfo) const
Fold away a merge of an unmerge of the corresponding values.
LLVM_ABI bool matchCombineInsertVecElts(MachineInstr &MI, SmallVectorImpl< Register > &MatchInfo) const
LLVM_ABI bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI, Register &UnmergeSrc) const
LLVM_ABI bool matchDivByPow2(MachineInstr &MI, bool IsSigned) const
Given an G_SDIV MI expressing a signed divided by a pow2 constant, return expressions that implements...
LLVM_ABI bool matchAddOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchNarrowBinopFeedingAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchShlOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchRedundantNegOperands(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fadd x, fneg(y)) -> (fsub x, y) (fadd fneg(x), y) -> (fsub y, x) (fsub x,...
LLVM_ABI bool matchCombineLoadWithAndMask(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match (and (load x), mask) -> zextload x.
LLVM_ABI bool matchCombineFAddFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fadd (fmul x, y), z) -> (fma x, y, z) (fadd (fmul x, y), z) -> (fmad x,...
LLVM_ABI bool matchCombineCopy(MachineInstr &MI) const
LLVM_ABI bool matchExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI) const
LLVM_ABI void applyShiftImmedChain(MachineInstr &MI, RegisterImmPair &MatchInfo) const
LLVM_ABI bool matchXorOfAndWithSameReg(MachineInstr &MI, std::pair< Register, Register > &MatchInfo) const
Fold (xor (and x, y), y) -> (and (not x), y) {.
LLVM_ABI bool matchCombineShuffleVector(MachineInstr &MI, SmallVectorImpl< Register > &Ops) const
Check if the G_SHUFFLE_VECTOR MI can be replaced by a concat_vectors.
LLVM_ABI void applyCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst) const
LLVM_ABI bool matchTruncateOfExt(const MachineInstr &Root, const MachineInstr &ExtMI, BuildFnTy &MatchInfo) const
Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
LLVM_ABI bool matchCombineAddP2IToPtrAdd(MachineInstr &MI, std::pair< Register, bool > &PtrRegAndCommute) const
Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y) Transform G_ADD y,...
LLVM_ABI void replaceInstWithFConstant(MachineInstr &MI, double C) const
Replace an instruction with a G_FCONSTANT with value C.
LLVM_ABI bool matchMergeXAndUndef(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchFunnelShiftToRotate(MachineInstr &MI) const
Match an FSHL or FSHR that can be combined to a ROTR or ROTL rotate.
LLVM_ABI bool matchOrShiftToFunnelShift(MachineInstr &MI, bool AllowScalarConstants, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchRedundantSExtInReg(MachineInstr &MI) const
LLVM_ABI void replaceOpcodeWith(MachineInstr &FromMI, unsigned ToOpcode) const
Replace the opcode in instruction with a new opcode and inform the observer of the changes.
LLVM_ABI void applyFunnelShiftConstantModulo(MachineInstr &MI) const
Replaces the shift amount in MI with ShiftAmt % BW.
LLVM_ABI bool matchFoldC1Minus2MinusC2(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI void applyCombineShlOfExtend(MachineInstr &MI, const RegisterImmPair &MatchData) const
LLVM_ABI void applyUseVectorTruncate(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B, bool IsPreLegalize, GISelValueTracking *VT=nullptr, MachineDominatorTree *MDT=nullptr, const LegalizerInfo *LI=nullptr)
LLVM_ABI bool matchShuffleDisjointMask(MachineInstr &MI, BuildFnTy &MatchInfo) const
Turn shuffle a, b, mask -> shuffle undef, b, mask iff mask does not reference a.
LLVM_ABI bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal) const
Transform a multiply by a power-of-2 value to a left shift.
LLVM_ABI void applyCombineShuffleVector(MachineInstr &MI, ArrayRef< Register > Ops) const
Replace MI with a concat_vectors with Ops.
LLVM_ABI bool matchCombineConstPtrAddToI2P(MachineInstr &MI, APInt &NewCst) const
LLVM_ABI bool matchCombineUnmergeUndef(MachineInstr &MI, std::function< void(MachineIRBuilder &)> &MatchInfo) const
Transform G_UNMERGE G_IMPLICIT_DEF -> G_IMPLICIT_DEF, G_IMPLICIT_DEF, ...
LLVM_ABI void applyFoldBinOpIntoSelect(MachineInstr &MI, const unsigned &SelectOpNo) const
SelectOperand is the operand in binary operator MI that is the select to fold.
LLVM_ABI bool matchFoldAMinusC1MinusC2(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI void applyCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo) const
LLVM_ABI bool matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match: (G_UMULO x, 2) -> (G_UADDO x, x) (G_SMULO x, 2) -> (G_SADDO x, x)
LLVM_ABI bool tryCombine(MachineInstr &MI) const
Try to transform MI by using all of the above combine functions.
LLVM_ABI bool matchCombineShuffleConcat(MachineInstr &MI, SmallVector< Register > &Ops) const
LLVM_ABI void applySextInRegOfLoad(MachineInstr &MI, std::tuple< Register, unsigned > &MatchInfo) const
LLVM_ABI bool tryCombineCopy(MachineInstr &MI) const
If MI is COPY, try to combine it.
LLVM_ABI bool matchTruncUSatU(MachineInstr &MI, MachineInstr &MinMI) const
const RegisterBankInfo & getRBI() const
LLVM_ABI bool matchICmpToLHSKnownBits(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchExtOfExt(const MachineInstr &FirstMI, const MachineInstr &SecondMI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchReassocPtrAdd(MachineInstr &MI, BuildFnTy &MatchInfo) const
Reassociate pointer calculations with G_ADD involved, to allow better addressing mode usage.
LLVM_ABI bool matchCanonicalizeFCmp(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool isPreLegalize() const
LLVM_ABI bool matchUndefShuffleVectorMask(MachineInstr &MI) const
Return true if a G_SHUFFLE_VECTOR instruction MI has an undef mask.
LLVM_ABI bool matchAnyExplicitUseIsUndef(MachineInstr &MI) const
Return true if any explicit use operand on MI is defined by a G_IMPLICIT_DEF.
LLVM_ABI bool matchCombineI2PToP2I(MachineInstr &MI, Register &Reg) const
Transform IntToPtr(PtrToInt(x)) to x if cast is in the same address space.
LLVM_ABI bool matchCombineSubToAdd(MachineInstr &MI, BuildFnTy &MatchInfo) const
const TargetRegisterInfo & getTRI() const
LLVM_ABI bool matchShiftOfShiftedLogic(MachineInstr &MI, ShiftOfShiftedLogic &MatchInfo) const
If we have a shift-by-constant of a bitwise logic op that itself has a shift-by-constant operand with...
LLVM_ABI bool matchCombineConcatVectors(MachineInstr &MI, SmallVector< Register > &Ops) const
If MI is G_CONCAT_VECTORS, try to combine it.
LLVM_ABI bool tryCombineShuffleVector(MachineInstr &MI) const
Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
LLVM_ABI bool matchInsertExtractVecEltOutOfBounds(MachineInstr &MI) const
Return true if a G_{EXTRACT,INSERT}_VECTOR_ELT has an out of range index.
LLVM_ABI bool matchExtractVectorElementWithShuffleVector(const MachineInstr &MI, const MachineInstr &MI2, BuildFnTy &MatchInfo) const
Combine extract vector element with a shuffle vector on the vector register.
LLVM_ABI bool matchExtractAllEltsFromBuildVector(MachineInstr &MI, SmallVectorImpl< std::pair< Register, MachineInstr * > > &MatchInfo) const
LLVM_ABI LLVMContext & getContext() const
LLVM_ABI void applyPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo) const
LLVM_ABI bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const
LLVM_ABI bool matchNotCmp(MachineInstr &MI, SmallVectorImpl< Register > &RegsToNegate) const
Combine inverting a result of a compare into the opposite cond code.
LLVM_ABI bool matchSextInRegOfLoad(MachineInstr &MI, std::tuple< Register, unsigned > &MatchInfo) const
Match sext_inreg(load p), imm -> sextload p.
LLVM_ABI bool matchSelectIMinMax(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine select to integer min/max.
LLVM_ABI bool matchConstantFoldUnaryIntOp(MachineInstr &MI, BuildFnTy &MatchInfo) const
Constant fold a unary integer op (G_CTLZ, G_CTTZ, G_CTPOP and their _ZERO_POISON variants,...
LLVM_ABI void applyCombineConstantFoldFpUnary(MachineInstr &MI, const ConstantFP *Cst) const
Transform fp_instr(cst) to constant result of the fp operation.
LLVM_ABI bool isLegal(const LegalityQuery &Query) const
LLVM_ABI bool matchICmpToTrueFalseKnownBits(MachineInstr &MI, int64_t &MatchInfo) const
LLVM_ABI bool matchOperandIsKnownToBeAPowerOfTwo(const MachineOperand &MO, bool OrNegative=false) const
Check if operand MO is known to be a power of 2.
LLVM_ABI bool tryReassocBinOp(unsigned Opc, Register DstReg, Register Op0, Register Op1, BuildFnTy &MatchInfo) const
Try to reassociate to reassociate operands of a commutative binop.
LLVM_ABI void eraseInst(MachineInstr &MI) const
Erase MI.
LLVM_ABI bool matchConstantFoldFPBinOp(MachineInstr &MI, ConstantFP *&MatchInfo) const
Do constant FP folding when opportunities are exposed after MIR building.
LLVM_ABI void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo) const
Use a function which takes in a MachineIRBuilder to perform a combine.
LLVM_ABI bool matchUseVectorTruncate(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchUndefStore(MachineInstr &MI) const
Return true if a G_STORE instruction MI is storing an undef value.
MachineRegisterInfo & MRI
LLVM_ABI void applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) const
Transform PtrToInt(IntToPtr(x)) to x.
LLVM_ABI void applyExtendThroughPhis(MachineInstr &MI, MachineInstr *&ExtMI) const
LLVM_ABI bool matchConstantFPOp(const MachineOperand &MOP, double C) const
Return true if MOP is defined by a G_FCONSTANT or splat with a value exactly equal to C.
LLVM_ABI MachineInstr * buildUDivOrURemUsingMul(MachineInstr &MI) const
Given an G_UDIV MI or G_UREM MI expressing a divide by constant, return an expression that implements...
LLVM_ABI void applyExtractVecEltBuildVec(MachineInstr &MI, Register &Reg) const
LLVM_ABI bool matchFoldBinOpIntoSelect(MachineInstr &MI, unsigned &SelectOpNo) const
Push a binary operator through a select on constants.
LLVM_ABI bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount) const
LLVM_ABI bool tryCombineExtendingLoads(MachineInstr &MI) const
If MI is extend that consumes the result of a load, try to combine it.
LLVM_ABI bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const
LLVM_ABI bool matchBuildVectorIdentityFold(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchBitfieldExtractFromShrAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match: shr (and x, n), k -> ubfx x, pos, width.
LLVM_ABI void applyTruncSSatS(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchConstantFoldCastOp(MachineInstr &MI, APInt &MatchInfo) const
Do constant folding when opportunities are exposed after MIR building.
LLVM_ABI void applyRotateOutOfRange(MachineInstr &MI) const
LLVM_ABI bool matchReassocFoldConstantsInSubTree(GPtrAdd &MI, MachineInstr *LHS, MachineInstr *RHS, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchHoistLogicOpWithSameOpcodeHands(MachineInstr &MI, InstructionStepsMatchInfo &MatchInfo) const
Match (logic_op (op x...), (op y...)) -> (op (logic_op x, y))
LLVM_ABI bool matchBitfieldExtractFromAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match: and (lshr x, cst), mask -> ubfx x, cst, width.
LLVM_ABI bool matchBitfieldExtractFromSExtInReg(MachineInstr &MI, BuildFnTy &MatchInfo) const
Form a G_SBFX from a G_SEXT_INREG fed by a right shift.
LLVM_ABI bool matchNarrowBinop(const MachineInstr &TruncMI, const MachineInstr &BinopMI, BuildFnTy &MatchInfo) const
trunc (binop X, C) --> binop (trunc X, trunc C).
LLVM_ABI bool matchUndefSelectCmp(MachineInstr &MI) const
Return true if a G_SELECT instruction MI has an undef comparison.
LLVM_ABI bool matchAndOrDisjointMask(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI void replaceInstWithUndef(MachineInstr &MI) const
Replace an instruction with a G_IMPLICIT_DEF.
LLVM_ABI bool matchRedundantBinOpInEquality(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform: (X + Y) == X -> Y == 0 (X - Y) == X -> Y == 0 (X ^ Y) == X -> Y == 0 (X + Y) !...
LLVM_ABI bool matchOptBrCondByInvertingCond(MachineInstr &MI, MachineInstr *&BrCond) const
If a brcond's true block is not the fallthrough, make it so by inverting the condition and swapping o...
LLVM_ABI bool matchAddOverflow(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine addos.
LLVM_ABI void applyAshShlToSextInreg(MachineInstr &MI, std::tuple< Register, int64_t > &MatchInfo) const
LLVM_ABI bool matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine selects.
LLVM_ABI bool matchCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo) const
LLVM_ABI bool matchCombineUnmergeWithDeadLanesToTrunc(MachineInstr &MI) const
Transform X, Y<dead> = G_UNMERGE Z -> X = G_TRUNC Z.
LLVM_ABI bool matchFsubToFneg(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchRotateOutOfRange(MachineInstr &MI) const
LLVM_ABI void applyExpandFPowI(MachineInstr &MI, int64_t Exponent) const
Expands FPOWI into a series of multiplications and a division if the exponent is negative.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank *RegBank) const
Set the register bank of Reg.
LLVM_ABI bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) const
Return true if a G_SELECT instruction MI has a constant comparison.
LLVM_ABI bool matchCommuteFPConstantToRHS(MachineInstr &MI) const
Match constant LHS FP ops that should be commuted.
LLVM_ABI void applyCombineDivRem(MachineInstr &MI, MachineInstr *&OtherMI) const
const TargetInstrInfo & getTII() const
LLVM_ABI bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info) const
LLVM_ABI bool matchRedundantOr(MachineInstr &MI, Register &Replacement) const
LLVM_ABI void applyTruncSSatU(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI void applySimplifySRemByPow2(MachineInstr &MI) const
Combine G_SREM x, (+/-2^k) to a bias-and-mask sequence.
LLVM_ABI bool matchCombineFSubFpExtFNegFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fsub (fpext (fneg (fmul x, y))), z) -> (fneg (fma (fpext x), (fpext y),...
LLVM_ABI bool matchTruncBuildVectorFold(MachineInstr &MI, Register &MatchInfo) const
LLVM_ABI bool matchSubOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo) const
LLVM_ABI void applyCombineTruncOfShift(MachineInstr &MI, std::pair< MachineInstr *, LLT > &MatchInfo) const
LLVM_ABI bool matchConstantOp(const MachineOperand &MOP, int64_t C) const
Return true if MOP is defined by a G_CONSTANT or splat with a value equal to C.
const LegalizerInfo * LI
LLVM_ABI void applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal) const
LLVM_ABI void applyCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B, Register &UnmergeSrc) const
LLVM_ABI bool matchUMulHToLShr(MachineInstr &MI) const
MachineDominatorTree * MDT
MachineIRBuilder & getBuilder() const
LLVM_ABI void applyFunnelShiftToRotate(MachineInstr &MI) const
LLVM_ABI bool matchSimplifySelectToMinMax(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI void applyRepeatedFPDivisor(SmallVector< MachineInstr * > &MatchInfo) const
LLVM_ABI bool matchTruncUSatUToFPTOUISat(MachineInstr &MI, MachineInstr &SrcMI) const
const RegisterBankInfo * RBI
LLVM_ABI bool matchMulOBy0(MachineInstr &MI, BuildFnTy &MatchInfo) const
Match: (G_*MULO x, 0) -> 0 + no carry out.
GISelValueTracking * VT
LLVM_ABI bool matchBinopWithNeg(MachineInstr &MI, BuildFnTy &MatchInfo) const
Fold a bitwiseop (~b +/- c) -> a bitwiseop ~(b -/+ c)
LLVM_ABI bool matchCombineUnmergeConstant(MachineInstr &MI, SmallVectorImpl< APInt > &Csts) const
Transform G_UNMERGE Constant -> Constant1, Constant2, ...
LLVM_ABI void applyShiftOfShiftedLogic(MachineInstr &MI, ShiftOfShiftedLogic &MatchInfo) const
const TargetRegisterInfo * TRI
LLVM_ABI bool matchRedundantAnd(MachineInstr &MI, Register &Replacement) const
LLVM_ABI bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI) const
Returns true if DefMI dominates UseMI.
GISelChangeObserver & Observer
LLVM_ABI void applyBuildFn(MachineInstr &MI, BuildFnTy &MatchInfo) const
Use a function which takes in a MachineIRBuilder to perform a combine.
LLVM_ABI bool matchCombineTruncOfShift(MachineInstr &MI, std::pair< MachineInstr *, LLT > &MatchInfo) const
Transform trunc (shl x, K) to shl (trunc x), K if K < VT.getScalarSizeInBits().
LLVM_ABI bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize, unsigned &ShiftVal) const
Reduce a shift by a constant to an unmerge and a shift on a half sized type.
LLVM_ABI bool matchUDivOrURemByConst(MachineInstr &MI) const
Combine G_UDIV or G_UREM by constant into a multiply by magic constant.
LLVM_ABI bool matchAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const
Combine ands.
LLVM_ABI bool matchSuboCarryOut(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchRedundantSextInReg(MachineInstr &Root, MachineInstr &Other, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchConstantFoldFMA(MachineInstr &MI, ConstantFP *&MatchInfo) const
Constant fold G_FMA/G_FMAD.
LLVM_ABI bool matchCombineFSubFNegFMulToFMadOrFMA(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform (fsub (fneg (fmul, x, y)), z) -> (fma (fneg x), y, (fneg z)) (fsub (fneg (fmul,...
LLVM_ABI bool matchCombineZextTrunc(MachineInstr &MI, Register &Reg) const
Transform zext(trunc(x)) to x.
LLVM_ABI bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) const
Check if operand OpIdx is undef.
LLVM_ABI void applyLshrOfTruncOfLshr(MachineInstr &MI, LshrOfTruncOfLshr &MatchInfo) const
LLVM_ABI bool tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen=0) const
Optimize memcpy intrinsics et al, e.g.
LLVM_ABI bool matchFreezeOfSingleMaybePoisonOperand(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI void applySDivOrSRemByConst(MachineInstr &MI) const
LLVM_ABI MachineInstr * buildSDivOrSRemUsingMul(MachineInstr &MI) const
Given an G_SDIV MI or G_SREM MI expressing a signed divide by constant, return an expression that imp...
LLVM_ABI bool isLegalOrHasWidenScalar(const LegalityQuery &Query) const
LLVM_ABI bool matchCanonicalizeICmp(const MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchCastOfBuildVector(const MachineInstr &CastMI, const MachineInstr &BVMI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchSubAddSameReg(MachineInstr &MI, BuildFnTy &MatchInfo) const
Transform: (x + y) - y -> x (x + y) - x -> y x - (y + x) -> 0 - y x - (x + z) -> 0 - z.
LLVM_ABI bool matchReassocConstantInnerLHS(GPtrAdd &MI, MachineInstr *LHS, MachineInstr *RHS, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchCastOfInteger(const MachineInstr &CastMI, APInt &MatchInfo) const
LLVM_ABI bool matchOverlappingAnd(MachineInstr &MI, BuildFnTy &MatchInfo) const
Fold and(and(x, C1), C2) -> C1&C2 ? and(x, C1&C2) : 0.
LLVM_ABI bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) const
Transform anyext(trunc(x)) to x.
LLVM_ABI void applyExtractAllEltsFromBuildVector(MachineInstr &MI, SmallVectorImpl< std::pair< Register, MachineInstr * > > &MatchInfo) const
MachineIRBuilder & Builder
LLVM_ABI void applyCommuteBinOpOperands(MachineInstr &MI) const
LLVM_ABI void replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx) const
Delete MI and replace all of its uses with its OpIdx-th operand.
LLVM_ABI void applySextTruncSextLoad(MachineInstr &MI) const
LLVM_ABI const MachineFunction & getMachineFunction() const
LLVM_ABI bool matchCombineBuildVectorOfBitcast(MachineInstr &MI, SmallVector< Register > &Ops) const
Combine G_BUILD_VECTOR(G_UNMERGE(G_BITCAST), Undef) to G_BITCAST(G_BUILD_VECTOR(.....
LLVM_ABI bool matchCombineFAddFpExtFMulToFMadOrFMAAggressive(MachineInstr &MI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchExtractVectorElementWithBuildVector(const MachineInstr &MI, const MachineInstr &MI2, BuildFnTy &MatchInfo) const
Combine extract vector element with a build vector on the vector register.
LLVM_ABI bool matchSDivOrSRemByConst(MachineInstr &MI) const
Combine G_SDIV or G_SREM by constant into a multiply by magic constant.
LLVM_ABI void applyOptBrCondByInvertingCond(MachineInstr &MI, MachineInstr *&BrCond) const
LLVM_ABI void applyCombineShiftToUnmerge(MachineInstr &MI, const unsigned &ShiftVal) const
LLVM_ABI bool matchCastOfSelect(const MachineInstr &Cast, const MachineInstr &SelectMI, BuildFnTy &MatchInfo) const
LLVM_ABI bool matchFPowIExpansion(MachineInstr &MI, int64_t Exponent) const
Match FPOWI if it's safe to extend it into a series of multiplications.
LLVM_ABI void applyCombineInsertVecElts(MachineInstr &MI, SmallVectorImpl< Register > &MatchInfo) const
LLVM_ABI bool matchCombineUnmergeMergeToPlainValues(MachineInstr &MI, SmallVectorImpl< Register > &Operands) const
Transform <ty,...> G_UNMERGE(G_MERGE ty X, Y, Z) -> ty X, Y, Z.
LLVM_ABI void applyCombineUnmergeMergeToPlainValues(MachineInstr &MI, SmallVectorImpl< Register > &Operands) const
LLVM_ABI bool matchAshrShlToSextInreg(MachineInstr &MI, std::tuple< Register, int64_t > &MatchInfo) const
Match ashr (shl x, C), C -> sext_inreg (C)
LLVM_ABI void applyCombineUnmergeZExtToZExt(MachineInstr &MI) const
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Represent a G_FCMP.
An floating-point-like constant.
Definition Utils.h:679
Represent a G_ICMP.
An integer-like constant.
Definition Utils.h:640
Abstract class that contains various methods for clients to notify about changes.
Represents any type of generic load or store.
Represents a logical binary operation.
Represents a G_PTR_ADD.
Represents a G_SELECT.
Represents a G_ZEXTLOAD.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Helper class to build MachineInstr.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Holds all the information related to register banks.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
std::function< void(MachineIRBuilder &)> BuildFnTy
SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > OperandBuildSteps
LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
@ Other
Any other memory.
Definition ModRef.h:68
LLVM_ABI bool isZeroOrZeroSplat(SDValue N, bool AllowUndefs=false)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
InstructionBuildSteps(unsigned Opcode, const OperandBuildSteps &OperandFns)
InstructionBuildSteps()=default
Operands to be added to the instruction.
OperandBuildSteps OperandFns
The opcode for the produced instruction.
InstructionStepsMatchInfo(std::initializer_list< InstructionBuildSteps > InstrsToBuild)
SmallVector< InstructionBuildSteps, 2 > InstrsToBuild
Describes instructions to be built during a combine.
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
const RegisterBank * Bank