LLVM 24.0.0git
AMDGPUPostLegalizerCombiner.cpp
Go to the documentation of this file.
1//=== lib/CodeGen/GlobalISel/AMDGPUPostLegalizerCombiner.cpp --------------===//
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//
9// This pass does combining of machine instructions at the generic MI level,
10// after the legalizer.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPU.h"
16#include "AMDGPULegalizerInfo.h"
17#include "GCNSubtarget.h"
26#include "llvm/IR/IntrinsicsAMDGPU.h"
28
29#define GET_GICOMBINER_DEPS
30#include "AMDGPUGenPreLegalizeGICombiner.inc"
31#undef GET_GICOMBINER_DEPS
32
33#define DEBUG_TYPE "amdgpu-postlegalizer-combiner"
34
35using namespace llvm;
36using namespace MIPatternMatch;
37
38namespace {
39#define GET_GICOMBINER_TYPES
40#include "AMDGPUGenPostLegalizeGICombiner.inc"
41#undef GET_GICOMBINER_TYPES
42
43class AMDGPUPostLegalizerCombinerImpl : public Combiner {
44protected:
45 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig;
46 const GCNSubtarget &STI;
47 const SIInstrInfo &TII;
48 // TODO: Make CombinerHelper methods const.
49 mutable AMDGPUCombinerHelper Helper;
50
51public:
52 AMDGPUPostLegalizerCombinerImpl(
54 GISelCSEInfo *CSEInfo,
55 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
56 const GCNSubtarget &STI, MachineDominatorTree *MDT,
57 const LegalizerInfo *LI);
58
59 static const char *getName() { return "AMDGPUPostLegalizerCombinerImpl"; }
60
61 bool tryCombineAllImpl(MachineInstr &I) const;
62 bool tryCombineAll(MachineInstr &I) const override;
63
64 struct FMinFMaxLegacyInfo {
68 };
69
70 // TODO: Make sure fmin_legacy/fmax_legacy don't canonicalize
71 bool matchFMinFMaxLegacy(MachineInstr &MI, MachineInstr &FCmp,
72 FMinFMaxLegacyInfo &Info) const;
73 void applySelectFCmpToFMinFMaxLegacy(MachineInstr &MI,
74 const FMinFMaxLegacyInfo &Info) const;
75
76 bool matchUCharToFloat(MachineInstr &MI) const;
77 void applyUCharToFloat(MachineInstr &MI) const;
78
79 bool matchFDivSqrtToRsqF16(MachineInstr &MI) const;
80 void applyFDivSqrtToRsqF16(MachineInstr &MI, const Register &X) const;
81
82 // FIXME: Should be able to have 2 separate matchdatas rather than custom
83 // struct boilerplate.
84 struct CvtF32UByteMatchInfo {
85 Register CvtVal;
86 unsigned ShiftOffset;
87 };
88
89 bool matchCvtF32UByteN(MachineInstr &MI,
90 CvtF32UByteMatchInfo &MatchInfo) const;
91 void applyCvtF32UByteN(MachineInstr &MI,
92 const CvtF32UByteMatchInfo &MatchInfo) const;
93
94 bool matchRemoveFcanonicalize(MachineInstr &MI) const;
95
96 // Combine unsigned buffer load and signed extension instructions to generate
97 // signed buffer load instructions.
98 bool matchCombineSignExtendInReg(
99 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchInfo) const;
100 void applyCombineSignExtendInReg(
101 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchInfo) const;
102
103 // Find the s_mul_u64 instructions where the higher bits are either
104 // zero-extended or sign-extended.
105 // Replace the s_mul_u64 instructions with S_MUL_I64_I32_PSEUDO if the higher
106 // 33 bits are sign extended and with S_MUL_U64_U32_PSEUDO if the higher 32
107 // bits are zero extended.
108 bool matchCombine_s_mul_u64(MachineInstr &MI, unsigned &NewOpcode) const;
109
110private:
111#define GET_GICOMBINER_CLASS_MEMBERS
112#define AMDGPUSubtarget GCNSubtarget
113#include "AMDGPUGenPostLegalizeGICombiner.inc"
114#undef GET_GICOMBINER_CLASS_MEMBERS
115#undef AMDGPUSubtarget
116};
117
118#define GET_GICOMBINER_IMPL
119#define AMDGPUSubtarget GCNSubtarget
120#include "AMDGPUGenPostLegalizeGICombiner.inc"
121#undef AMDGPUSubtarget
122#undef GET_GICOMBINER_IMPL
123
124AMDGPUPostLegalizerCombinerImpl::AMDGPUPostLegalizerCombinerImpl(
126 GISelCSEInfo *CSEInfo,
127 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
128 const GCNSubtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
129 : Combiner(MF, CInfo, &VT, CSEInfo), RuleConfig(RuleConfig), STI(STI),
130 TII(*STI.getInstrInfo()),
131 Helper(Observer, B, /*IsPreLegalize*/ false, &VT, MDT, LI, STI),
133#include "AMDGPUGenPostLegalizeGICombiner.inc"
135{
136}
137
138bool AMDGPUPostLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
139 if (tryCombineAllImpl(MI))
140 return true;
141
142 switch (MI.getOpcode()) {
143 case TargetOpcode::G_SHL:
144 case TargetOpcode::G_LSHR:
145 case TargetOpcode::G_ASHR:
146 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
147 // common case, splitting this into a move and a 32-bit shift is faster and
148 // the same code size.
149 return Helper.tryCombineShiftToUnmerge(MI, 32);
150 }
151
152 return false;
153}
154
155bool AMDGPUPostLegalizerCombinerImpl::matchFMinFMaxLegacy(
156 MachineInstr &MI, MachineInstr &FCmp, FMinFMaxLegacyInfo &Info) const {
157 if (!MRI.hasOneNonDBGUse(FCmp.getOperand(0).getReg()))
158 return false;
159
160 Info.Pred =
161 static_cast<CmpInst::Predicate>(FCmp.getOperand(1).getPredicate());
162 Info.LHS = FCmp.getOperand(2).getReg();
163 Info.RHS = FCmp.getOperand(3).getReg();
164 Register True = MI.getOperand(2).getReg();
165 Register False = MI.getOperand(3).getReg();
166
167 // TODO: Handle case where the the selected value is an fneg and the compared
168 // constant is the negation of the selected value.
169 if ((Info.LHS != True || Info.RHS != False) &&
170 (Info.LHS != False || Info.RHS != True))
171 return false;
172
173 // Invert the predicate if necessary so that the apply function can assume
174 // that the select operands are the same as the fcmp operands.
175 // (select (fcmp P, L, R), R, L) -> (select (fcmp !P, L, R), L, R)
176 if (Info.LHS != True)
178
179 // Only match </<=/>=/> not ==/!= etc.
180 if (Info.Pred == CmpInst::getSwappedPredicate(Info.Pred))
181 return false;
182
183 // These predicates pick the signed zero tie-incorrect operand order.
184 if (Info.Pred == CmpInst::FCMP_OLE || Info.Pred == CmpInst::FCMP_ULT ||
185 Info.Pred == CmpInst::FCMP_OGT || Info.Pred == CmpInst::FCMP_UGE)
186 return Helper.canIgnoreLegacyMinMaxTies(MI, Info.LHS, Info.RHS);
187
188 return true;
189}
190
191void AMDGPUPostLegalizerCombinerImpl::applySelectFCmpToFMinFMaxLegacy(
192 MachineInstr &MI, const FMinFMaxLegacyInfo &Info) const {
193 unsigned Opc = (Info.Pred & CmpInst::FCMP_OGT) ? AMDGPU::G_AMDGPU_FMAX_LEGACY
194 : AMDGPU::G_AMDGPU_FMIN_LEGACY;
195 Register X = Info.LHS;
196 Register Y = Info.RHS;
197 if (Info.Pred == CmpInst::getUnorderedPredicate(Info.Pred)) {
198 // We need to permute the operands to get the correct NaN behavior. The
199 // selected operand is the second one based on the failing compare with NaN,
200 // so permute it based on the compare type the hardware uses.
201 std::swap(X, Y);
202 }
203
204 B.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags());
205
206 MI.eraseFromParent();
207}
208
209bool AMDGPUPostLegalizerCombinerImpl::matchUCharToFloat(
210 MachineInstr &MI) const {
211 Register DstReg = MI.getOperand(0).getReg();
212
213 // TODO: We could try to match extracting the higher bytes, which would be
214 // easier if i8 vectors weren't promoted to i32 vectors, particularly after
215 // types are legalized. v4i8 -> v4f32 is probably the only case to worry
216 // about in practice.
217 LLT Ty = MRI.getType(DstReg);
218 if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) {
219 Register SrcReg = MI.getOperand(1).getReg();
220 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits();
221 assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64);
222 const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8);
223 return Helper.getValueTracking()->maskedValueIsZero(SrcReg, Mask);
224 }
225
226 return false;
227}
228
229void AMDGPUPostLegalizerCombinerImpl::applyUCharToFloat(
230 MachineInstr &MI) const {
231 const LLT S32 = LLT::scalar(32);
232
233 Register DstReg = MI.getOperand(0).getReg();
234 Register SrcReg = MI.getOperand(1).getReg();
235 LLT Ty = MRI.getType(DstReg);
236 LLT SrcTy = MRI.getType(SrcReg);
237 if (SrcTy != S32)
238 SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0);
239
240 if (Ty == S32) {
241 B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, {SrcReg},
242 MI.getFlags());
243 } else {
244 auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, {SrcReg},
245 MI.getFlags());
246 B.buildFPTrunc(DstReg, Cvt0, MI.getFlags());
247 }
248
249 MI.eraseFromParent();
250}
251
252bool AMDGPUPostLegalizerCombinerImpl::matchFDivSqrtToRsqF16(
253 MachineInstr &MI) const {
254 Register Sqrt = MI.getOperand(2).getReg();
255 return MRI.hasOneNonDBGUse(Sqrt);
256}
257
258void AMDGPUPostLegalizerCombinerImpl::applyFDivSqrtToRsqF16(
259 MachineInstr &MI, const Register &X) const {
260 Register Dst = MI.getOperand(0).getReg();
261 Register Y = MI.getOperand(1).getReg();
262 LLT DstTy = MRI.getType(Dst);
263 uint32_t Flags = MI.getFlags();
264 Register RSQ = B.buildIntrinsic(Intrinsic::amdgcn_rsq, {DstTy})
265 .addUse(X)
266 .setMIFlags(Flags)
267 .getReg(0);
268 B.buildFMul(Dst, RSQ, Y, Flags);
269 MI.eraseFromParent();
270}
271
272bool AMDGPUPostLegalizerCombinerImpl::matchCvtF32UByteN(
273 MachineInstr &MI, CvtF32UByteMatchInfo &MatchInfo) const {
274 Register SrcReg = MI.getOperand(1).getReg();
275
276 // Look through G_ZEXT.
277 bool IsShr = mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg)));
278
279 Register Src0;
280 int64_t ShiftAmt;
281 IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt)));
282 if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) {
283 const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0;
284
285 unsigned ShiftOffset = 8 * Offset;
286 if (IsShr)
287 ShiftOffset += ShiftAmt;
288 else
289 ShiftOffset -= ShiftAmt;
290
291 MatchInfo.CvtVal = Src0;
292 MatchInfo.ShiftOffset = ShiftOffset;
293 return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0;
294 }
295
296 // TODO: Simplify demanded bits.
297 return false;
298}
299
300void AMDGPUPostLegalizerCombinerImpl::applyCvtF32UByteN(
301 MachineInstr &MI, const CvtF32UByteMatchInfo &MatchInfo) const {
302 unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8;
303
304 const LLT S32 = LLT::scalar(32);
305 Register CvtSrc = MatchInfo.CvtVal;
306 LLT SrcTy = MRI.getType(MatchInfo.CvtVal);
307 if (SrcTy != S32) {
308 assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8);
309 CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0);
310 }
311
312 assert(MI.getOpcode() != NewOpc);
313 B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags());
314 MI.eraseFromParent();
315}
316
317bool AMDGPUPostLegalizerCombinerImpl::matchRemoveFcanonicalize(
318 MachineInstr &MI) const {
319 const SITargetLowering *TLI = static_cast<const SITargetLowering *>(
320 MF.getSubtarget().getTargetLowering());
321 return TLI->isCanonicalized(MI.getOperand(1).getReg(), MF);
322}
323
324// The buffer_load_{i8, i16} intrinsics are initially lowered as
325// buffer_load_{u8, u16} instructions. Here, the buffer_load_{u8, u16}
326// instructions are combined with sign extension instrucions in order to
327// generate buffer_load_{i8, i16} instructions.
328
329// Identify buffer_load_{u8, u16}.
330bool AMDGPUPostLegalizerCombinerImpl::matchCombineSignExtendInReg(
331 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
332 Register LoadReg = MI.getOperand(1).getReg();
333 if (!MRI.hasOneNonDBGUse(LoadReg))
334 return false;
335
336 // Check if the first operand of the sign extension is a subword buffer load
337 // instruction.
338 MachineInstr *LoadMI = MRI.getVRegDef(LoadReg);
339 int64_t Width = MI.getOperand(2).getImm();
340 switch (LoadMI->getOpcode()) {
341 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
342 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE};
343 return Width == 8;
344 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
345 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT};
346 return Width == 16;
347 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_UBYTE:
348 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SBYTE};
349 return Width == 8;
350 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_USHORT:
351 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SSHORT};
352 return Width == 16;
353 }
354 return false;
355}
356
357// Combine buffer_load_{u8, u16} and the sign extension instruction to generate
358// buffer_load_{i8, i16}.
359void AMDGPUPostLegalizerCombinerImpl::applyCombineSignExtendInReg(
360 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
361 auto [LoadMI, NewOpcode] = MatchData;
362 LoadMI->setDesc(TII.get(NewOpcode));
363 // Update the destination register of the load with the destination register
364 // of the sign extension.
365 Register SignExtendInsnDst = MI.getOperand(0).getReg();
366 LoadMI->getOperand(0).setReg(SignExtendInsnDst);
367 // Remove the sign extension.
368 MI.eraseFromParent();
369}
370
371bool AMDGPUPostLegalizerCombinerImpl::matchCombine_s_mul_u64(
372 MachineInstr &MI, unsigned &NewOpcode) const {
373 Register Src0 = MI.getOperand(1).getReg();
374 Register Src1 = MI.getOperand(2).getReg();
375 if (MRI.getType(Src0) != LLT::scalar(64))
376 return false;
377
378 if (VT->getKnownBits(Src1).countMinLeadingZeros() >= 32 &&
379 VT->getKnownBits(Src0).countMinLeadingZeros() >= 32) {
380 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_U64_U32;
381 return true;
382 }
383
384 if (VT->computeNumSignBits(Src1) >= 33 &&
385 VT->computeNumSignBits(Src0) >= 33) {
386 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_I64_I32;
387 return true;
388 }
389 return false;
390}
391
392// Pass boilerplate
393// ================
394
395class AMDGPUPostLegalizerCombiner : public MachineFunctionPass {
396public:
397 static char ID;
398
399 AMDGPUPostLegalizerCombiner(bool IsOptNone = false);
400
401 StringRef getPassName() const override {
402 return "AMDGPUPostLegalizerCombiner";
403 }
404
405 bool runOnMachineFunction(MachineFunction &MF) override;
406
407 void getAnalysisUsage(AnalysisUsage &AU) const override;
408
409private:
410 bool IsOptNone;
411 AMDGPUPostLegalizerCombinerImplRuleConfig RuleConfig;
412};
413} // end anonymous namespace
414
415void AMDGPUPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
416 AU.setPreservesCFG();
418 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
419 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
420 if (!IsOptNone) {
421 AU.addRequired<MachineDominatorTreeWrapperPass>();
422 }
424}
425
426AMDGPUPostLegalizerCombiner::AMDGPUPostLegalizerCombiner(bool IsOptNone)
427 : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
428 if (!RuleConfig.parseCommandLineOption())
429 report_fatal_error("Invalid rule identifier");
430}
431
432bool AMDGPUPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
433 if (MF.getProperties().hasFailedISel())
434 return false;
435 const Function &F = MF.getFunction();
436 bool EnableOpt =
437 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
438
440 const AMDGPULegalizerInfo *LI =
441 static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo());
442
444 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
446 IsOptNone ? nullptr
447 : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
448
449 CombinerInfo CInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true,
450 LI, EnableOpt, F.hasOptSize(), F.hasMinSize());
451 // Disable fixed-point iteration to reduce compile-time
452 CInfo.MaxIterations = 1;
453 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
454 // Legalizer performs DCE, so a full DCE pass is unnecessary.
455 CInfo.EnableFullDCE = false;
456 AMDGPUPostLegalizerCombinerImpl Impl(MF, CInfo, *VT, /*CSEInfo*/ nullptr,
457 RuleConfig, ST, MDT, LI);
458 return Impl.combineMachineInstrs();
459}
460
461char AMDGPUPostLegalizerCombiner::ID = 0;
462INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombiner, DEBUG_TYPE,
463 "Combine AMDGPU machine instrs after legalization", false,
464 false)
466INITIALIZE_PASS_END(AMDGPUPostLegalizerCombiner, DEBUG_TYPE,
467 "Combine AMDGPU machine instrs after legalization", false,
468 false)
469
471 return new AMDGPUPostLegalizerCombiner(IsOptNone);
472}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
This contains common combine transformations that may be used in a combine pass.
constexpr LLT S32
This file declares the targeting of the Machinelegalizer class for AMDGPU.
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common combine transformations that may be used in a combine pass,or by the target else...
Option class for Targets to specify which operations are combined how and when.
This contains the base class for all Combiners generated by TableGen.
AMD GCN specific subclass of TargetSubtarget.
Provides analysis for querying information about KnownBits during GISel passes.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Contains matchers for matching SSA Machine Instructions.
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static StringRef getName(Value *V)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Target-Independent Code Generator Pass Configuration Options pass.
Value * RHS
Value * LHS
bool canIgnoreLegacyMinMaxTies(const MachineInstr &MI, Register LHS, Register RHS) const
fmin_legacy/fmax_legacy select s1 on NaN, and on a +0.0/-0.0 tie (s1 for min, s0 for max).
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:293
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:278
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
@ FCMP_ULT
1 1 0 0 True if unordered or less than
Definition InstrTypes.h:754
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Definition InstrTypes.h:753
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
Predicate getUnorderedPredicate() const
Definition InstrTypes.h:874
GISelValueTracking * getValueTracking() const
LLVM_ABI bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount) const
Combiner implementation.
Definition Combiner.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
The CSE Analysis object.
Definition CSEInfo.h:72
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
bool maskedValueIsZero(Register Val, const APInt &Mask)
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
bool isCanonicalized(SelectionDAG &DAG, SDValue Op, SDNodeFlags UserFlags={}, unsigned MaxDepth=5) const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
operand_type_match m_Reg()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition Utils.cpp:1137
FunctionPass * createAMDGPUPostLegalizeCombiner(bool IsOptNone)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
@ SinglePass
Enables Observer-based DCE and additional heuristics that retry combining defined and used instructio...