LLVM: lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23
24#define DEBUG_TYPE "gi-combiner"
25
26using namespace llvm;
27
32
35
36 LLT DstTy = MRI.getType(Dst);
37 LLT SrcTy = MRI.getType(Src);
38
39
41 if (DstTy != SrcTy ||
43 return false;
44
45
46
47 unsigned TruncWidth = MRI.getType(Trunc->getReg(0)).getScalarSizeInBits();
48 if (TruncWidth < 8)
49 return false;
50
52 B.buildSExtInReg(Dst, Src, TruncWidth);
53 };
54 return true;
55 }
56
57
58
59 if (DstTy == SrcTy) {
61 return true;
62 }
63
68 };
69 return true;
70 }
71
75 return true;
76 }
77
78 return false;
79}
80
85
88
89 LLT DstTy = MRI.getType(Dst);
90 LLT SrcTy = MRI.getType(Src);
91
92 if (DstTy == SrcTy) {
94 return true;
95 }
96
101 };
102 return true;
103 }
104
109 };
110 return true;
111 }
112
113 return false;
114}
115
119
122
123 LLT DstTy = MRI.getType(Dst);
124 LLT SrcTy = MRI.getType(Src);
126
127
131 return true;
132 }
133
134 return false;
135}
136
142
143 if (.hasOneNonDBGUse(Ext->getReg(0)))
144 return false;
145
148 LLT DstTy = MRI.getType(Dst);
149 LLT SrcTy = MRI.getType(Src);
150
151 if (SrcTy == DstTy) {
152
154
155 return true;
156 }
157
159
160
162 return false;
163
165 B.buildInstr(Ext->getOpcode(), {Dst}, {Src});
166 };
167
168 return true;
169 }
170
172
173
175 return false;
176
178
179 return true;
180 }
181
182 return false;
183}
184
185bool CombinerHelper::isCastFree(unsigned Opcode, LLT ToTy, LLT FromTy) const {
188
189 switch (Opcode) {
190 case TargetOpcode::G_ANYEXT:
191 case TargetOpcode::G_ZEXT:
192 return TLI.isZExtFree(FromTy, ToTy, Ctx);
193 case TargetOpcode::G_TRUNC:
195 default:
196 return false;
197 }
198}
199
205
206 if (.hasOneNonDBGUse(Select->getReg(0)))
207 return false;
208
210 LLT DstTy = MRI.getType(Dst);
211 LLT CondTy = MRI.getType(Select->getCondReg());
214 LLT SrcTy = MRI.getType(TrueReg);
216
218 return false;
219
220 if (!isCastFree(Cast->getOpcode(), DstTy, SrcTy))
221 return false;
222
224 auto True = B.buildInstr(Cast->getOpcode(), {DstTy}, {TrueReg});
225 auto False = B.buildInstr(Cast->getOpcode(), {DstTy}, {FalseReg});
226 B.buildSelect(Dst, Cond, True, False);
227 };
228
229 return true;
230}
231
237
240 LLT DstTy = MRI.getType(Dst);
241 LLT SrcTy = MRI.getType(Src);
242
243 if (.hasOneNonDBGUse(Second->getReg(0)))
244 return false;
245
246
249 if (Second->getOpcode() == TargetOpcode::G_ZEXT) {
253 MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); };
254 return true;
255 }
256
258 B.buildInstr(Second->getOpcode(), {Dst}, {Src});
259 };
260 return true;
261 }
262
263
264
265 if (First->getOpcode() == TargetOpcode::G_ANYEXT &&
267 if (Second->getOpcode() == TargetOpcode::G_ZEXT) {
271 MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); };
272 return true;
273 }
275 return true;
276 }
277
278
279
280 if (Second->getOpcode() == TargetOpcode::G_ANYEXT &&
282 if (First->getOpcode() == TargetOpcode::G_ZEXT) {
286 MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); };
287 return true;
288 }
290 return true;
291 }
292
293 return false;
294}
295
301
302 if (.hasOneNonDBGUse(BV->getReg(0)))
303 return false;
304
306
307 LLT DstTy = MRI.getType(Dst);
308
310
311 LLT InputElemTy = MRI.getType(BV->getReg(0)).getElementType();
312
313
314
316 {TargetOpcode::G_BUILD_VECTOR, {DstTy, ElemTy}}) ||
318 !isCastFree(Cast->getOpcode(), ElemTy, InputElemTy))
319 return false;
320
324 for (unsigned I = 0; I < Elements; ++I) {
325 auto CastI =
326 B.buildInstr(Cast->getOpcode(), {ElemTy}, {BV->getSourceReg(I)});
327 Casts.push_back(CastI.getReg(0));
328 }
329
330 B.buildBuildVector(Dst, Casts);
331 };
332
333 return true;
334}
335
341
342 if (.hasOneNonDBGUse(BinOp->getReg(0)))
343 return false;
344
346 LLT DstTy = MRI.getType(Dst);
347
348
350 return false;
351
353 auto LHS = B.buildTrunc(DstTy, BinOp->getLHSReg());
354 auto RHS = B.buildTrunc(DstTy, BinOp->getRHSReg());
355 B.buildInstr(BinOp->getOpcode(), {Dst}, {LHS, RHS});
356 };
357
358 return true;
359}
360
362 APInt &MatchInfo) const {
364
366
368
370 return false;
371
373 case TargetOpcode::G_TRUNC: {
375 return true;
376 }
377 default:
378 return false;
379 }
380}
381
386 Other.getOpcode() == TargetOpcode::G_SEXT_INREG);
387
389 unsigned OtherWidth = Other.getOperand(2).getImm();
390
392 Register OtherDst = Other.getOperand(0).getReg();
394
395 if (RootWidth >= OtherWidth) {
396
397
399 return false;
400
403 MRI.replaceRegWith(Dst, OtherDst);
404 Observer.finishedChangingAllUsesOfReg();
405 };
406 } else {
407
408
410 B.buildSExtInReg(Dst, Src, RootWidth);
411 };
412 }
413
414 return true;
415}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
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...
Interface for Targets to specify which operations they can successfully select and how the others sho...
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
const SmallVectorImpl< MachineOperand > & Cond
The Input class is used to parse a yaml document into in-memory structs and vectors.
Class for arbitrary precision integers.
bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine zext of trunc.
Definition CombinerHelperCasts.cpp:81
bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine zext nneg to sext.
Definition CombinerHelperCasts.cpp:116
const TargetLowering & getTargetLowering() const
bool matchSextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const
Combine sext of trunc.
Definition CombinerHelperCasts.cpp:28
bool matchTruncateOfExt(const MachineInstr &Root, const MachineInstr &ExtMI, BuildFnTy &MatchInfo) const
Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).
Definition CombinerHelperCasts.cpp:137
bool matchExtOfExt(const MachineInstr &FirstMI, const MachineInstr &SecondMI, BuildFnTy &MatchInfo) const
Definition CombinerHelperCasts.cpp:232
LLVMContext & getContext() const
bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const
MachineRegisterInfo & MRI
bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const
bool matchNarrowBinop(const MachineInstr &TruncMI, const MachineInstr &BinopMI, BuildFnTy &MatchInfo) const
trunc (binop X, C) --> binop (trunc X, trunc C).
Definition CombinerHelperCasts.cpp:336
GISelChangeObserver & Observer
bool matchRedundantSextInReg(MachineInstr &Root, MachineInstr &Other, BuildFnTy &MatchInfo) const
Definition CombinerHelperCasts.cpp:382
bool matchCastOfBuildVector(const MachineInstr &CastMI, const MachineInstr &BVMI, BuildFnTy &MatchInfo) const
Definition CombinerHelperCasts.cpp:296
bool matchCastOfInteger(const MachineInstr &CastMI, APInt &MatchInfo) const
Definition CombinerHelperCasts.cpp:361
bool matchCastOfSelect(const MachineInstr &Cast, const MachineInstr &SelectMI, BuildFnTy &MatchInfo) const
Definition CombinerHelperCasts.cpp:200
Represents a binary operation, i.e, x = y op z.
Register getLHSReg() const
Register getRHSReg() const
Represents a G_BUILD_VECTOR.
Register getSrcReg() const
Represents an integer-like extending operation.
Represents an integer-like extending or truncating operation.
unsigned getNumSources() const
Returns the number of source registers.
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr unsigned getScalarSizeInBits() const
constexpr LLT getScalarType() const
This is an important class for using LLVM in a threaded context.
Helper class to build MachineInstr.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
This is an optimization pass for GlobalISel generic memory operations.
std::function< void(MachineIRBuilder &)> BuildFnTy
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
LLVM_ABI const APInt & getIConstantFromReg(Register VReg, const MachineRegisterInfo &MRI)
VReg is defined by a G_CONSTANT, return the corresponding value.
LLVM_ABI bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.