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
114 /// Check if register is carry-out (operand 1) of a carry-producing add/sub
115 bool isCarryOut(Register Reg) const;
116
117 bool shouldFoldCarryIntoAdd(Register Src) const;
118
119private:
120#define GET_GICOMBINER_CLASS_MEMBERS
121#define AMDGPUSubtarget GCNSubtarget
122#include "AMDGPUGenPostLegalizeGICombiner.inc"
123#undef GET_GICOMBINER_CLASS_MEMBERS
124#undef AMDGPUSubtarget
125};
126
127#define GET_GICOMBINER_IMPL
128#define AMDGPUSubtarget GCNSubtarget
129#include "AMDGPUGenPostLegalizeGICombiner.inc"
130#undef AMDGPUSubtarget
131#undef GET_GICOMBINER_IMPL
132
133AMDGPUPostLegalizerCombinerImpl::AMDGPUPostLegalizerCombinerImpl(
135 GISelCSEInfo *CSEInfo,
136 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
137 const GCNSubtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
138 : Combiner(MF, CInfo, &VT, CSEInfo), RuleConfig(RuleConfig), STI(STI),
139 TII(*STI.getInstrInfo()),
140 Helper(Observer, B, /*IsPreLegalize*/ false, &VT, MDT, LI, STI),
142#include "AMDGPUGenPostLegalizeGICombiner.inc"
144{
145}
146
147bool AMDGPUPostLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
148 if (tryCombineAllImpl(MI))
149 return true;
150
151 switch (MI.getOpcode()) {
152 case TargetOpcode::G_SHL:
153 case TargetOpcode::G_LSHR:
154 case TargetOpcode::G_ASHR:
155 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
156 // common case, splitting this into a move and a 32-bit shift is faster and
157 // the same code size.
158 return Helper.tryCombineShiftToUnmerge(MI, 32);
159 }
160
161 return false;
162}
163
164bool AMDGPUPostLegalizerCombinerImpl::matchFMinFMaxLegacy(
165 MachineInstr &MI, MachineInstr &FCmp, FMinFMaxLegacyInfo &Info) const {
166 if (!MRI.hasOneNonDBGUse(FCmp.getOperand(0).getReg()))
167 return false;
168
169 Info.Pred =
170 static_cast<CmpInst::Predicate>(FCmp.getOperand(1).getPredicate());
171 Info.LHS = FCmp.getOperand(2).getReg();
172 Info.RHS = FCmp.getOperand(3).getReg();
173 Register True = MI.getOperand(2).getReg();
174 Register False = MI.getOperand(3).getReg();
175
176 // TODO: Handle case where the the selected value is an fneg and the compared
177 // constant is the negation of the selected value.
178 if ((Info.LHS != True || Info.RHS != False) &&
179 (Info.LHS != False || Info.RHS != True))
180 return false;
181
182 // Invert the predicate if necessary so that the apply function can assume
183 // that the select operands are the same as the fcmp operands.
184 // (select (fcmp P, L, R), R, L) -> (select (fcmp !P, L, R), L, R)
185 if (Info.LHS != True)
187
188 // Only match </<=/>=/> not ==/!= etc.
189 if (Info.Pred == CmpInst::getSwappedPredicate(Info.Pred))
190 return false;
191
192 // These predicates pick the signed zero tie-incorrect operand order.
193 if (Info.Pred == CmpInst::FCMP_OLE || Info.Pred == CmpInst::FCMP_ULT ||
194 Info.Pred == CmpInst::FCMP_OGT || Info.Pred == CmpInst::FCMP_UGE)
195 return Helper.canIgnoreLegacyMinMaxTies(MI, Info.LHS, Info.RHS);
196
197 return true;
198}
199
200void AMDGPUPostLegalizerCombinerImpl::applySelectFCmpToFMinFMaxLegacy(
201 MachineInstr &MI, const FMinFMaxLegacyInfo &Info) const {
202 unsigned Opc = (Info.Pred & CmpInst::FCMP_OGT) ? AMDGPU::G_AMDGPU_FMAX_LEGACY
203 : AMDGPU::G_AMDGPU_FMIN_LEGACY;
204 Register X = Info.LHS;
205 Register Y = Info.RHS;
206 if (Info.Pred == CmpInst::getUnorderedPredicate(Info.Pred)) {
207 // We need to permute the operands to get the correct NaN behavior. The
208 // selected operand is the second one based on the failing compare with NaN,
209 // so permute it based on the compare type the hardware uses.
210 std::swap(X, Y);
211 }
212
213 B.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags());
214
215 MI.eraseFromParent();
216}
217
218bool AMDGPUPostLegalizerCombinerImpl::matchUCharToFloat(
219 MachineInstr &MI) const {
220 Register DstReg = MI.getOperand(0).getReg();
221
222 // TODO: We could try to match extracting the higher bytes, which would be
223 // easier if i8 vectors weren't promoted to i32 vectors, particularly after
224 // types are legalized. v4i8 -> v4f32 is probably the only case to worry
225 // about in practice.
226 LLT Ty = MRI.getType(DstReg);
227 if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) {
228 Register SrcReg = MI.getOperand(1).getReg();
229 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits();
230 assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64);
231 const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8);
232 return Helper.getValueTracking()->maskedValueIsZero(SrcReg, Mask);
233 }
234
235 return false;
236}
237
238void AMDGPUPostLegalizerCombinerImpl::applyUCharToFloat(
239 MachineInstr &MI) const {
240 const LLT S32 = LLT::scalar(32);
241
242 Register DstReg = MI.getOperand(0).getReg();
243 Register SrcReg = MI.getOperand(1).getReg();
244 LLT Ty = MRI.getType(DstReg);
245 LLT SrcTy = MRI.getType(SrcReg);
246 if (SrcTy != S32)
247 SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0);
248
249 if (Ty == S32) {
250 B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, {SrcReg},
251 MI.getFlags());
252 } else {
253 auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, {SrcReg},
254 MI.getFlags());
255 B.buildFPTrunc(DstReg, Cvt0, MI.getFlags());
256 }
257
258 MI.eraseFromParent();
259}
260
261bool AMDGPUPostLegalizerCombinerImpl::matchFDivSqrtToRsqF16(
262 MachineInstr &MI) const {
263 Register Sqrt = MI.getOperand(2).getReg();
264 return MRI.hasOneNonDBGUse(Sqrt);
265}
266
267void AMDGPUPostLegalizerCombinerImpl::applyFDivSqrtToRsqF16(
268 MachineInstr &MI, const Register &X) const {
269 Register Dst = MI.getOperand(0).getReg();
270 Register Y = MI.getOperand(1).getReg();
271 LLT DstTy = MRI.getType(Dst);
272 uint32_t Flags = MI.getFlags();
273 Register RSQ = B.buildIntrinsic(Intrinsic::amdgcn_rsq, {DstTy})
274 .addUse(X)
275 .setMIFlags(Flags)
276 .getReg(0);
277 B.buildFMul(Dst, RSQ, Y, Flags);
278 MI.eraseFromParent();
279}
280
281bool AMDGPUPostLegalizerCombinerImpl::matchCvtF32UByteN(
282 MachineInstr &MI, CvtF32UByteMatchInfo &MatchInfo) const {
283 Register SrcReg = MI.getOperand(1).getReg();
284
285 // Look through G_ZEXT.
286 bool IsShr = mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg)));
287
289 int64_t ShiftAmt;
290 IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt)));
291 if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) {
292 const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0;
293
294 unsigned ShiftOffset = 8 * Offset;
295 if (IsShr)
296 ShiftOffset += ShiftAmt;
297 else
298 ShiftOffset -= ShiftAmt;
299
300 MatchInfo.CvtVal = Src0;
301 MatchInfo.ShiftOffset = ShiftOffset;
302 return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0;
303 }
304
305 // TODO: Simplify demanded bits.
306 return false;
307}
308
309void AMDGPUPostLegalizerCombinerImpl::applyCvtF32UByteN(
310 MachineInstr &MI, const CvtF32UByteMatchInfo &MatchInfo) const {
311 unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8;
312
313 const LLT S32 = LLT::scalar(32);
314 Register CvtSrc = MatchInfo.CvtVal;
315 LLT SrcTy = MRI.getType(MatchInfo.CvtVal);
316 if (SrcTy != S32) {
317 assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8);
318 CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0);
319 }
320
321 assert(MI.getOpcode() != NewOpc);
322 B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags());
323 MI.eraseFromParent();
324}
325
326bool AMDGPUPostLegalizerCombinerImpl::matchRemoveFcanonicalize(
327 MachineInstr &MI) const {
328 const SITargetLowering *TLI = static_cast<const SITargetLowering *>(
329 MF.getSubtarget().getTargetLowering());
330 return TLI->isCanonicalized(MI.getOperand(1).getReg(), MF);
331}
332
333// The buffer_load_{i8, i16} intrinsics are initially lowered as
334// buffer_load_{u8, u16} instructions. Here, the buffer_load_{u8, u16}
335// instructions are combined with sign extension instrucions in order to
336// generate buffer_load_{i8, i16} instructions.
337
338// Identify buffer_load_{u8, u16}.
339bool AMDGPUPostLegalizerCombinerImpl::matchCombineSignExtendInReg(
340 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
341 Register LoadReg = MI.getOperand(1).getReg();
342 if (!MRI.hasOneNonDBGUse(LoadReg))
343 return false;
344
345 // Check if the first operand of the sign extension is a subword buffer load
346 // instruction.
347 MachineInstr *LoadMI = MRI.getVRegDef(LoadReg);
348 int64_t Width = MI.getOperand(2).getImm();
349 switch (LoadMI->getOpcode()) {
350 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
351 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE};
352 return Width == 8;
353 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
354 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT};
355 return Width == 16;
356 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_UBYTE:
357 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SBYTE};
358 return Width == 8;
359 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_USHORT:
360 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SSHORT};
361 return Width == 16;
362 }
363 return false;
364}
365
366// Combine buffer_load_{u8, u16} and the sign extension instruction to generate
367// buffer_load_{i8, i16}.
368void AMDGPUPostLegalizerCombinerImpl::applyCombineSignExtendInReg(
369 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
370 auto [LoadMI, NewOpcode] = MatchData;
371 LoadMI->setDesc(TII.get(NewOpcode));
372 // Update the destination register of the load with the destination register
373 // of the sign extension.
374 Register SignExtendInsnDst = MI.getOperand(0).getReg();
375 LoadMI->getOperand(0).setReg(SignExtendInsnDst);
376 // Remove the sign extension.
377 MI.eraseFromParent();
378}
379
380bool AMDGPUPostLegalizerCombinerImpl::matchCombine_s_mul_u64(
381 MachineInstr &MI, unsigned &NewOpcode) const {
382 Register Src0 = MI.getOperand(1).getReg();
383 Register Src1 = MI.getOperand(2).getReg();
384 if (MRI.getType(Src0) != LLT::scalar(64))
385 return false;
386
387 if (VT->getKnownBits(Src1).countMinLeadingZeros() >= 32 &&
388 VT->getKnownBits(Src0).countMinLeadingZeros() >= 32) {
389 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_U64_U32;
390 return true;
391 }
392
393 if (VT->computeNumSignBits(Src1) >= 33 &&
394 VT->computeNumSignBits(Src0) >= 33) {
395 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_I64_I32;
396 return true;
397 }
398 return false;
399}
400
401bool AMDGPUPostLegalizerCombinerImpl::isCarryOut(Register Reg) const {
402 const MachineInstr *Def = MRI.getVRegDef(Reg);
403 if (!Def)
404 return false;
405
406 switch (Def->getOpcode()) {
407 case TargetOpcode::G_UADDO:
408 case TargetOpcode::G_UADDE:
409 case TargetOpcode::G_USUBO:
410 case TargetOpcode::G_USUBE:
411 return Def->getOperand(1).getReg() == Reg;
412 default:
413 return false;
414 }
415}
416
417bool AMDGPUPostLegalizerCombinerImpl::shouldFoldCarryIntoAdd(
418 Register Src) const {
419 // Let right_identity_zero combine delete this instead.
420 if (mi_match(Src, MRI, m_SpecificICst(0)))
421 return false;
422
423 // When both operands are a carry only the right hand one is folded, so that
424 // the two carries never have to be live at the same time.
425 Register Carry;
426 return !mi_match(Src, MRI, m_GZExt(m_Reg(Carry))) ||
427 !MRI.hasOneNonDBGUse(Src) || !isCarryOut(Carry);
428}
429
430// Pass boilerplate
431// ================
432
433static bool
434runCombiner(MachineFunction &MF, GISelValueTracking *VT, GISelCSEInfo *CSEInfo,
435 MachineDominatorTree *MDT,
436 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
437 bool EnableOpt) {
438 const Function &F = MF.getFunction();
439 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
440 const LegalizerInfo *LI = ST.getLegalizerInfo();
441
442 CombinerInfo CInfo(/*AllowIllegalOps=*/false,
443 /*ShouldLegalizeIllegal=*/true, LI, EnableOpt,
444 F.hasOptSize(), F.hasMinSize());
445 // Disable fixed-point iteration to reduce compile-time
446 CInfo.MaxIterations = 1;
447 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
448 // Legalizer performs DCE, so a full DCE pass is unnecessary.
449 CInfo.EnableFullDCE = false;
450 AMDGPUPostLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST,
451 MDT, LI);
452 return Impl.combineMachineInstrs();
453}
454
455class AMDGPUPostLegalizerCombinerLegacy : public MachineFunctionPass {
456public:
457 static char ID;
458
459 AMDGPUPostLegalizerCombinerLegacy(bool IsOptNone = false);
460
461 StringRef getPassName() const override {
462 return "AMDGPUPostLegalizerCombiner";
463 }
464
465 bool runOnMachineFunction(MachineFunction &MF) override;
466
467 void getAnalysisUsage(AnalysisUsage &AU) const override;
468
469private:
470 bool IsOptNone;
471 AMDGPUPostLegalizerCombinerImplRuleConfig RuleConfig;
472};
473} // end anonymous namespace
474
475void AMDGPUPostLegalizerCombinerLegacy::getAnalysisUsage(
476 AnalysisUsage &AU) const {
477 AU.setPreservesCFG();
479 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
480 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
481 AU.addRequired<GISelCSEAnalysisWrapperPass>();
482 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
483 if (!IsOptNone) {
484 AU.addRequired<MachineDominatorTreeWrapperPass>();
485 }
487}
488
489AMDGPUPostLegalizerCombinerLegacy::AMDGPUPostLegalizerCombinerLegacy(
490 bool IsOptNone)
491 : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
492 if (!RuleConfig.parseCommandLineOption())
493 report_fatal_error("Invalid rule identifier");
494}
495
496bool AMDGPUPostLegalizerCombinerLegacy::runOnMachineFunction(
497 MachineFunction &MF) {
498 if (MF.getProperties().hasFailedISel())
499 return false;
500 const Function &F = MF.getFunction();
501 bool EnableOpt =
502 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
503
504 GISelValueTracking *VT =
505 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
506 GISelCSEAnalysisWrapper &Wrapper =
507 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
508 GISelCSEInfo *CSEInfo =
510 MachineDominatorTree *MDT =
511 IsOptNone ? nullptr
512 : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
513
514 return runCombiner(MF, VT, CSEInfo, MDT, RuleConfig, EnableOpt);
515}
516
517char AMDGPUPostLegalizerCombinerLegacy::ID = 0;
518INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombinerLegacy, DEBUG_TYPE,
519 "Combine AMDGPU machine instrs after legalization", false,
520 false)
523INITIALIZE_PASS_END(AMDGPUPostLegalizerCombinerLegacy, DEBUG_TYPE,
524 "Combine AMDGPU machine instrs after legalization", false,
525 false)
526
528 return new AMDGPUPostLegalizerCombinerLegacy(IsOptNone);
529}
530
534 if (MF.getProperties().hasFailedISel())
535 return PreservedAnalyses::all();
536
537 AMDGPUPostLegalizerCombinerImplRuleConfig RuleConfig;
538 if (!RuleConfig.parseCommandLineOption())
539 report_fatal_error("Invalid rule identifier");
540
541 bool IsOptNone = MF.getTarget().getOptLevel() == CodeGenOptLevel::None ||
543
545 GISelCSEInfo *CSEInfo = MFAM.getResult<GISelCSEAnalysis>(MF).get();
547 IsOptNone ? nullptr : &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
548
549 if (!runCombiner(MF, &VT, CSEInfo, MDT, RuleConfig,
550 /*EnableOpt=*/!IsOptNone))
551 return PreservedAnalyses::all();
552
557 return PA;
558}
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.
Register Reg
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:292
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()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
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.
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
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