[SampleProfileLoader] Fix integer overflow in generateMDProfMetadata (#90217)
[llvm-project.git] / llvm / lib / Target / SPIRV / SPIRVPostLegalizer.cpp
blobd652b5de60808640a0702bcf250fd246e8949712
1 //===-- SPIRVPostLegalizer.cpp - ammend info after legalization -*- C++ -*-===//
2 //
3 // which may appear after the legalizer pass
4 //
5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 // See https://llvm.org/LICENSE.txt for license information.
7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //
9 //===----------------------------------------------------------------------===//
11 // The pass partially apply pre-legalization logic to new instructions inserted
12 // as a result of legalization:
13 // - assigns SPIR-V types to registers for new instructions.
15 //===----------------------------------------------------------------------===//
17 #include "SPIRV.h"
18 #include "SPIRVSubtarget.h"
19 #include "SPIRVUtils.h"
20 #include "llvm/ADT/PostOrderIterator.h"
21 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
22 #include "llvm/IR/Attributes.h"
23 #include "llvm/IR/Constants.h"
24 #include "llvm/IR/DebugInfoMetadata.h"
25 #include "llvm/IR/IntrinsicsSPIRV.h"
26 #include "llvm/Target/TargetIntrinsicInfo.h"
28 #define DEBUG_TYPE "spirv-postlegalizer"
30 using namespace llvm;
32 namespace {
33 class SPIRVPostLegalizer : public MachineFunctionPass {
34 public:
35 static char ID;
36 SPIRVPostLegalizer() : MachineFunctionPass(ID) {
37 initializeSPIRVPostLegalizerPass(*PassRegistry::getPassRegistry());
39 bool runOnMachineFunction(MachineFunction &MF) override;
41 } // namespace
43 // Defined in SPIRVLegalizerInfo.cpp.
44 extern bool isTypeFoldingSupported(unsigned Opcode);
46 namespace llvm {
47 // Defined in SPIRVPreLegalizer.cpp.
48 extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
49 SPIRVGlobalRegistry *GR,
50 MachineIRBuilder &MIB,
51 MachineRegisterInfo &MRI);
52 extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
53 MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR);
54 } // namespace llvm
56 static bool isMetaInstrGET(unsigned Opcode) {
57 return Opcode == SPIRV::GET_ID || Opcode == SPIRV::GET_fID ||
58 Opcode == SPIRV::GET_pID32 || Opcode == SPIRV::GET_pID64 ||
59 Opcode == SPIRV::GET_vID || Opcode == SPIRV::GET_vfID ||
60 Opcode == SPIRV::GET_vpID32 || Opcode == SPIRV::GET_vpID64;
63 static bool mayBeInserted(unsigned Opcode) {
64 switch (Opcode) {
65 case TargetOpcode::G_SMAX:
66 case TargetOpcode::G_UMAX:
67 case TargetOpcode::G_SMIN:
68 case TargetOpcode::G_UMIN:
69 case TargetOpcode::G_FMINNUM:
70 case TargetOpcode::G_FMINIMUM:
71 case TargetOpcode::G_FMAXNUM:
72 case TargetOpcode::G_FMAXIMUM:
73 return true;
74 default:
75 return isTypeFoldingSupported(Opcode);
79 static void processNewInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
80 MachineIRBuilder MIB) {
81 MachineRegisterInfo &MRI = MF.getRegInfo();
83 for (MachineBasicBlock &MBB : MF) {
84 for (MachineInstr &I : MBB) {
85 const unsigned Opcode = I.getOpcode();
86 if (Opcode == TargetOpcode::G_UNMERGE_VALUES) {
87 unsigned ArgI = I.getNumOperands() - 1;
88 Register SrcReg = I.getOperand(ArgI).isReg()
89 ? I.getOperand(ArgI).getReg()
90 : Register(0);
91 SPIRVType *DefType =
92 SrcReg.isValid() ? GR->getSPIRVTypeForVReg(SrcReg) : nullptr;
93 if (!DefType || DefType->getOpcode() != SPIRV::OpTypeVector)
94 report_fatal_error(
95 "cannot select G_UNMERGE_VALUES with a non-vector argument");
96 SPIRVType *ScalarType =
97 GR->getSPIRVTypeForVReg(DefType->getOperand(1).getReg());
98 for (unsigned i = 0; i < I.getNumDefs(); ++i) {
99 Register ResVReg = I.getOperand(i).getReg();
100 SPIRVType *ResType = GR->getSPIRVTypeForVReg(ResVReg);
101 if (!ResType) {
102 // There was no "assign type" actions, let's fix this now
103 ResType = ScalarType;
104 MRI.setRegClass(ResVReg, &SPIRV::IDRegClass);
105 MRI.setType(ResVReg,
106 LLT::scalar(GR->getScalarOrVectorBitWidth(ResType)));
107 GR->assignSPIRVTypeToVReg(ResType, ResVReg, *GR->CurMF);
110 } else if (mayBeInserted(Opcode) && I.getNumDefs() == 1 &&
111 I.getNumOperands() > 1 && I.getOperand(1).isReg()) {
112 // Legalizer may have added a new instructions and introduced new
113 // registers, we must decorate them as if they were introduced in a
114 // non-automatic way
115 Register ResVReg = I.getOperand(0).getReg();
116 SPIRVType *ResVType = GR->getSPIRVTypeForVReg(ResVReg);
117 // Check if the register defined by the instruction is newly generated
118 // or already processed
119 if (!ResVType) {
120 // Set type of the defined register
121 ResVType = GR->getSPIRVTypeForVReg(I.getOperand(1).getReg());
122 // Check if we have type defined for operands of the new instruction
123 if (!ResVType)
124 continue;
125 // Set type & class
126 MRI.setRegClass(ResVReg, &SPIRV::IDRegClass);
127 MRI.setType(ResVReg,
128 LLT::scalar(GR->getScalarOrVectorBitWidth(ResVType)));
129 GR->assignSPIRVTypeToVReg(ResVType, ResVReg, *GR->CurMF);
131 // If this is a simple operation that is to be reduced by TableGen
132 // definition we must apply some of pre-legalizer rules here
133 if (isTypeFoldingSupported(Opcode)) {
134 // Check if the instruction newly generated or already processed
135 MachineInstr *NextMI = I.getNextNode();
136 if (NextMI && isMetaInstrGET(NextMI->getOpcode()))
137 continue;
138 // Restore usual instructions pattern for the newly inserted
139 // instruction
140 MRI.setRegClass(ResVReg, MRI.getType(ResVReg).isVector()
141 ? &SPIRV::IDRegClass
142 : &SPIRV::ANYIDRegClass);
143 MRI.setType(ResVReg, LLT::scalar(32));
144 insertAssignInstr(ResVReg, nullptr, ResVType, GR, MIB, MRI);
145 processInstr(I, MIB, MRI, GR);
152 bool SPIRVPostLegalizer::runOnMachineFunction(MachineFunction &MF) {
153 // Initialize the type registry.
154 const SPIRVSubtarget &ST = MF.getSubtarget<SPIRVSubtarget>();
155 SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
156 GR->setCurrentFunc(MF);
157 MachineIRBuilder MIB(MF);
159 processNewInstrs(MF, GR, MIB);
161 return true;
164 INITIALIZE_PASS(SPIRVPostLegalizer, DEBUG_TYPE, "SPIRV post legalizer", false,
165 false)
167 char SPIRVPostLegalizer::ID = 0;
169 FunctionPass *llvm::createSPIRVPostLegalizerPass() {
170 return new SPIRVPostLegalizer();