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"
30#include "llvm/IR/IntrinsicsAMDGPU.h"
32
33#define GET_GICOMBINER_DEPS
34#include "AMDGPUGenPreLegalizeGICombiner.inc"
35#undef GET_GICOMBINER_DEPS
36
37#define DEBUG_TYPE "amdgpu-postlegalizer-combiner"
38
39using namespace llvm;
40using namespace MIPatternMatch;
41
42namespace {
43#define GET_GICOMBINER_TYPES
44#include "AMDGPUGenPostLegalizeGICombiner.inc"
45#undef GET_GICOMBINER_TYPES
46
47class AMDGPUPostLegalizerCombinerImpl : public Combiner {
48protected:
49 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig;
50 const GCNSubtarget &STI;
51 const SIInstrInfo &TII;
52 // TODO: Make CombinerHelper methods const.
53 mutable AMDGPUCombinerHelper Helper;
54
55public:
56 AMDGPUPostLegalizerCombinerImpl(
58 GISelCSEInfo *CSEInfo,
59 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
60 const GCNSubtarget &STI, MachineDominatorTree *MDT,
61 const LegalizerInfo *LI);
62
63 static const char *getName() { return "AMDGPUPostLegalizerCombinerImpl"; }
64
65 bool tryCombineAllImpl(MachineInstr &I) const;
66 bool tryCombineAll(MachineInstr &I) const override;
67
68 struct FMinFMaxLegacyInfo {
72 };
73
74 // TODO: Make sure fmin_legacy/fmax_legacy don't canonicalize
75 bool matchFMinFMaxLegacy(MachineInstr &MI, MachineInstr &FCmp,
76 FMinFMaxLegacyInfo &Info) const;
77 void applySelectFCmpToFMinFMaxLegacy(MachineInstr &MI,
78 const FMinFMaxLegacyInfo &Info) const;
79
80 bool matchUCharToFloat(MachineInstr &MI) const;
81 void applyUCharToFloat(MachineInstr &MI) const;
82
83 bool matchFDivSqrtToRsqF16(MachineInstr &MI) const;
84 void applyFDivSqrtToRsqF16(MachineInstr &MI, const Register &X) const;
85
86 // FIXME: Should be able to have 2 separate matchdatas rather than custom
87 // struct boilerplate.
88 struct CvtF32UByteMatchInfo {
89 Register CvtVal;
90 unsigned ShiftOffset;
91 };
92
93 bool matchCvtF32UByteN(MachineInstr &MI,
94 CvtF32UByteMatchInfo &MatchInfo) const;
95 void applyCvtF32UByteN(MachineInstr &MI,
96 const CvtF32UByteMatchInfo &MatchInfo) const;
97
98 bool matchRemoveFcanonicalize(MachineInstr &MI) const;
99
100 // Combine unsigned buffer load and signed extension instructions to generate
101 // signed buffer load instructions.
102 bool matchCombineSignExtendInReg(
103 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchInfo) const;
104 void applyCombineSignExtendInReg(
105 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchInfo) const;
106
107 // Find the s_mul_u64 instructions where the higher bits are either
108 // zero-extended or sign-extended.
109 // Replace the s_mul_u64 instructions with S_MUL_I64_I32_PSEUDO if the higher
110 // 33 bits are sign extended and with S_MUL_U64_U32_PSEUDO if the higher 32
111 // bits are zero extended.
112 bool matchCombine_s_mul_u64(MachineInstr &MI, unsigned &NewOpcode) const;
113
114private:
115#define GET_GICOMBINER_CLASS_MEMBERS
116#define AMDGPUSubtarget GCNSubtarget
117#include "AMDGPUGenPostLegalizeGICombiner.inc"
118#undef GET_GICOMBINER_CLASS_MEMBERS
119#undef AMDGPUSubtarget
120};
121
122#define GET_GICOMBINER_IMPL
123#define AMDGPUSubtarget GCNSubtarget
124#include "AMDGPUGenPostLegalizeGICombiner.inc"
125#undef AMDGPUSubtarget
126#undef GET_GICOMBINER_IMPL
127
128AMDGPUPostLegalizerCombinerImpl::AMDGPUPostLegalizerCombinerImpl(
130 GISelCSEInfo *CSEInfo,
131 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
132 const GCNSubtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
133 : Combiner(MF, CInfo, &VT, CSEInfo), RuleConfig(RuleConfig), STI(STI),
134 TII(*STI.getInstrInfo()),
135 Helper(Observer, B, /*IsPreLegalize*/ false, &VT, MDT, LI, STI),
137#include "AMDGPUGenPostLegalizeGICombiner.inc"
139{
140}
141
142bool AMDGPUPostLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
143 if (tryCombineAllImpl(MI))
144 return true;
145
146 switch (MI.getOpcode()) {
147 case TargetOpcode::G_SHL:
148 case TargetOpcode::G_LSHR:
149 case TargetOpcode::G_ASHR:
150 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
151 // common case, splitting this into a move and a 32-bit shift is faster and
152 // the same code size.
153 return Helper.tryCombineShiftToUnmerge(MI, 32);
154 }
155
156 return false;
157}
158
159bool AMDGPUPostLegalizerCombinerImpl::matchFMinFMaxLegacy(
160 MachineInstr &MI, MachineInstr &FCmp, FMinFMaxLegacyInfo &Info) const {
161 if (!MRI.hasOneNonDBGUse(FCmp.getOperand(0).getReg()))
162 return false;
163
164 Info.Pred =
165 static_cast<CmpInst::Predicate>(FCmp.getOperand(1).getPredicate());
166 Info.LHS = FCmp.getOperand(2).getReg();
167 Info.RHS = FCmp.getOperand(3).getReg();
168 Register True = MI.getOperand(2).getReg();
169 Register False = MI.getOperand(3).getReg();
170
171 // TODO: Handle case where the the selected value is an fneg and the compared
172 // constant is the negation of the selected value.
173 if ((Info.LHS != True || Info.RHS != False) &&
174 (Info.LHS != False || Info.RHS != True))
175 return false;
176
177 // Invert the predicate if necessary so that the apply function can assume
178 // that the select operands are the same as the fcmp operands.
179 // (select (fcmp P, L, R), R, L) -> (select (fcmp !P, L, R), L, R)
180 if (Info.LHS != True)
182
183 // Only match </<=/>=/> not ==/!= etc.
184 if (Info.Pred == CmpInst::getSwappedPredicate(Info.Pred))
185 return false;
186
187 // These predicates pick the signed zero tie-incorrect operand order.
188 if (Info.Pred == CmpInst::FCMP_OLE || Info.Pred == CmpInst::FCMP_ULT ||
189 Info.Pred == CmpInst::FCMP_OGT || Info.Pred == CmpInst::FCMP_UGE)
190 return Helper.canIgnoreLegacyMinMaxTies(MI, Info.LHS, Info.RHS);
191
192 return true;
193}
194
195void AMDGPUPostLegalizerCombinerImpl::applySelectFCmpToFMinFMaxLegacy(
196 MachineInstr &MI, const FMinFMaxLegacyInfo &Info) const {
197 unsigned Opc = (Info.Pred & CmpInst::FCMP_OGT) ? AMDGPU::G_AMDGPU_FMAX_LEGACY
198 : AMDGPU::G_AMDGPU_FMIN_LEGACY;
199 Register X = Info.LHS;
200 Register Y = Info.RHS;
201 if (Info.Pred == CmpInst::getUnorderedPredicate(Info.Pred)) {
202 // We need to permute the operands to get the correct NaN behavior. The
203 // selected operand is the second one based on the failing compare with NaN,
204 // so permute it based on the compare type the hardware uses.
205 std::swap(X, Y);
206 }
207
208 B.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags());
209
210 MI.eraseFromParent();
211}
212
213bool AMDGPUPostLegalizerCombinerImpl::matchUCharToFloat(
214 MachineInstr &MI) const {
215 Register DstReg = MI.getOperand(0).getReg();
216
217 // TODO: We could try to match extracting the higher bytes, which would be
218 // easier if i8 vectors weren't promoted to i32 vectors, particularly after
219 // types are legalized. v4i8 -> v4f32 is probably the only case to worry
220 // about in practice.
221 LLT Ty = MRI.getType(DstReg);
222 if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) {
223 Register SrcReg = MI.getOperand(1).getReg();
224 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits();
225 assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64);
226 const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8);
227 return Helper.getValueTracking()->maskedValueIsZero(SrcReg, Mask);
228 }
229
230 return false;
231}
232
233void AMDGPUPostLegalizerCombinerImpl::applyUCharToFloat(
234 MachineInstr &MI) const {
235 const LLT S32 = LLT::scalar(32);
236
237 Register DstReg = MI.getOperand(0).getReg();
238 Register SrcReg = MI.getOperand(1).getReg();
239 LLT Ty = MRI.getType(DstReg);
240 LLT SrcTy = MRI.getType(SrcReg);
241 if (SrcTy != S32)
242 SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0);
243
244 if (Ty == S32) {
245 B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, {SrcReg},
246 MI.getFlags());
247 } else {
248 auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, {SrcReg},
249 MI.getFlags());
250 B.buildFPTrunc(DstReg, Cvt0, MI.getFlags());
251 }
252
253 MI.eraseFromParent();
254}
255
256bool AMDGPUPostLegalizerCombinerImpl::matchFDivSqrtToRsqF16(
257 MachineInstr &MI) const {
258 Register Sqrt = MI.getOperand(2).getReg();
259 return MRI.hasOneNonDBGUse(Sqrt);
260}
261
262void AMDGPUPostLegalizerCombinerImpl::applyFDivSqrtToRsqF16(
263 MachineInstr &MI, const Register &X) const {
264 Register Dst = MI.getOperand(0).getReg();
265 Register Y = MI.getOperand(1).getReg();
266 LLT DstTy = MRI.getType(Dst);
267 uint32_t Flags = MI.getFlags();
268 Register RSQ = B.buildIntrinsic(Intrinsic::amdgcn_rsq, {DstTy})
269 .addUse(X)
270 .setMIFlags(Flags)
271 .getReg(0);
272 B.buildFMul(Dst, RSQ, Y, Flags);
273 MI.eraseFromParent();
274}
275
276bool AMDGPUPostLegalizerCombinerImpl::matchCvtF32UByteN(
277 MachineInstr &MI, CvtF32UByteMatchInfo &MatchInfo) const {
278 Register SrcReg = MI.getOperand(1).getReg();
279
280 // Look through G_ZEXT.
281 bool IsShr = mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg)));
282
283 Register Src0;
284 int64_t ShiftAmt;
285 IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt)));
286 if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) {
287 const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0;
288
289 unsigned ShiftOffset = 8 * Offset;
290 if (IsShr)
291 ShiftOffset += ShiftAmt;
292 else
293 ShiftOffset -= ShiftAmt;
294
295 MatchInfo.CvtVal = Src0;
296 MatchInfo.ShiftOffset = ShiftOffset;
297 return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0;
298 }
299
300 // TODO: Simplify demanded bits.
301 return false;
302}
303
304void AMDGPUPostLegalizerCombinerImpl::applyCvtF32UByteN(
305 MachineInstr &MI, const CvtF32UByteMatchInfo &MatchInfo) const {
306 unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8;
307
308 const LLT S32 = LLT::scalar(32);
309 Register CvtSrc = MatchInfo.CvtVal;
310 LLT SrcTy = MRI.getType(MatchInfo.CvtVal);
311 if (SrcTy != S32) {
312 assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8);
313 CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0);
314 }
315
316 assert(MI.getOpcode() != NewOpc);
317 B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags());
318 MI.eraseFromParent();
319}
320
321bool AMDGPUPostLegalizerCombinerImpl::matchRemoveFcanonicalize(
322 MachineInstr &MI) const {
323 const SITargetLowering *TLI = static_cast<const SITargetLowering *>(
324 MF.getSubtarget().getTargetLowering());
325 return TLI->isCanonicalized(MI.getOperand(1).getReg(), MF);
326}
327
328// The buffer_load_{i8, i16} intrinsics are initially lowered as
329// buffer_load_{u8, u16} instructions. Here, the buffer_load_{u8, u16}
330// instructions are combined with sign extension instrucions in order to
331// generate buffer_load_{i8, i16} instructions.
332
333// Identify buffer_load_{u8, u16}.
334bool AMDGPUPostLegalizerCombinerImpl::matchCombineSignExtendInReg(
335 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
336 Register LoadReg = MI.getOperand(1).getReg();
337 if (!MRI.hasOneNonDBGUse(LoadReg))
338 return false;
339
340 // Check if the first operand of the sign extension is a subword buffer load
341 // instruction.
342 MachineInstr *LoadMI = MRI.getVRegDef(LoadReg);
343 int64_t Width = MI.getOperand(2).getImm();
344 switch (LoadMI->getOpcode()) {
345 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
346 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE};
347 return Width == 8;
348 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
349 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT};
350 return Width == 16;
351 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_UBYTE:
352 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SBYTE};
353 return Width == 8;
354 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_USHORT:
355 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SSHORT};
356 return Width == 16;
357 }
358 return false;
359}
360
361// Combine buffer_load_{u8, u16} and the sign extension instruction to generate
362// buffer_load_{i8, i16}.
363void AMDGPUPostLegalizerCombinerImpl::applyCombineSignExtendInReg(
364 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
365 auto [LoadMI, NewOpcode] = MatchData;
366 LoadMI->setDesc(TII.get(NewOpcode));
367 // Update the destination register of the load with the destination register
368 // of the sign extension.
369 Register SignExtendInsnDst = MI.getOperand(0).getReg();
370 LoadMI->getOperand(0).setReg(SignExtendInsnDst);
371 // Remove the sign extension.
372 MI.eraseFromParent();
373}
374
375bool AMDGPUPostLegalizerCombinerImpl::matchCombine_s_mul_u64(
376 MachineInstr &MI, unsigned &NewOpcode) const {
377 Register Src0 = MI.getOperand(1).getReg();
378 Register Src1 = MI.getOperand(2).getReg();
379 if (MRI.getType(Src0) != LLT::scalar(64))
380 return false;
381
382 if (VT->getKnownBits(Src1).countMinLeadingZeros() >= 32 &&
383 VT->getKnownBits(Src0).countMinLeadingZeros() >= 32) {
384 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_U64_U32;
385 return true;
386 }
387
388 if (VT->computeNumSignBits(Src1) >= 33 &&
389 VT->computeNumSignBits(Src0) >= 33) {
390 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_I64_I32;
391 return true;
392 }
393 return false;
394}
395
396// Pass boilerplate
397// ================
398
399static bool
400runCombiner(MachineFunction &MF, GISelValueTracking *VT, GISelCSEInfo *CSEInfo,
401 MachineDominatorTree *MDT,
402 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
403 bool EnableOpt) {
404 const Function &F = MF.getFunction();
405 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
406 const LegalizerInfo *LI = ST.getLegalizerInfo();
407
408 CombinerInfo CInfo(/*AllowIllegalOps=*/false,
409 /*ShouldLegalizeIllegal=*/true, LI, EnableOpt,
410 F.hasOptSize(), F.hasMinSize());
411 // Disable fixed-point iteration to reduce compile-time
412 CInfo.MaxIterations = 1;
413 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
414 // Legalizer performs DCE, so a full DCE pass is unnecessary.
415 CInfo.EnableFullDCE = false;
416 AMDGPUPostLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST,
417 MDT, LI);
418 return Impl.combineMachineInstrs();
419}
420
421class AMDGPUPostLegalizerCombinerLegacy : public MachineFunctionPass {
422public:
423 static char ID;
424
425 AMDGPUPostLegalizerCombinerLegacy(bool IsOptNone = false);
426
427 StringRef getPassName() const override {
428 return "AMDGPUPostLegalizerCombiner";
429 }
430
431 bool runOnMachineFunction(MachineFunction &MF) override;
432
433 void getAnalysisUsage(AnalysisUsage &AU) const override;
434
435private:
436 bool IsOptNone;
437 AMDGPUPostLegalizerCombinerImplRuleConfig RuleConfig;
438};
439} // end anonymous namespace
440
441void AMDGPUPostLegalizerCombinerLegacy::getAnalysisUsage(
442 AnalysisUsage &AU) const {
443 AU.setPreservesCFG();
445 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
446 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
447 AU.addRequired<GISelCSEAnalysisWrapperPass>();
448 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
449 if (!IsOptNone) {
450 AU.addRequired<MachineDominatorTreeWrapperPass>();
451 }
453}
454
455AMDGPUPostLegalizerCombinerLegacy::AMDGPUPostLegalizerCombinerLegacy(
456 bool IsOptNone)
457 : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
458 if (!RuleConfig.parseCommandLineOption())
459 report_fatal_error("Invalid rule identifier");
460}
461
462bool AMDGPUPostLegalizerCombinerLegacy::runOnMachineFunction(
463 MachineFunction &MF) {
464 if (MF.getProperties().hasFailedISel())
465 return false;
466 const Function &F = MF.getFunction();
467 bool EnableOpt =
468 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
469
470 GISelValueTracking *VT =
471 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
472 GISelCSEAnalysisWrapper &Wrapper =
473 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
474 GISelCSEInfo *CSEInfo =
476 MachineDominatorTree *MDT =
477 IsOptNone ? nullptr
478 : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
479
480 return runCombiner(MF, VT, CSEInfo, MDT, RuleConfig, EnableOpt);
481}
482
483char AMDGPUPostLegalizerCombinerLegacy::ID = 0;
484INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombinerLegacy, DEBUG_TYPE,
485 "Combine AMDGPU machine instrs after legalization", false,
486 false)
489INITIALIZE_PASS_END(AMDGPUPostLegalizerCombinerLegacy, DEBUG_TYPE,
490 "Combine AMDGPU machine instrs after legalization", false,
491 false)
492
494 return new AMDGPUPostLegalizerCombinerLegacy(IsOptNone);
495}
496
500 if (MF.getProperties().hasFailedISel())
501 return PreservedAnalyses::all();
502
503 AMDGPUPostLegalizerCombinerImplRuleConfig RuleConfig;
504 if (!RuleConfig.parseCommandLineOption())
505 report_fatal_error("Invalid rule identifier");
506
507 bool IsOptNone = MF.getTarget().getOptLevel() == CodeGenOptLevel::None;
508
510 GISelCSEInfo *CSEInfo = MFAM.getResult<GISelCSEAnalysis>(MF).get();
512 IsOptNone ? nullptr : &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
513
514 if (!runCombiner(MF, &VT, CSEInfo, MDT, RuleConfig,
515 /*EnableOpt=*/!IsOptNone))
516 return PreservedAnalyses::all();
517
522 return PA;
523}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
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.
Provides AMDGPU specific target descriptions.
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
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).
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:293
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
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 actual analysis pass wrapper.
Definition CSEInfo.h:244
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.
Analysis pass which computes a MachineDominatorTree.
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.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
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
FunctionPass * createAMDGPUPostLegalizeCombinerLegacy(bool IsOptNone)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition CSEInfo.cpp:85
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
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
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880