52 return TE.EvexOpc < Opc;
55#include "X86GenEVEX2VEXTables.inc"
57#define EVEX2VEX_DESC "Compressing EVEX instrs to VEX encoding when possible"
58#define EVEX2VEX_NAME "x86-evex-to-vex-compress"
60#define DEBUG_TYPE EVEX2VEX_NAME
77 MachineFunctionProperties::Property::NoVRegs);
83char EvexToVexInstPass::ID = 0;
86 auto isHiRegIdx = [](
unsigned Reg) {
88 if (Reg >= X86::XMM16 && Reg <= X86::XMM31)
91 if (Reg >= X86::YMM16 && Reg <= X86::YMM31)
107 "ZMM instructions should not be in the EVEX->VEX tables");
119 case X86::VCVTNEPS2BF16Z128rm:
120 case X86::VCVTNEPS2BF16Z128rr:
121 case X86::VCVTNEPS2BF16Z256rm:
122 case X86::VCVTNEPS2BF16Z256rr:
123 return ST.hasAVXNECONVERT();
124 case X86::VPDPBUSDSZ128m:
125 case X86::VPDPBUSDSZ128r:
126 case X86::VPDPBUSDSZ256m:
127 case X86::VPDPBUSDSZ256r:
128 case X86::VPDPBUSDZ128m:
129 case X86::VPDPBUSDZ128r:
130 case X86::VPDPBUSDZ256m:
131 case X86::VPDPBUSDZ256r:
132 case X86::VPDPWSSDSZ128m:
133 case X86::VPDPWSSDSZ128r:
134 case X86::VPDPWSSDSZ256m:
135 case X86::VPDPWSSDSZ256r:
136 case X86::VPDPWSSDZ128m:
137 case X86::VPDPWSSDZ128r:
138 case X86::VPDPWSSDZ256m:
139 case X86::VPDPWSSDZ256r:
140 return ST.hasAVXVNNI();
141 case X86::VPMADD52HUQZ128m:
142 case X86::VPMADD52HUQZ128r:
143 case X86::VPMADD52HUQZ256m:
144 case X86::VPMADD52HUQZ256r:
145 case X86::VPMADD52LUQZ128m:
146 case X86::VPMADD52LUQZ128r:
147 case X86::VPMADD52LUQZ256m:
148 case X86::VPMADD52LUQZ256r:
149 return ST.hasAVXIFMA();
156 unsigned Opc =
MI.getOpcode();
158 case X86::VALIGNDZ128rri:
159 case X86::VALIGNDZ128rmi:
160 case X86::VALIGNQZ128rri:
161 case X86::VALIGNQZ128rmi: {
162 assert((VexOpc == X86::VPALIGNRrri || VexOpc == X86::VPALIGNRrmi) &&
163 "Unexpected new opcode!");
165 (Opc == X86::VALIGNQZ128rri || Opc == X86::VALIGNQZ128rmi) ? 8 : 4;
167 Imm.setImm(Imm.getImm() * Scale);
170 case X86::VSHUFF32X4Z256rmi:
171 case X86::VSHUFF32X4Z256rri:
172 case X86::VSHUFF64X2Z256rmi:
173 case X86::VSHUFF64X2Z256rri:
174 case X86::VSHUFI32X4Z256rmi:
175 case X86::VSHUFI32X4Z256rri:
176 case X86::VSHUFI64X2Z256rmi:
177 case X86::VSHUFI64X2Z256rri: {
178 assert((VexOpc == X86::VPERM2F128rr || VexOpc == X86::VPERM2I128rr ||
179 VexOpc == X86::VPERM2F128rm || VexOpc == X86::VPERM2I128rm) &&
180 "Unexpected new opcode!");
182 int64_t ImmVal = Imm.getImm();
184 Imm.setImm(0x20 | ((ImmVal & 2) << 3) | (ImmVal & 1));
187 case X86::VRNDSCALEPDZ128rri:
188 case X86::VRNDSCALEPDZ128rmi:
189 case X86::VRNDSCALEPSZ128rri:
190 case X86::VRNDSCALEPSZ128rmi:
191 case X86::VRNDSCALEPDZ256rri:
192 case X86::VRNDSCALEPDZ256rmi:
193 case X86::VRNDSCALEPSZ256rri:
194 case X86::VRNDSCALEPSZ256rmi:
195 case X86::VRNDSCALESDZr:
196 case X86::VRNDSCALESDZm:
197 case X86::VRNDSCALESSZr:
198 case X86::VRNDSCALESSZm:
199 case X86::VRNDSCALESDZr_Int:
200 case X86::VRNDSCALESDZm_Int:
201 case X86::VRNDSCALESSZr_Int:
202 case X86::VRNDSCALESSZm_Int:
204 int64_t ImmVal = Imm.getImm();
206 if ((ImmVal & 0xf) != ImmVal)
244 :
ArrayRef(X86EvexToVex128CompressTable);
246 unsigned EvexOpc =
MI.getOpcode();
248 if (
I == Table.
end() ||
I->EvexOpc != EvexOpc)
258 MI.setDesc(ST.getInstrInfo()->get(
I->VexOpc));
266 static std::atomic<bool> TableChecked(
false);
267 if (!TableChecked.load(std::memory_order_relaxed)) {
269 "X86EvexToVex128CompressTable is not sorted!");
271 "X86EvexToVex256CompressTable is not sorted!");
272 TableChecked.store(
true, std::memory_order_relaxed);
279 bool Changed =
false;
295 return new EvexToVexInstPass();
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool checkVEXInstPredicate(unsigned EvexOpc, const X86Subtarget &ST)
static bool performCustomAdjustments(MachineInstr &MI, unsigned VexOpc)
static bool CompressEvexToVexImpl(MachineInstr &MI, const X86Subtarget &ST)
static bool usesExtendedRegister(const MachineInstr &MI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isZMMReg(unsigned RegNo)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
bool isApxExtendedReg(unsigned RegNo)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createX86EvexToVexInsts()
This pass replaces EVEX encoded of AVX-512 instructiosn by VEX encoding when possible in order to red...
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
friend bool operator<(const X86EvexToVexCompressTableEntry &TE, unsigned Opc)
bool operator<(const X86EvexToVexCompressTableEntry &RHS) const
Description of the encoding of one expression Op.