Bug Summary

File:llvm/include/llvm/CodeGen/SelectionDAGNodes.h
Warning:line 1114, column 10
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name AArch64ISelDAGToDAG.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/AArch64 -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/AArch64 -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64 -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/lib/llvm-13/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/AArch64 -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-04-14-063029-18377-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

1//===-- AArch64ISelDAGToDAG.cpp - A dag to dag inst selector for AArch64 --===//
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 file defines an instruction selector for the AArch64 target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "AArch64MachineFunctionInfo.h"
14#include "AArch64TargetMachine.h"
15#include "MCTargetDesc/AArch64AddressingModes.h"
16#include "llvm/ADT/APSInt.h"
17#include "llvm/CodeGen/SelectionDAGISel.h"
18#include "llvm/IR/Function.h" // To access function attributes.
19#include "llvm/IR/GlobalValue.h"
20#include "llvm/IR/Intrinsics.h"
21#include "llvm/IR/IntrinsicsAArch64.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/KnownBits.h"
25#include "llvm/Support/MathExtras.h"
26#include "llvm/Support/raw_ostream.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE"aarch64-isel" "aarch64-isel"
31
32//===--------------------------------------------------------------------===//
33/// AArch64DAGToDAGISel - AArch64 specific code to select AArch64 machine
34/// instructions for SelectionDAG operations.
35///
36namespace {
37
38class AArch64DAGToDAGISel : public SelectionDAGISel {
39
40 /// Subtarget - Keep a pointer to the AArch64Subtarget around so that we can
41 /// make the right decision when generating code for different targets.
42 const AArch64Subtarget *Subtarget;
43
44public:
45 explicit AArch64DAGToDAGISel(AArch64TargetMachine &tm,
46 CodeGenOpt::Level OptLevel)
47 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr) {}
48
49 StringRef getPassName() const override {
50 return "AArch64 Instruction Selection";
51 }
52
53 bool runOnMachineFunction(MachineFunction &MF) override {
54 Subtarget = &MF.getSubtarget<AArch64Subtarget>();
55 return SelectionDAGISel::runOnMachineFunction(MF);
56 }
57
58 void Select(SDNode *Node) override;
59
60 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
61 /// inline asm expressions.
62 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
63 unsigned ConstraintID,
64 std::vector<SDValue> &OutOps) override;
65
66 template <signed Low, signed High, signed Scale>
67 bool SelectRDVLImm(SDValue N, SDValue &Imm);
68
69 bool tryMLAV64LaneV128(SDNode *N);
70 bool tryMULLV64LaneV128(unsigned IntNo, SDNode *N);
71 bool SelectArithExtendedRegister(SDValue N, SDValue &Reg, SDValue &Shift);
72 bool SelectArithImmed(SDValue N, SDValue &Val, SDValue &Shift);
73 bool SelectNegArithImmed(SDValue N, SDValue &Val, SDValue &Shift);
74 bool SelectArithShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) {
75 return SelectShiftedRegister(N, false, Reg, Shift);
76 }
77 bool SelectLogicalShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) {
78 return SelectShiftedRegister(N, true, Reg, Shift);
79 }
80 bool SelectAddrModeIndexed7S8(SDValue N, SDValue &Base, SDValue &OffImm) {
81 return SelectAddrModeIndexed7S(N, 1, Base, OffImm);
82 }
83 bool SelectAddrModeIndexed7S16(SDValue N, SDValue &Base, SDValue &OffImm) {
84 return SelectAddrModeIndexed7S(N, 2, Base, OffImm);
85 }
86 bool SelectAddrModeIndexed7S32(SDValue N, SDValue &Base, SDValue &OffImm) {
87 return SelectAddrModeIndexed7S(N, 4, Base, OffImm);
88 }
89 bool SelectAddrModeIndexed7S64(SDValue N, SDValue &Base, SDValue &OffImm) {
90 return SelectAddrModeIndexed7S(N, 8, Base, OffImm);
91 }
92 bool SelectAddrModeIndexed7S128(SDValue N, SDValue &Base, SDValue &OffImm) {
93 return SelectAddrModeIndexed7S(N, 16, Base, OffImm);
94 }
95 bool SelectAddrModeIndexedS9S128(SDValue N, SDValue &Base, SDValue &OffImm) {
96 return SelectAddrModeIndexedBitWidth(N, true, 9, 16, Base, OffImm);
97 }
98 bool SelectAddrModeIndexedU6S128(SDValue N, SDValue &Base, SDValue &OffImm) {
99 return SelectAddrModeIndexedBitWidth(N, false, 6, 16, Base, OffImm);
100 }
101 bool SelectAddrModeIndexed8(SDValue N, SDValue &Base, SDValue &OffImm) {
102 return SelectAddrModeIndexed(N, 1, Base, OffImm);
103 }
104 bool SelectAddrModeIndexed16(SDValue N, SDValue &Base, SDValue &OffImm) {
105 return SelectAddrModeIndexed(N, 2, Base, OffImm);
106 }
107 bool SelectAddrModeIndexed32(SDValue N, SDValue &Base, SDValue &OffImm) {
108 return SelectAddrModeIndexed(N, 4, Base, OffImm);
109 }
110 bool SelectAddrModeIndexed64(SDValue N, SDValue &Base, SDValue &OffImm) {
111 return SelectAddrModeIndexed(N, 8, Base, OffImm);
112 }
113 bool SelectAddrModeIndexed128(SDValue N, SDValue &Base, SDValue &OffImm) {
114 return SelectAddrModeIndexed(N, 16, Base, OffImm);
115 }
116 bool SelectAddrModeUnscaled8(SDValue N, SDValue &Base, SDValue &OffImm) {
117 return SelectAddrModeUnscaled(N, 1, Base, OffImm);
118 }
119 bool SelectAddrModeUnscaled16(SDValue N, SDValue &Base, SDValue &OffImm) {
120 return SelectAddrModeUnscaled(N, 2, Base, OffImm);
121 }
122 bool SelectAddrModeUnscaled32(SDValue N, SDValue &Base, SDValue &OffImm) {
123 return SelectAddrModeUnscaled(N, 4, Base, OffImm);
124 }
125 bool SelectAddrModeUnscaled64(SDValue N, SDValue &Base, SDValue &OffImm) {
126 return SelectAddrModeUnscaled(N, 8, Base, OffImm);
127 }
128 bool SelectAddrModeUnscaled128(SDValue N, SDValue &Base, SDValue &OffImm) {
129 return SelectAddrModeUnscaled(N, 16, Base, OffImm);
130 }
131
132 template<int Width>
133 bool SelectAddrModeWRO(SDValue N, SDValue &Base, SDValue &Offset,
134 SDValue &SignExtend, SDValue &DoShift) {
135 return SelectAddrModeWRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
136 }
137
138 template<int Width>
139 bool SelectAddrModeXRO(SDValue N, SDValue &Base, SDValue &Offset,
140 SDValue &SignExtend, SDValue &DoShift) {
141 return SelectAddrModeXRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
142 }
143
144 bool SelectDupZeroOrUndef(SDValue N) {
145 switch(N->getOpcode()) {
146 case ISD::UNDEF:
147 return true;
148 case AArch64ISD::DUP:
149 case ISD::SPLAT_VECTOR: {
150 auto Opnd0 = N->getOperand(0);
151 if (auto CN = dyn_cast<ConstantSDNode>(Opnd0))
152 if (CN->isNullValue())
153 return true;
154 if (auto CN = dyn_cast<ConstantFPSDNode>(Opnd0))
155 if (CN->isZero())
156 return true;
157 break;
158 }
159 default:
160 break;
161 }
162
163 return false;
164 }
165
166 bool SelectDupZero(SDValue N) {
167 switch(N->getOpcode()) {
168 case AArch64ISD::DUP:
169 case ISD::SPLAT_VECTOR: {
170 auto Opnd0 = N->getOperand(0);
171 if (auto CN = dyn_cast<ConstantSDNode>(Opnd0))
172 if (CN->isNullValue())
173 return true;
174 if (auto CN = dyn_cast<ConstantFPSDNode>(Opnd0))
175 if (CN->isZero())
176 return true;
177 break;
178 }
179 }
180
181 return false;
182 }
183
184 template<MVT::SimpleValueType VT>
185 bool SelectSVEAddSubImm(SDValue N, SDValue &Imm, SDValue &Shift) {
186 return SelectSVEAddSubImm(N, VT, Imm, Shift);
187 }
188
189 template<MVT::SimpleValueType VT>
190 bool SelectSVELogicalImm(SDValue N, SDValue &Imm) {
191 return SelectSVELogicalImm(N, VT, Imm);
192 }
193
194 template <MVT::SimpleValueType VT>
195 bool SelectSVEArithImm(SDValue N, SDValue &Imm) {
196 return SelectSVEArithImm(N, VT, Imm);
197 }
198
199 template <unsigned Low, unsigned High, bool AllowSaturation = false>
200 bool SelectSVEShiftImm(SDValue N, SDValue &Imm) {
201 return SelectSVEShiftImm(N, Low, High, AllowSaturation, Imm);
202 }
203
204 // Returns a suitable CNT/INC/DEC/RDVL multiplier to calculate VSCALE*N.
205 template<signed Min, signed Max, signed Scale, bool Shift>
206 bool SelectCntImm(SDValue N, SDValue &Imm) {
207 if (!isa<ConstantSDNode>(N))
208 return false;
209
210 int64_t MulImm = cast<ConstantSDNode>(N)->getSExtValue();
211 if (Shift)
212 MulImm = 1LL << MulImm;
213
214 if ((MulImm % std::abs(Scale)) != 0)
215 return false;
216
217 MulImm /= Scale;
218 if ((MulImm >= Min) && (MulImm <= Max)) {
219 Imm = CurDAG->getTargetConstant(MulImm, SDLoc(N), MVT::i32);
220 return true;
221 }
222
223 return false;
224 }
225
226 /// Form sequences of consecutive 64/128-bit registers for use in NEON
227 /// instructions making use of a vector-list (e.g. ldN, tbl). Vecs must have
228 /// between 1 and 4 elements. If it contains a single element that is returned
229 /// unchanged; otherwise a REG_SEQUENCE value is returned.
230 SDValue createDTuple(ArrayRef<SDValue> Vecs);
231 SDValue createQTuple(ArrayRef<SDValue> Vecs);
232 // Form a sequence of SVE registers for instructions using list of vectors,
233 // e.g. structured loads and stores (ldN, stN).
234 SDValue createZTuple(ArrayRef<SDValue> Vecs);
235
236 /// Generic helper for the createDTuple/createQTuple
237 /// functions. Those should almost always be called instead.
238 SDValue createTuple(ArrayRef<SDValue> Vecs, const unsigned RegClassIDs[],
239 const unsigned SubRegs[]);
240
241 void SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc, bool isExt);
242
243 bool tryIndexedLoad(SDNode *N);
244
245 bool trySelectStackSlotTagP(SDNode *N);
246 void SelectTagP(SDNode *N);
247
248 void SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
249 unsigned SubRegIdx);
250 void SelectPostLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
251 unsigned SubRegIdx);
252 void SelectLoadLane(SDNode *N, unsigned NumVecs, unsigned Opc);
253 void SelectPostLoadLane(SDNode *N, unsigned NumVecs, unsigned Opc);
254 void SelectPredicatedLoad(SDNode *N, unsigned NumVecs, unsigned Scale,
255 unsigned Opc_rr, unsigned Opc_ri);
256
257 bool SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base, SDValue &OffImm);
258 /// SVE Reg+Imm addressing mode.
259 template <int64_t Min, int64_t Max>
260 bool SelectAddrModeIndexedSVE(SDNode *Root, SDValue N, SDValue &Base,
261 SDValue &OffImm);
262 /// SVE Reg+Reg address mode.
263 template <unsigned Scale>
264 bool SelectSVERegRegAddrMode(SDValue N, SDValue &Base, SDValue &Offset) {
265 return SelectSVERegRegAddrMode(N, Scale, Base, Offset);
266 }
267
268 void SelectStore(SDNode *N, unsigned NumVecs, unsigned Opc);
269 void SelectPostStore(SDNode *N, unsigned NumVecs, unsigned Opc);
270 void SelectStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc);
271 void SelectPostStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc);
272 void SelectPredicatedStore(SDNode *N, unsigned NumVecs, unsigned Scale,
273 unsigned Opc_rr, unsigned Opc_ri);
274 std::tuple<unsigned, SDValue, SDValue>
275 findAddrModeSVELoadStore(SDNode *N, unsigned Opc_rr, unsigned Opc_ri,
276 const SDValue &OldBase, const SDValue &OldOffset,
277 unsigned Scale);
278
279 bool tryBitfieldExtractOp(SDNode *N);
280 bool tryBitfieldExtractOpFromSExt(SDNode *N);
281 bool tryBitfieldInsertOp(SDNode *N);
282 bool tryBitfieldInsertInZeroOp(SDNode *N);
283 bool tryShiftAmountMod(SDNode *N);
284 bool tryHighFPExt(SDNode *N);
285
286 bool tryReadRegister(SDNode *N);
287 bool tryWriteRegister(SDNode *N);
288
289// Include the pieces autogenerated from the target description.
290#include "AArch64GenDAGISel.inc"
291
292private:
293 bool SelectShiftedRegister(SDValue N, bool AllowROR, SDValue &Reg,
294 SDValue &Shift);
295 bool SelectAddrModeIndexed7S(SDValue N, unsigned Size, SDValue &Base,
296 SDValue &OffImm) {
297 return SelectAddrModeIndexedBitWidth(N, true, 7, Size, Base, OffImm);
298 }
299 bool SelectAddrModeIndexedBitWidth(SDValue N, bool IsSignedImm, unsigned BW,
300 unsigned Size, SDValue &Base,
301 SDValue &OffImm);
302 bool SelectAddrModeIndexed(SDValue N, unsigned Size, SDValue &Base,
303 SDValue &OffImm);
304 bool SelectAddrModeUnscaled(SDValue N, unsigned Size, SDValue &Base,
305 SDValue &OffImm);
306 bool SelectAddrModeWRO(SDValue N, unsigned Size, SDValue &Base,
307 SDValue &Offset, SDValue &SignExtend,
308 SDValue &DoShift);
309 bool SelectAddrModeXRO(SDValue N, unsigned Size, SDValue &Base,
310 SDValue &Offset, SDValue &SignExtend,
311 SDValue &DoShift);
312 bool isWorthFolding(SDValue V) const;
313 bool SelectExtendedSHL(SDValue N, unsigned Size, bool WantExtend,
314 SDValue &Offset, SDValue &SignExtend);
315
316 template<unsigned RegWidth>
317 bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos) {
318 return SelectCVTFixedPosOperand(N, FixedPos, RegWidth);
319 }
320
321 bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos, unsigned Width);
322
323 bool SelectCMP_SWAP(SDNode *N);
324
325 bool SelectSVE8BitLslImm(SDValue N, SDValue &Imm, SDValue &Shift);
326
327 bool SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift);
328
329 bool SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm);
330
331 bool SelectSVESignedArithImm(SDValue N, SDValue &Imm);
332 bool SelectSVEShiftImm(SDValue N, uint64_t Low, uint64_t High,
333 bool AllowSaturation, SDValue &Imm);
334
335 bool SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm);
336 bool SelectSVERegRegAddrMode(SDValue N, unsigned Scale, SDValue &Base,
337 SDValue &Offset);
338};
339} // end anonymous namespace
340
341/// isIntImmediate - This method tests to see if the node is a constant
342/// operand. If so Imm will receive the 32-bit value.
343static bool isIntImmediate(const SDNode *N, uint64_t &Imm) {
344 if (const ConstantSDNode *C = dyn_cast<const ConstantSDNode>(N)) {
345 Imm = C->getZExtValue();
346 return true;
347 }
348 return false;
349}
350
351// isIntImmediate - This method tests to see if a constant operand.
352// If so Imm will receive the value.
353static bool isIntImmediate(SDValue N, uint64_t &Imm) {
354 return isIntImmediate(N.getNode(), Imm);
355}
356
357// isOpcWithIntImmediate - This method tests to see if the node is a specific
358// opcode and that it has a immediate integer right operand.
359// If so Imm will receive the 32 bit value.
360static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc,
361 uint64_t &Imm) {
362 return N->getOpcode() == Opc &&
363 isIntImmediate(N->getOperand(1).getNode(), Imm);
364}
365
366bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
367 const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
368 switch(ConstraintID) {
369 default:
370 llvm_unreachable("Unexpected asm memory constraint")::llvm::llvm_unreachable_internal("Unexpected asm memory constraint"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 370)
;
371 case InlineAsm::Constraint_m:
372 case InlineAsm::Constraint_Q:
373 // We need to make sure that this one operand does not end up in XZR, thus
374 // require the address to be in a PointerRegClass register.
375 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
376 const TargetRegisterClass *TRC = TRI->getPointerRegClass(*MF);
377 SDLoc dl(Op);
378 SDValue RC = CurDAG->getTargetConstant(TRC->getID(), dl, MVT::i64);
379 SDValue NewOp =
380 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
381 dl, Op.getValueType(),
382 Op, RC), 0);
383 OutOps.push_back(NewOp);
384 return false;
385 }
386 return true;
387}
388
389/// SelectArithImmed - Select an immediate value that can be represented as
390/// a 12-bit value shifted left by either 0 or 12. If so, return true with
391/// Val set to the 12-bit value and Shift set to the shifter operand.
392bool AArch64DAGToDAGISel::SelectArithImmed(SDValue N, SDValue &Val,
393 SDValue &Shift) {
394 // This function is called from the addsub_shifted_imm ComplexPattern,
395 // which lists [imm] as the list of opcode it's interested in, however
396 // we still need to check whether the operand is actually an immediate
397 // here because the ComplexPattern opcode list is only used in
398 // root-level opcode matching.
399 if (!isa<ConstantSDNode>(N.getNode()))
400 return false;
401
402 uint64_t Immed = cast<ConstantSDNode>(N.getNode())->getZExtValue();
403 unsigned ShiftAmt;
404
405 if (Immed >> 12 == 0) {
406 ShiftAmt = 0;
407 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
408 ShiftAmt = 12;
409 Immed = Immed >> 12;
410 } else
411 return false;
412
413 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt);
414 SDLoc dl(N);
415 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
416 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
417 return true;
418}
419
420/// SelectNegArithImmed - As above, but negates the value before trying to
421/// select it.
422bool AArch64DAGToDAGISel::SelectNegArithImmed(SDValue N, SDValue &Val,
423 SDValue &Shift) {
424 // This function is called from the addsub_shifted_imm ComplexPattern,
425 // which lists [imm] as the list of opcode it's interested in, however
426 // we still need to check whether the operand is actually an immediate
427 // here because the ComplexPattern opcode list is only used in
428 // root-level opcode matching.
429 if (!isa<ConstantSDNode>(N.getNode()))
430 return false;
431
432 // The immediate operand must be a 24-bit zero-extended immediate.
433 uint64_t Immed = cast<ConstantSDNode>(N.getNode())->getZExtValue();
434
435 // This negation is almost always valid, but "cmp wN, #0" and "cmn wN, #0"
436 // have the opposite effect on the C flag, so this pattern mustn't match under
437 // those circumstances.
438 if (Immed == 0)
439 return false;
440
441 if (N.getValueType() == MVT::i32)
442 Immed = ~((uint32_t)Immed) + 1;
443 else
444 Immed = ~Immed + 1ULL;
445 if (Immed & 0xFFFFFFFFFF000000ULL)
446 return false;
447
448 Immed &= 0xFFFFFFULL;
449 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(N), MVT::i32), Val,
450 Shift);
451}
452
453/// getShiftTypeForNode - Translate a shift node to the corresponding
454/// ShiftType value.
455static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N) {
456 switch (N.getOpcode()) {
457 default:
458 return AArch64_AM::InvalidShiftExtend;
459 case ISD::SHL:
460 return AArch64_AM::LSL;
461 case ISD::SRL:
462 return AArch64_AM::LSR;
463 case ISD::SRA:
464 return AArch64_AM::ASR;
465 case ISD::ROTR:
466 return AArch64_AM::ROR;
467 }
468}
469
470/// Determine whether it is worth it to fold SHL into the addressing
471/// mode.
472static bool isWorthFoldingSHL(SDValue V) {
473 assert(V.getOpcode() == ISD::SHL && "invalid opcode")((V.getOpcode() == ISD::SHL && "invalid opcode") ? static_cast
<void> (0) : __assert_fail ("V.getOpcode() == ISD::SHL && \"invalid opcode\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 473, __PRETTY_FUNCTION__))
;
474 // It is worth folding logical shift of up to three places.
475 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1));
476 if (!CSD)
477 return false;
478 unsigned ShiftVal = CSD->getZExtValue();
479 if (ShiftVal > 3)
480 return false;
481
482 // Check if this particular node is reused in any non-memory related
483 // operation. If yes, do not try to fold this node into the address
484 // computation, since the computation will be kept.
485 const SDNode *Node = V.getNode();
486 for (SDNode *UI : Node->uses())
487 if (!isa<MemSDNode>(*UI))
488 for (SDNode *UII : UI->uses())
489 if (!isa<MemSDNode>(*UII))
490 return false;
491 return true;
492}
493
494/// Determine whether it is worth to fold V into an extended register.
495bool AArch64DAGToDAGISel::isWorthFolding(SDValue V) const {
496 // Trivial if we are optimizing for code size or if there is only
497 // one use of the value.
498 if (CurDAG->shouldOptForSize() || V.hasOneUse())
499 return true;
500 // If a subtarget has a fastpath LSL we can fold a logical shift into
501 // the addressing mode and save a cycle.
502 if (Subtarget->hasLSLFast() && V.getOpcode() == ISD::SHL &&
503 isWorthFoldingSHL(V))
504 return true;
505 if (Subtarget->hasLSLFast() && V.getOpcode() == ISD::ADD) {
506 const SDValue LHS = V.getOperand(0);
507 const SDValue RHS = V.getOperand(1);
508 if (LHS.getOpcode() == ISD::SHL && isWorthFoldingSHL(LHS))
509 return true;
510 if (RHS.getOpcode() == ISD::SHL && isWorthFoldingSHL(RHS))
511 return true;
512 }
513
514 // It hurts otherwise, since the value will be reused.
515 return false;
516}
517
518/// SelectShiftedRegister - Select a "shifted register" operand. If the value
519/// is not shifted, set the Shift operand to default of "LSL 0". The logical
520/// instructions allow the shifted register to be rotated, but the arithmetic
521/// instructions do not. The AllowROR parameter specifies whether ROR is
522/// supported.
523bool AArch64DAGToDAGISel::SelectShiftedRegister(SDValue N, bool AllowROR,
524 SDValue &Reg, SDValue &Shift) {
525 AArch64_AM::ShiftExtendType ShType = getShiftTypeForNode(N);
526 if (ShType == AArch64_AM::InvalidShiftExtend)
527 return false;
528 if (!AllowROR && ShType == AArch64_AM::ROR)
529 return false;
530
531 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
532 unsigned BitSize = N.getValueSizeInBits();
533 unsigned Val = RHS->getZExtValue() & (BitSize - 1);
534 unsigned ShVal = AArch64_AM::getShifterImm(ShType, Val);
535
536 Reg = N.getOperand(0);
537 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(N), MVT::i32);
538 return isWorthFolding(N);
539 }
540
541 return false;
542}
543
544/// getExtendTypeForNode - Translate an extend node to the corresponding
545/// ExtendType value.
546static AArch64_AM::ShiftExtendType
547getExtendTypeForNode(SDValue N, bool IsLoadStore = false) {
548 if (N.getOpcode() == ISD::SIGN_EXTEND ||
549 N.getOpcode() == ISD::SIGN_EXTEND_INREG) {
550 EVT SrcVT;
551 if (N.getOpcode() == ISD::SIGN_EXTEND_INREG)
552 SrcVT = cast<VTSDNode>(N.getOperand(1))->getVT();
553 else
554 SrcVT = N.getOperand(0).getValueType();
555
556 if (!IsLoadStore && SrcVT == MVT::i8)
557 return AArch64_AM::SXTB;
558 else if (!IsLoadStore && SrcVT == MVT::i16)
559 return AArch64_AM::SXTH;
560 else if (SrcVT == MVT::i32)
561 return AArch64_AM::SXTW;
562 assert(SrcVT != MVT::i64 && "extend from 64-bits?")((SrcVT != MVT::i64 && "extend from 64-bits?") ? static_cast
<void> (0) : __assert_fail ("SrcVT != MVT::i64 && \"extend from 64-bits?\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 562, __PRETTY_FUNCTION__))
;
563
564 return AArch64_AM::InvalidShiftExtend;
565 } else if (N.getOpcode() == ISD::ZERO_EXTEND ||
566 N.getOpcode() == ISD::ANY_EXTEND) {
567 EVT SrcVT = N.getOperand(0).getValueType();
568 if (!IsLoadStore && SrcVT == MVT::i8)
569 return AArch64_AM::UXTB;
570 else if (!IsLoadStore && SrcVT == MVT::i16)
571 return AArch64_AM::UXTH;
572 else if (SrcVT == MVT::i32)
573 return AArch64_AM::UXTW;
574 assert(SrcVT != MVT::i64 && "extend from 64-bits?")((SrcVT != MVT::i64 && "extend from 64-bits?") ? static_cast
<void> (0) : __assert_fail ("SrcVT != MVT::i64 && \"extend from 64-bits?\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 574, __PRETTY_FUNCTION__))
;
575
576 return AArch64_AM::InvalidShiftExtend;
577 } else if (N.getOpcode() == ISD::AND) {
578 ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1));
579 if (!CSD)
580 return AArch64_AM::InvalidShiftExtend;
581 uint64_t AndMask = CSD->getZExtValue();
582
583 switch (AndMask) {
584 default:
585 return AArch64_AM::InvalidShiftExtend;
586 case 0xFF:
587 return !IsLoadStore ? AArch64_AM::UXTB : AArch64_AM::InvalidShiftExtend;
588 case 0xFFFF:
589 return !IsLoadStore ? AArch64_AM::UXTH : AArch64_AM::InvalidShiftExtend;
590 case 0xFFFFFFFF:
591 return AArch64_AM::UXTW;
592 }
593 }
594
595 return AArch64_AM::InvalidShiftExtend;
596}
597
598// Helper for SelectMLAV64LaneV128 - Recognize high lane extracts.
599static bool checkHighLaneIndex(SDNode *DL, SDValue &LaneOp, int &LaneIdx) {
600 if (DL->getOpcode() != AArch64ISD::DUPLANE16 &&
601 DL->getOpcode() != AArch64ISD::DUPLANE32)
602 return false;
603
604 SDValue SV = DL->getOperand(0);
605 if (SV.getOpcode() != ISD::INSERT_SUBVECTOR)
606 return false;
607
608 SDValue EV = SV.getOperand(1);
609 if (EV.getOpcode() != ISD::EXTRACT_SUBVECTOR)
610 return false;
611
612 ConstantSDNode *DLidx = cast<ConstantSDNode>(DL->getOperand(1).getNode());
613 ConstantSDNode *EVidx = cast<ConstantSDNode>(EV.getOperand(1).getNode());
614 LaneIdx = DLidx->getSExtValue() + EVidx->getSExtValue();
615 LaneOp = EV.getOperand(0);
616
617 return true;
618}
619
620// Helper for SelectOpcV64LaneV128 - Recognize operations where one operand is a
621// high lane extract.
622static bool checkV64LaneV128(SDValue Op0, SDValue Op1, SDValue &StdOp,
623 SDValue &LaneOp, int &LaneIdx) {
624
625 if (!checkHighLaneIndex(Op0.getNode(), LaneOp, LaneIdx)) {
626 std::swap(Op0, Op1);
627 if (!checkHighLaneIndex(Op0.getNode(), LaneOp, LaneIdx))
628 return false;
629 }
630 StdOp = Op1;
631 return true;
632}
633
634/// SelectMLAV64LaneV128 - AArch64 supports vector MLAs where one multiplicand
635/// is a lane in the upper half of a 128-bit vector. Recognize and select this
636/// so that we don't emit unnecessary lane extracts.
637bool AArch64DAGToDAGISel::tryMLAV64LaneV128(SDNode *N) {
638 SDLoc dl(N);
639 SDValue Op0 = N->getOperand(0);
640 SDValue Op1 = N->getOperand(1);
641 SDValue MLAOp1; // Will hold ordinary multiplicand for MLA.
642 SDValue MLAOp2; // Will hold lane-accessed multiplicand for MLA.
643 int LaneIdx = -1; // Will hold the lane index.
644
645 if (Op1.getOpcode() != ISD::MUL ||
646 !checkV64LaneV128(Op1.getOperand(0), Op1.getOperand(1), MLAOp1, MLAOp2,
647 LaneIdx)) {
648 std::swap(Op0, Op1);
649 if (Op1.getOpcode() != ISD::MUL ||
650 !checkV64LaneV128(Op1.getOperand(0), Op1.getOperand(1), MLAOp1, MLAOp2,
651 LaneIdx))
652 return false;
653 }
654
655 SDValue LaneIdxVal = CurDAG->getTargetConstant(LaneIdx, dl, MVT::i64);
656
657 SDValue Ops[] = { Op0, MLAOp1, MLAOp2, LaneIdxVal };
658
659 unsigned MLAOpc = ~0U;
660
661 switch (N->getSimpleValueType(0).SimpleTy) {
662 default:
663 llvm_unreachable("Unrecognized MLA.")::llvm::llvm_unreachable_internal("Unrecognized MLA.", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 663)
;
664 case MVT::v4i16:
665 MLAOpc = AArch64::MLAv4i16_indexed;
666 break;
667 case MVT::v8i16:
668 MLAOpc = AArch64::MLAv8i16_indexed;
669 break;
670 case MVT::v2i32:
671 MLAOpc = AArch64::MLAv2i32_indexed;
672 break;
673 case MVT::v4i32:
674 MLAOpc = AArch64::MLAv4i32_indexed;
675 break;
676 }
677
678 ReplaceNode(N, CurDAG->getMachineNode(MLAOpc, dl, N->getValueType(0), Ops));
679 return true;
680}
681
682bool AArch64DAGToDAGISel::tryMULLV64LaneV128(unsigned IntNo, SDNode *N) {
683 SDLoc dl(N);
684 SDValue SMULLOp0;
685 SDValue SMULLOp1;
686 int LaneIdx;
687
688 if (!checkV64LaneV128(N->getOperand(1), N->getOperand(2), SMULLOp0, SMULLOp1,
689 LaneIdx))
690 return false;
691
692 SDValue LaneIdxVal = CurDAG->getTargetConstant(LaneIdx, dl, MVT::i64);
693
694 SDValue Ops[] = { SMULLOp0, SMULLOp1, LaneIdxVal };
695
696 unsigned SMULLOpc = ~0U;
697
698 if (IntNo == Intrinsic::aarch64_neon_smull) {
699 switch (N->getSimpleValueType(0).SimpleTy) {
700 default:
701 llvm_unreachable("Unrecognized SMULL.")::llvm::llvm_unreachable_internal("Unrecognized SMULL.", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 701)
;
702 case MVT::v4i32:
703 SMULLOpc = AArch64::SMULLv4i16_indexed;
704 break;
705 case MVT::v2i64:
706 SMULLOpc = AArch64::SMULLv2i32_indexed;
707 break;
708 }
709 } else if (IntNo == Intrinsic::aarch64_neon_umull) {
710 switch (N->getSimpleValueType(0).SimpleTy) {
711 default:
712 llvm_unreachable("Unrecognized SMULL.")::llvm::llvm_unreachable_internal("Unrecognized SMULL.", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 712)
;
713 case MVT::v4i32:
714 SMULLOpc = AArch64::UMULLv4i16_indexed;
715 break;
716 case MVT::v2i64:
717 SMULLOpc = AArch64::UMULLv2i32_indexed;
718 break;
719 }
720 } else
721 llvm_unreachable("Unrecognized intrinsic.")::llvm::llvm_unreachable_internal("Unrecognized intrinsic.", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 721)
;
722
723 ReplaceNode(N, CurDAG->getMachineNode(SMULLOpc, dl, N->getValueType(0), Ops));
724 return true;
725}
726
727/// Instructions that accept extend modifiers like UXTW expect the register
728/// being extended to be a GPR32, but the incoming DAG might be acting on a
729/// GPR64 (either via SEXT_INREG or AND). Extract the appropriate low bits if
730/// this is the case.
731static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N) {
732 if (N.getValueType() == MVT::i32)
733 return N;
734
735 SDLoc dl(N);
736 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
737 MachineSDNode *Node = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
738 dl, MVT::i32, N, SubReg);
739 return SDValue(Node, 0);
740}
741
742// Returns a suitable CNT/INC/DEC/RDVL multiplier to calculate VSCALE*N.
743template<signed Low, signed High, signed Scale>
744bool AArch64DAGToDAGISel::SelectRDVLImm(SDValue N, SDValue &Imm) {
745 if (!isa<ConstantSDNode>(N))
746 return false;
747
748 int64_t MulImm = cast<ConstantSDNode>(N)->getSExtValue();
749 if ((MulImm % std::abs(Scale)) == 0) {
750 int64_t RDVLImm = MulImm / Scale;
751 if ((RDVLImm >= Low) && (RDVLImm <= High)) {
752 Imm = CurDAG->getTargetConstant(RDVLImm, SDLoc(N), MVT::i32);
753 return true;
754 }
755 }
756
757 return false;
758}
759
760/// SelectArithExtendedRegister - Select a "extended register" operand. This
761/// operand folds in an extend followed by an optional left shift.
762bool AArch64DAGToDAGISel::SelectArithExtendedRegister(SDValue N, SDValue &Reg,
763 SDValue &Shift) {
764 unsigned ShiftVal = 0;
765 AArch64_AM::ShiftExtendType Ext;
766
767 if (N.getOpcode() == ISD::SHL) {
768 ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1));
769 if (!CSD)
770 return false;
771 ShiftVal = CSD->getZExtValue();
772 if (ShiftVal > 4)
773 return false;
774
775 Ext = getExtendTypeForNode(N.getOperand(0));
776 if (Ext == AArch64_AM::InvalidShiftExtend)
777 return false;
778
779 Reg = N.getOperand(0).getOperand(0);
780 } else {
781 Ext = getExtendTypeForNode(N);
782 if (Ext == AArch64_AM::InvalidShiftExtend)
783 return false;
784
785 Reg = N.getOperand(0);
786
787 // Don't match if free 32-bit -> 64-bit zext can be used instead.
788 if (Ext == AArch64_AM::UXTW &&
789 Reg->getValueType(0).getSizeInBits() == 32 && isDef32(*Reg.getNode()))
790 return false;
791 }
792
793 // AArch64 mandates that the RHS of the operation must use the smallest
794 // register class that could contain the size being extended from. Thus,
795 // if we're folding a (sext i8), we need the RHS to be a GPR32, even though
796 // there might not be an actual 32-bit value in the program. We can
797 // (harmlessly) synthesize one by injected an EXTRACT_SUBREG here.
798 assert(Ext != AArch64_AM::UXTX && Ext != AArch64_AM::SXTX)((Ext != AArch64_AM::UXTX && Ext != AArch64_AM::SXTX)
? static_cast<void> (0) : __assert_fail ("Ext != AArch64_AM::UXTX && Ext != AArch64_AM::SXTX"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 798, __PRETTY_FUNCTION__))
;
799 Reg = narrowIfNeeded(CurDAG, Reg);
800 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(N),
801 MVT::i32);
802 return isWorthFolding(N);
803}
804
805/// If there's a use of this ADDlow that's not itself a load/store then we'll
806/// need to create a real ADD instruction from it anyway and there's no point in
807/// folding it into the mem op. Theoretically, it shouldn't matter, but there's
808/// a single pseudo-instruction for an ADRP/ADD pair so over-aggressive folding
809/// leads to duplicated ADRP instructions.
810static bool isWorthFoldingADDlow(SDValue N) {
811 for (auto Use : N->uses()) {
812 if (Use->getOpcode() != ISD::LOAD && Use->getOpcode() != ISD::STORE &&
813 Use->getOpcode() != ISD::ATOMIC_LOAD &&
814 Use->getOpcode() != ISD::ATOMIC_STORE)
815 return false;
816
817 // ldar and stlr have much more restrictive addressing modes (just a
818 // register).
819 if (isStrongerThanMonotonic(cast<MemSDNode>(Use)->getOrdering()))
820 return false;
821 }
822
823 return true;
824}
825
826/// SelectAddrModeIndexedBitWidth - Select a "register plus scaled (un)signed BW-bit
827/// immediate" address. The "Size" argument is the size in bytes of the memory
828/// reference, which determines the scale.
829bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(SDValue N, bool IsSignedImm,
830 unsigned BW, unsigned Size,
831 SDValue &Base,
832 SDValue &OffImm) {
833 SDLoc dl(N);
834 const DataLayout &DL = CurDAG->getDataLayout();
835 const TargetLowering *TLI = getTargetLowering();
836 if (N.getOpcode() == ISD::FrameIndex) {
837 int FI = cast<FrameIndexSDNode>(N)->getIndex();
838 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
839 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
840 return true;
841 }
842
843 // As opposed to the (12-bit) Indexed addressing mode below, the 7/9-bit signed
844 // selected here doesn't support labels/immediates, only base+offset.
845 if (CurDAG->isBaseWithConstantOffset(N)) {
846 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
847 if (IsSignedImm) {
848 int64_t RHSC = RHS->getSExtValue();
849 unsigned Scale = Log2_32(Size);
850 int64_t Range = 0x1LL << (BW - 1);
851
852 if ((RHSC & (Size - 1)) == 0 && RHSC >= -(Range << Scale) &&
853 RHSC < (Range << Scale)) {
854 Base = N.getOperand(0);
855 if (Base.getOpcode() == ISD::FrameIndex) {
856 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
857 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
858 }
859 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
860 return true;
861 }
862 } else {
863 // unsigned Immediate
864 uint64_t RHSC = RHS->getZExtValue();
865 unsigned Scale = Log2_32(Size);
866 uint64_t Range = 0x1ULL << BW;
867
868 if ((RHSC & (Size - 1)) == 0 && RHSC < (Range << Scale)) {
869 Base = N.getOperand(0);
870 if (Base.getOpcode() == ISD::FrameIndex) {
871 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
872 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
873 }
874 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
875 return true;
876 }
877 }
878 }
879 }
880 // Base only. The address will be materialized into a register before
881 // the memory is accessed.
882 // add x0, Xbase, #offset
883 // stp x1, x2, [x0]
884 Base = N;
885 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
886 return true;
887}
888
889/// SelectAddrModeIndexed - Select a "register plus scaled unsigned 12-bit
890/// immediate" address. The "Size" argument is the size in bytes of the memory
891/// reference, which determines the scale.
892bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue N, unsigned Size,
893 SDValue &Base, SDValue &OffImm) {
894 SDLoc dl(N);
895 const DataLayout &DL = CurDAG->getDataLayout();
896 const TargetLowering *TLI = getTargetLowering();
897 if (N.getOpcode() == ISD::FrameIndex) {
898 int FI = cast<FrameIndexSDNode>(N)->getIndex();
899 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
900 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
901 return true;
902 }
903
904 if (N.getOpcode() == AArch64ISD::ADDlow && isWorthFoldingADDlow(N)) {
905 GlobalAddressSDNode *GAN =
906 dyn_cast<GlobalAddressSDNode>(N.getOperand(1).getNode());
907 Base = N.getOperand(0);
908 OffImm = N.getOperand(1);
909 if (!GAN)
910 return true;
911
912 if (GAN->getOffset() % Size == 0 &&
913 GAN->getGlobal()->getPointerAlignment(DL) >= Size)
914 return true;
915 }
916
917 if (CurDAG->isBaseWithConstantOffset(N)) {
918 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
919 int64_t RHSC = (int64_t)RHS->getZExtValue();
920 unsigned Scale = Log2_32(Size);
921 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
922 Base = N.getOperand(0);
923 if (Base.getOpcode() == ISD::FrameIndex) {
924 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
925 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
926 }
927 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
928 return true;
929 }
930 }
931 }
932
933 // Before falling back to our general case, check if the unscaled
934 // instructions can handle this. If so, that's preferable.
935 if (SelectAddrModeUnscaled(N, Size, Base, OffImm))
936 return false;
937
938 // Base only. The address will be materialized into a register before
939 // the memory is accessed.
940 // add x0, Xbase, #offset
941 // ldr x0, [x0]
942 Base = N;
943 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
944 return true;
945}
946
947/// SelectAddrModeUnscaled - Select a "register plus unscaled signed 9-bit
948/// immediate" address. This should only match when there is an offset that
949/// is not valid for a scaled immediate addressing mode. The "Size" argument
950/// is the size in bytes of the memory reference, which is needed here to know
951/// what is valid for a scaled immediate.
952bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(SDValue N, unsigned Size,
953 SDValue &Base,
954 SDValue &OffImm) {
955 if (!CurDAG->isBaseWithConstantOffset(N))
956 return false;
957 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
958 int64_t RHSC = RHS->getSExtValue();
959 // If the offset is valid as a scaled immediate, don't match here.
960 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 &&
961 RHSC < (0x1000 << Log2_32(Size)))
962 return false;
963 if (RHSC >= -256 && RHSC < 256) {
964 Base = N.getOperand(0);
965 if (Base.getOpcode() == ISD::FrameIndex) {
966 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
967 const TargetLowering *TLI = getTargetLowering();
968 Base = CurDAG->getTargetFrameIndex(
969 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
970 }
971 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i64);
972 return true;
973 }
974 }
975 return false;
976}
977
978static SDValue Widen(SelectionDAG *CurDAG, SDValue N) {
979 SDLoc dl(N);
980 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
981 SDValue ImpDef = SDValue(
982 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
983 MachineSDNode *Node = CurDAG->getMachineNode(
984 TargetOpcode::INSERT_SUBREG, dl, MVT::i64, ImpDef, N, SubReg);
985 return SDValue(Node, 0);
986}
987
988/// Check if the given SHL node (\p N), can be used to form an
989/// extended register for an addressing mode.
990bool AArch64DAGToDAGISel::SelectExtendedSHL(SDValue N, unsigned Size,
991 bool WantExtend, SDValue &Offset,
992 SDValue &SignExtend) {
993 assert(N.getOpcode() == ISD::SHL && "Invalid opcode.")((N.getOpcode() == ISD::SHL && "Invalid opcode.") ? static_cast
<void> (0) : __assert_fail ("N.getOpcode() == ISD::SHL && \"Invalid opcode.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 993, __PRETTY_FUNCTION__))
;
994 ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1));
995 if (!CSD || (CSD->getZExtValue() & 0x7) != CSD->getZExtValue())
996 return false;
997
998 SDLoc dl(N);
999 if (WantExtend) {
1000 AArch64_AM::ShiftExtendType Ext =
1001 getExtendTypeForNode(N.getOperand(0), true);
1002 if (Ext == AArch64_AM::InvalidShiftExtend)
1003 return false;
1004
1005 Offset = narrowIfNeeded(CurDAG, N.getOperand(0).getOperand(0));
1006 SignExtend = CurDAG->getTargetConstant(Ext == AArch64_AM::SXTW, dl,
1007 MVT::i32);
1008 } else {
1009 Offset = N.getOperand(0);
1010 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1011 }
1012
1013 unsigned LegalShiftVal = Log2_32(Size);
1014 unsigned ShiftVal = CSD->getZExtValue();
1015
1016 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1017 return false;
1018
1019 return isWorthFolding(N);
1020}
1021
1022bool AArch64DAGToDAGISel::SelectAddrModeWRO(SDValue N, unsigned Size,
1023 SDValue &Base, SDValue &Offset,
1024 SDValue &SignExtend,
1025 SDValue &DoShift) {
1026 if (N.getOpcode() != ISD::ADD)
1027 return false;
1028 SDValue LHS = N.getOperand(0);
1029 SDValue RHS = N.getOperand(1);
1030 SDLoc dl(N);
1031
1032 // We don't want to match immediate adds here, because they are better lowered
1033 // to the register-immediate addressing modes.
1034 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
1035 return false;
1036
1037 // Check if this particular node is reused in any non-memory related
1038 // operation. If yes, do not try to fold this node into the address
1039 // computation, since the computation will be kept.
1040 const SDNode *Node = N.getNode();
1041 for (SDNode *UI : Node->uses()) {
1042 if (!isa<MemSDNode>(*UI))
1043 return false;
1044 }
1045
1046 // Remember if it is worth folding N when it produces extended register.
1047 bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
1048
1049 // Try to match a shifted extend on the RHS.
1050 if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL &&
1051 SelectExtendedSHL(RHS, Size, true, Offset, SignExtend)) {
1052 Base = LHS;
1053 DoShift = CurDAG->getTargetConstant(true, dl, MVT::i32);
1054 return true;
1055 }
1056
1057 // Try to match a shifted extend on the LHS.
1058 if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL &&
1059 SelectExtendedSHL(LHS, Size, true, Offset, SignExtend)) {
1060 Base = RHS;
1061 DoShift = CurDAG->getTargetConstant(true, dl, MVT::i32);
1062 return true;
1063 }
1064
1065 // There was no shift, whatever else we find.
1066 DoShift = CurDAG->getTargetConstant(false, dl, MVT::i32);
1067
1068 AArch64_AM::ShiftExtendType Ext = AArch64_AM::InvalidShiftExtend;
1069 // Try to match an unshifted extend on the LHS.
1070 if (IsExtendedRegisterWorthFolding &&
1071 (Ext = getExtendTypeForNode(LHS, true)) !=
1072 AArch64_AM::InvalidShiftExtend) {
1073 Base = RHS;
1074 Offset = narrowIfNeeded(CurDAG, LHS.getOperand(0));
1075 SignExtend = CurDAG->getTargetConstant(Ext == AArch64_AM::SXTW, dl,
1076 MVT::i32);
1077 if (isWorthFolding(LHS))
1078 return true;
1079 }
1080
1081 // Try to match an unshifted extend on the RHS.
1082 if (IsExtendedRegisterWorthFolding &&
1083 (Ext = getExtendTypeForNode(RHS, true)) !=
1084 AArch64_AM::InvalidShiftExtend) {
1085 Base = LHS;
1086 Offset = narrowIfNeeded(CurDAG, RHS.getOperand(0));
1087 SignExtend = CurDAG->getTargetConstant(Ext == AArch64_AM::SXTW, dl,
1088 MVT::i32);
1089 if (isWorthFolding(RHS))
1090 return true;
1091 }
1092
1093 return false;
1094}
1095
1096// Check if the given immediate is preferred by ADD. If an immediate can be
1097// encoded in an ADD, or it can be encoded in an "ADD LSL #12" and can not be
1098// encoded by one MOVZ, return true.
1099static bool isPreferredADD(int64_t ImmOff) {
1100 // Constant in [0x0, 0xfff] can be encoded in ADD.
1101 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1102 return true;
1103 // Check if it can be encoded in an "ADD LSL #12".
1104 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1105 // As a single MOVZ is faster than a "ADD of LSL #12", ignore such constant.
1106 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1107 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1108 return false;
1109}
1110
1111bool AArch64DAGToDAGISel::SelectAddrModeXRO(SDValue N, unsigned Size,
1112 SDValue &Base, SDValue &Offset,
1113 SDValue &SignExtend,
1114 SDValue &DoShift) {
1115 if (N.getOpcode() != ISD::ADD)
1116 return false;
1117 SDValue LHS = N.getOperand(0);
1118 SDValue RHS = N.getOperand(1);
1119 SDLoc DL(N);
1120
1121 // Check if this particular node is reused in any non-memory related
1122 // operation. If yes, do not try to fold this node into the address
1123 // computation, since the computation will be kept.
1124 const SDNode *Node = N.getNode();
1125 for (SDNode *UI : Node->uses()) {
1126 if (!isa<MemSDNode>(*UI))
1127 return false;
1128 }
1129
1130 // Watch out if RHS is a wide immediate, it can not be selected into
1131 // [BaseReg+Imm] addressing mode. Also it may not be able to be encoded into
1132 // ADD/SUB. Instead it will use [BaseReg + 0] address mode and generate
1133 // instructions like:
1134 // MOV X0, WideImmediate
1135 // ADD X1, BaseReg, X0
1136 // LDR X2, [X1, 0]
1137 // For such situation, using [BaseReg, XReg] addressing mode can save one
1138 // ADD/SUB:
1139 // MOV X0, WideImmediate
1140 // LDR X2, [BaseReg, X0]
1141 if (isa<ConstantSDNode>(RHS)) {
1142 int64_t ImmOff = (int64_t)cast<ConstantSDNode>(RHS)->getZExtValue();
1143 unsigned Scale = Log2_32(Size);
1144 // Skip the immediate can be selected by load/store addressing mode.
1145 // Also skip the immediate can be encoded by a single ADD (SUB is also
1146 // checked by using -ImmOff).
1147 if ((ImmOff % Size == 0 && ImmOff >= 0 && ImmOff < (0x1000 << Scale)) ||
1148 isPreferredADD(ImmOff) || isPreferredADD(-ImmOff))
1149 return false;
1150
1151 SDValue Ops[] = { RHS };
1152 SDNode *MOVI =
1153 CurDAG->getMachineNode(AArch64::MOVi64imm, DL, MVT::i64, Ops);
1154 SDValue MOVIV = SDValue(MOVI, 0);
1155 // This ADD of two X register will be selected into [Reg+Reg] mode.
1156 N = CurDAG->getNode(ISD::ADD, DL, MVT::i64, LHS, MOVIV);
1157 }
1158
1159 // Remember if it is worth folding N when it produces extended register.
1160 bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
1161
1162 // Try to match a shifted extend on the RHS.
1163 if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL &&
1164 SelectExtendedSHL(RHS, Size, false, Offset, SignExtend)) {
1165 Base = LHS;
1166 DoShift = CurDAG->getTargetConstant(true, DL, MVT::i32);
1167 return true;
1168 }
1169
1170 // Try to match a shifted extend on the LHS.
1171 if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL &&
1172 SelectExtendedSHL(LHS, Size, false, Offset, SignExtend)) {
1173 Base = RHS;
1174 DoShift = CurDAG->getTargetConstant(true, DL, MVT::i32);
1175 return true;
1176 }
1177
1178 // Match any non-shifted, non-extend, non-immediate add expression.
1179 Base = LHS;
1180 Offset = RHS;
1181 SignExtend = CurDAG->getTargetConstant(false, DL, MVT::i32);
1182 DoShift = CurDAG->getTargetConstant(false, DL, MVT::i32);
1183 // Reg1 + Reg2 is free: no check needed.
1184 return true;
1185}
1186
1187SDValue AArch64DAGToDAGISel::createDTuple(ArrayRef<SDValue> Regs) {
1188 static const unsigned RegClassIDs[] = {
1189 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1190 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1191 AArch64::dsub2, AArch64::dsub3};
1192
1193 return createTuple(Regs, RegClassIDs, SubRegs);
1194}
1195
1196SDValue AArch64DAGToDAGISel::createQTuple(ArrayRef<SDValue> Regs) {
1197 static const unsigned RegClassIDs[] = {
1198 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1199 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1200 AArch64::qsub2, AArch64::qsub3};
1201
1202 return createTuple(Regs, RegClassIDs, SubRegs);
1203}
1204
1205SDValue AArch64DAGToDAGISel::createZTuple(ArrayRef<SDValue> Regs) {
1206 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1207 AArch64::ZPR3RegClassID,
1208 AArch64::ZPR4RegClassID};
1209 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1210 AArch64::zsub2, AArch64::zsub3};
1211
1212 return createTuple(Regs, RegClassIDs, SubRegs);
1213}
1214
1215SDValue AArch64DAGToDAGISel::createTuple(ArrayRef<SDValue> Regs,
1216 const unsigned RegClassIDs[],
1217 const unsigned SubRegs[]) {
1218 // There's no special register-class for a vector-list of 1 element: it's just
1219 // a vector.
1220 if (Regs.size() == 1)
1221 return Regs[0];
1222
1223 assert(Regs.size() >= 2 && Regs.size() <= 4)((Regs.size() >= 2 && Regs.size() <= 4) ? static_cast
<void> (0) : __assert_fail ("Regs.size() >= 2 && Regs.size() <= 4"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1223, __PRETTY_FUNCTION__))
;
1224
1225 SDLoc DL(Regs[0]);
1226
1227 SmallVector<SDValue, 4> Ops;
1228
1229 // First operand of REG_SEQUENCE is the desired RegClass.
1230 Ops.push_back(
1231 CurDAG->getTargetConstant(RegClassIDs[Regs.size() - 2], DL, MVT::i32));
1232
1233 // Then we get pairs of source & subregister-position for the components.
1234 for (unsigned i = 0; i < Regs.size(); ++i) {
1235 Ops.push_back(Regs[i]);
1236 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i], DL, MVT::i32));
1237 }
1238
1239 SDNode *N =
1240 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::Untyped, Ops);
1241 return SDValue(N, 0);
1242}
1243
1244void AArch64DAGToDAGISel::SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc,
1245 bool isExt) {
1246 SDLoc dl(N);
1247 EVT VT = N->getValueType(0);
1248
1249 unsigned ExtOff = isExt;
1250
1251 // Form a REG_SEQUENCE to force register allocation.
1252 unsigned Vec0Off = ExtOff + 1;
1253 SmallVector<SDValue, 4> Regs(N->op_begin() + Vec0Off,
1254 N->op_begin() + Vec0Off + NumVecs);
1255 SDValue RegSeq = createQTuple(Regs);
1256
1257 SmallVector<SDValue, 6> Ops;
1258 if (isExt)
1259 Ops.push_back(N->getOperand(1));
1260 Ops.push_back(RegSeq);
1261 Ops.push_back(N->getOperand(NumVecs + ExtOff + 1));
1262 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
1263}
1264
1265bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *N) {
1266 LoadSDNode *LD = cast<LoadSDNode>(N);
1267 if (LD->isUnindexed())
1268 return false;
1269 EVT VT = LD->getMemoryVT();
1270 EVT DstVT = N->getValueType(0);
1271 ISD::MemIndexedMode AM = LD->getAddressingMode();
1272 bool IsPre = AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
1273
1274 // We're not doing validity checking here. That was done when checking
1275 // if we should mark the load as indexed or not. We're just selecting
1276 // the right instruction.
1277 unsigned Opcode = 0;
1278
1279 ISD::LoadExtType ExtType = LD->getExtensionType();
1280 bool InsertTo64 = false;
1281 if (VT == MVT::i64)
1282 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1283 else if (VT == MVT::i32) {
1284 if (ExtType == ISD::NON_EXTLOAD)
1285 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1286 else if (ExtType == ISD::SEXTLOAD)
1287 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1288 else {
1289 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1290 InsertTo64 = true;
1291 // The result of the load is only i32. It's the subreg_to_reg that makes
1292 // it into an i64.
1293 DstVT = MVT::i32;
1294 }
1295 } else if (VT == MVT::i16) {
1296 if (ExtType == ISD::SEXTLOAD) {
1297 if (DstVT == MVT::i64)
1298 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1299 else
1300 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1301 } else {
1302 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1303 InsertTo64 = DstVT == MVT::i64;
1304 // The result of the load is only i32. It's the subreg_to_reg that makes
1305 // it into an i64.
1306 DstVT = MVT::i32;
1307 }
1308 } else if (VT == MVT::i8) {
1309 if (ExtType == ISD::SEXTLOAD) {
1310 if (DstVT == MVT::i64)
1311 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1312 else
1313 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1314 } else {
1315 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1316 InsertTo64 = DstVT == MVT::i64;
1317 // The result of the load is only i32. It's the subreg_to_reg that makes
1318 // it into an i64.
1319 DstVT = MVT::i32;
1320 }
1321 } else if (VT == MVT::f16) {
1322 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1323 } else if (VT == MVT::bf16) {
1324 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1325 } else if (VT == MVT::f32) {
1326 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1327 } else if (VT == MVT::f64 || VT.is64BitVector()) {
1328 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1329 } else if (VT.is128BitVector()) {
1330 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1331 } else
1332 return false;
1333 SDValue Chain = LD->getChain();
1334 SDValue Base = LD->getBasePtr();
1335 ConstantSDNode *OffsetOp = cast<ConstantSDNode>(LD->getOffset());
1336 int OffsetVal = (int)OffsetOp->getZExtValue();
1337 SDLoc dl(N);
1338 SDValue Offset = CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1339 SDValue Ops[] = { Base, Offset, Chain };
1340 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1341 MVT::Other, Ops);
1342
1343 // Transfer memoperands.
1344 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
1345 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {MemOp});
1346
1347 // Either way, we're replacing the node, so tell the caller that.
1348 SDValue LoadedVal = SDValue(Res, 1);
1349 if (InsertTo64) {
1350 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1351 LoadedVal =
1352 SDValue(CurDAG->getMachineNode(
1353 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1354 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1355 SubReg),
1356 0);
1357 }
1358
1359 ReplaceUses(SDValue(N, 0), LoadedVal);
1360 ReplaceUses(SDValue(N, 1), SDValue(Res, 0));
1361 ReplaceUses(SDValue(N, 2), SDValue(Res, 2));
1362 CurDAG->RemoveDeadNode(N);
1363 return true;
1364}
1365
1366void AArch64DAGToDAGISel::SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
1367 unsigned SubRegIdx) {
1368 SDLoc dl(N);
1369 EVT VT = N->getValueType(0);
1370 SDValue Chain = N->getOperand(0);
1371
1372 SDValue Ops[] = {N->getOperand(2), // Mem operand;
1373 Chain};
1374
1375 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1376
1377 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1378 SDValue SuperReg = SDValue(Ld, 0);
1379 for (unsigned i = 0; i < NumVecs; ++i)
1380 ReplaceUses(SDValue(N, i),
1381 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1382
1383 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1));
1384
1385 // Transfer memoperands. In the case of AArch64::LD64B, there won't be one,
1386 // because it's too simple to have needed special treatment during lowering.
1387 if (auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(N)) {
1388 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1389 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
1390 }
1391
1392 CurDAG->RemoveDeadNode(N);
1393}
1394
1395void AArch64DAGToDAGISel::SelectPostLoad(SDNode *N, unsigned NumVecs,
1396 unsigned Opc, unsigned SubRegIdx) {
1397 SDLoc dl(N);
1398 EVT VT = N->getValueType(0);
1399 SDValue Chain = N->getOperand(0);
1400
1401 SDValue Ops[] = {N->getOperand(1), // Mem operand
1402 N->getOperand(2), // Incremental
1403 Chain};
1404
1405 const EVT ResTys[] = {MVT::i64, // Type of the write back register
1406 MVT::Untyped, MVT::Other};
1407
1408 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1409
1410 // Update uses of write back register
1411 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 0));
1412
1413 // Update uses of vector list
1414 SDValue SuperReg = SDValue(Ld, 1);
1415 if (NumVecs == 1)
1416 ReplaceUses(SDValue(N, 0), SuperReg);
1417 else
1418 for (unsigned i = 0; i < NumVecs; ++i)
1419 ReplaceUses(SDValue(N, i),
1420 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1421
1422 // Update the chain
1423 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(Ld, 2));
1424 CurDAG->RemoveDeadNode(N);
1425}
1426
1427/// Optimize \param OldBase and \param OldOffset selecting the best addressing
1428/// mode. Returns a tuple consisting of an Opcode, an SDValue representing the
1429/// new Base and an SDValue representing the new offset.
1430std::tuple<unsigned, SDValue, SDValue>
1431AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *N, unsigned Opc_rr,
1432 unsigned Opc_ri,
1433 const SDValue &OldBase,
1434 const SDValue &OldOffset,
1435 unsigned Scale) {
1436 SDValue NewBase = OldBase;
1437 SDValue NewOffset = OldOffset;
1438 // Detect a possible Reg+Imm addressing mode.
1439 const bool IsRegImm = SelectAddrModeIndexedSVE</*Min=*/-8, /*Max=*/7>(
1440 N, OldBase, NewBase, NewOffset);
1441
1442 // Detect a possible reg+reg addressing mode, but only if we haven't already
1443 // detected a Reg+Imm one.
1444 const bool IsRegReg =
1445 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1446
1447 // Select the instruction.
1448 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1449}
1450
1451void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *N, unsigned NumVecs,
1452 unsigned Scale, unsigned Opc_ri,
1453 unsigned Opc_rr) {
1454 assert(Scale < 4 && "Invalid scaling value.")((Scale < 4 && "Invalid scaling value.") ? static_cast
<void> (0) : __assert_fail ("Scale < 4 && \"Invalid scaling value.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1454, __PRETTY_FUNCTION__))
;
1455 SDLoc DL(N);
1456 EVT VT = N->getValueType(0);
1457 SDValue Chain = N->getOperand(0);
1458
1459 // Optimize addressing mode.
1460 SDValue Base, Offset;
1461 unsigned Opc;
1462 std::tie(Opc, Base, Offset) = findAddrModeSVELoadStore(
1463 N, Opc_rr, Opc_ri, N->getOperand(2),
1464 CurDAG->getTargetConstant(0, DL, MVT::i64), Scale);
1465
1466 SDValue Ops[] = {N->getOperand(1), // Predicate
1467 Base, // Memory operand
1468 Offset, Chain};
1469
1470 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1471
1472 SDNode *Load = CurDAG->getMachineNode(Opc, DL, ResTys, Ops);
1473 SDValue SuperReg = SDValue(Load, 0);
1474 for (unsigned i = 0; i < NumVecs; ++i)
1475 ReplaceUses(SDValue(N, i), CurDAG->getTargetExtractSubreg(
1476 AArch64::zsub0 + i, DL, VT, SuperReg));
1477
1478 // Copy chain
1479 unsigned ChainIdx = NumVecs;
1480 ReplaceUses(SDValue(N, ChainIdx), SDValue(Load, 1));
1481 CurDAG->RemoveDeadNode(N);
1482}
1483
1484void AArch64DAGToDAGISel::SelectStore(SDNode *N, unsigned NumVecs,
1485 unsigned Opc) {
1486 SDLoc dl(N);
1487 EVT VT = N->getOperand(2)->getValueType(0);
1488
1489 // Form a REG_SEQUENCE to force register allocation.
1490 bool Is128Bit = VT.getSizeInBits() == 128;
1491 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
1492 SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs);
1493
1494 SDValue Ops[] = {RegSeq, N->getOperand(NumVecs + 2), N->getOperand(0)};
1495 SDNode *St = CurDAG->getMachineNode(Opc, dl, N->getValueType(0), Ops);
1496
1497 // Transfer memoperands.
1498 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();
1499 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
1500
1501 ReplaceNode(N, St);
1502}
1503
1504void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *N, unsigned NumVecs,
1505 unsigned Scale, unsigned Opc_rr,
1506 unsigned Opc_ri) {
1507 SDLoc dl(N);
1508
1509 // Form a REG_SEQUENCE to force register allocation.
1510 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
1511 SDValue RegSeq = createZTuple(Regs);
1512
1513 // Optimize addressing mode.
1514 unsigned Opc;
1515 SDValue Offset, Base;
1516 std::tie(Opc, Base, Offset) = findAddrModeSVELoadStore(
1517 N, Opc_rr, Opc_ri, N->getOperand(NumVecs + 3),
1518 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
1519
1520 SDValue Ops[] = {RegSeq, N->getOperand(NumVecs + 2), // predicate
1521 Base, // address
1522 Offset, // offset
1523 N->getOperand(0)}; // chain
1524 SDNode *St = CurDAG->getMachineNode(Opc, dl, N->getValueType(0), Ops);
1525
1526 ReplaceNode(N, St);
1527}
1528
1529bool AArch64DAGToDAGISel::SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base,
1530 SDValue &OffImm) {
1531 SDLoc dl(N);
1532 const DataLayout &DL = CurDAG->getDataLayout();
1533 const TargetLowering *TLI = getTargetLowering();
1534
1535 // Try to match it for the frame address
1536 if (auto FINode = dyn_cast<FrameIndexSDNode>(N)) {
1537 int FI = FINode->getIndex();
1538 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
1539 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1540 return true;
1541 }
1542
1543 return false;
1544}
1545
1546void AArch64DAGToDAGISel::SelectPostStore(SDNode *N, unsigned NumVecs,
1547 unsigned Opc) {
1548 SDLoc dl(N);
1549 EVT VT = N->getOperand(2)->getValueType(0);
1550 const EVT ResTys[] = {MVT::i64, // Type of the write back register
1551 MVT::Other}; // Type for the Chain
1552
1553 // Form a REG_SEQUENCE to force register allocation.
1554 bool Is128Bit = VT.getSizeInBits() == 128;
1555 SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs);
1556 SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs);
1557
1558 SDValue Ops[] = {RegSeq,
1559 N->getOperand(NumVecs + 1), // base register
1560 N->getOperand(NumVecs + 2), // Incremental
1561 N->getOperand(0)}; // Chain
1562 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1563
1564 ReplaceNode(N, St);
1565}
1566
1567namespace {
1568/// WidenVector - Given a value in the V64 register class, produce the
1569/// equivalent value in the V128 register class.
1570class WidenVector {
1571 SelectionDAG &DAG;
1572
1573public:
1574 WidenVector(SelectionDAG &DAG) : DAG(DAG) {}
1575
1576 SDValue operator()(SDValue V64Reg) {
1577 EVT VT = V64Reg.getValueType();
1578 unsigned NarrowSize = VT.getVectorNumElements();
1579 MVT EltTy = VT.getVectorElementType().getSimpleVT();
1580 MVT WideTy = MVT::getVectorVT(EltTy, 2 * NarrowSize);
1581 SDLoc DL(V64Reg);
1582
1583 SDValue Undef =
1584 SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, WideTy), 0);
1585 return DAG.getTargetInsertSubreg(AArch64::dsub, DL, WideTy, Undef, V64Reg);
1586 }
1587};
1588} // namespace
1589
1590/// NarrowVector - Given a value in the V128 register class, produce the
1591/// equivalent value in the V64 register class.
1592static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG) {
1593 EVT VT = V128Reg.getValueType();
8
Calling 'SDValue::getValueType'
1594 unsigned WideSize = VT.getVectorNumElements();
1595 MVT EltTy = VT.getVectorElementType().getSimpleVT();
1596 MVT NarrowTy = MVT::getVectorVT(EltTy, WideSize / 2);
1597
1598 return DAG.getTargetExtractSubreg(AArch64::dsub, SDLoc(V128Reg), NarrowTy,
1599 V128Reg);
1600}
1601
1602void AArch64DAGToDAGISel::SelectLoadLane(SDNode *N, unsigned NumVecs,
1603 unsigned Opc) {
1604 SDLoc dl(N);
1605 EVT VT = N->getValueType(0);
1606 bool Narrow = VT.getSizeInBits() == 64;
1607
1608 // Form a REG_SEQUENCE to force register allocation.
1609 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
1610
1611 if (Narrow)
1612 transform(Regs, Regs.begin(),
1613 WidenVector(*CurDAG));
1614
1615 SDValue RegSeq = createQTuple(Regs);
1616
1617 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1618
1619 unsigned LaneNo =
1620 cast<ConstantSDNode>(N->getOperand(NumVecs + 2))->getZExtValue();
1621
1622 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
1623 N->getOperand(NumVecs + 3), N->getOperand(0)};
1624 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1625 SDValue SuperReg = SDValue(Ld, 0);
1626
1627 EVT WideVT = RegSeq.getOperand(1)->getValueType(0);
1628 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
1629 AArch64::qsub2, AArch64::qsub3 };
1630 for (unsigned i = 0; i < NumVecs; ++i) {
1631 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
1632 if (Narrow)
1633 NV = NarrowVector(NV, *CurDAG);
1634 ReplaceUses(SDValue(N, i), NV);
1635 }
1636
1637 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1));
1638 CurDAG->RemoveDeadNode(N);
1639}
1640
1641void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *N, unsigned NumVecs,
1642 unsigned Opc) {
1643 SDLoc dl(N);
1644 EVT VT = N->getValueType(0);
1645 bool Narrow = VT.getSizeInBits() == 64;
1
Assuming the condition is true
1646
1647 // Form a REG_SEQUENCE to force register allocation.
1648 SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs);
1649
1650 if (Narrow
1.1
'Narrow' is true
1.1
'Narrow' is true
)
2
Taking true branch
1651 transform(Regs, Regs.begin(),
1652 WidenVector(*CurDAG));
1653
1654 SDValue RegSeq = createQTuple(Regs);
1655
1656 const EVT ResTys[] = {MVT::i64, // Type of the write back register
1657 RegSeq->getValueType(0), MVT::Other};
1658
1659 unsigned LaneNo =
1660 cast<ConstantSDNode>(N->getOperand(NumVecs + 1))->getZExtValue();
1661
1662 SDValue Ops[] = {RegSeq,
1663 CurDAG->getTargetConstant(LaneNo, dl,
1664 MVT::i64), // Lane Number
1665 N->getOperand(NumVecs + 2), // Base register
1666 N->getOperand(NumVecs + 3), // Incremental
1667 N->getOperand(0)};
1668 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1669
1670 // Update uses of the write back register
1671 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 0));
1672
1673 // Update uses of the vector list
1674 SDValue SuperReg = SDValue(Ld, 1);
1675 if (NumVecs == 1) {
3
Assuming 'NumVecs' is equal to 1
4
Taking true branch
1676 ReplaceUses(SDValue(N, 0),
1677 Narrow
4.1
'Narrow' is true
4.1
'Narrow' is true
? NarrowVector(SuperReg, *CurDAG) : SuperReg);
5
'?' condition is true
6
Null pointer value stored to 'V128Reg.Node'
7
Calling 'NarrowVector'
1678 } else {
1679 EVT WideVT = RegSeq.getOperand(1)->getValueType(0);
1680 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
1681 AArch64::qsub2, AArch64::qsub3 };
1682 for (unsigned i = 0; i < NumVecs; ++i) {
1683 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
1684 SuperReg);
1685 if (Narrow)
1686 NV = NarrowVector(NV, *CurDAG);
1687 ReplaceUses(SDValue(N, i), NV);
1688 }
1689 }
1690
1691 // Update the Chain
1692 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(Ld, 2));
1693 CurDAG->RemoveDeadNode(N);
1694}
1695
1696void AArch64DAGToDAGISel::SelectStoreLane(SDNode *N, unsigned NumVecs,
1697 unsigned Opc) {
1698 SDLoc dl(N);
1699 EVT VT = N->getOperand(2)->getValueType(0);
1700 bool Narrow = VT.getSizeInBits() == 64;
1701
1702 // Form a REG_SEQUENCE to force register allocation.
1703 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
1704
1705 if (Narrow)
1706 transform(Regs, Regs.begin(),
1707 WidenVector(*CurDAG));
1708
1709 SDValue RegSeq = createQTuple(Regs);
1710
1711 unsigned LaneNo =
1712 cast<ConstantSDNode>(N->getOperand(NumVecs + 2))->getZExtValue();
1713
1714 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
1715 N->getOperand(NumVecs + 3), N->getOperand(0)};
1716 SDNode *St = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
1717
1718 // Transfer memoperands.
1719 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();
1720 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
1721
1722 ReplaceNode(N, St);
1723}
1724
1725void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *N, unsigned NumVecs,
1726 unsigned Opc) {
1727 SDLoc dl(N);
1728 EVT VT = N->getOperand(2)->getValueType(0);
1729 bool Narrow = VT.getSizeInBits() == 64;
1730
1731 // Form a REG_SEQUENCE to force register allocation.
1732 SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs);
1733
1734 if (Narrow)
1735 transform(Regs, Regs.begin(),
1736 WidenVector(*CurDAG));
1737
1738 SDValue RegSeq = createQTuple(Regs);
1739
1740 const EVT ResTys[] = {MVT::i64, // Type of the write back register
1741 MVT::Other};
1742
1743 unsigned LaneNo =
1744 cast<ConstantSDNode>(N->getOperand(NumVecs + 1))->getZExtValue();
1745
1746 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
1747 N->getOperand(NumVecs + 2), // Base Register
1748 N->getOperand(NumVecs + 3), // Incremental
1749 N->getOperand(0)};
1750 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1751
1752 // Transfer memoperands.
1753 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();
1754 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
1755
1756 ReplaceNode(N, St);
1757}
1758
1759static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N,
1760 unsigned &Opc, SDValue &Opd0,
1761 unsigned &LSB, unsigned &MSB,
1762 unsigned NumberOfIgnoredLowBits,
1763 bool BiggerPattern) {
1764 assert(N->getOpcode() == ISD::AND &&((N->getOpcode() == ISD::AND && "N must be a AND operation to call this function"
) ? static_cast<void> (0) : __assert_fail ("N->getOpcode() == ISD::AND && \"N must be a AND operation to call this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1765, __PRETTY_FUNCTION__))
1765 "N must be a AND operation to call this function")((N->getOpcode() == ISD::AND && "N must be a AND operation to call this function"
) ? static_cast<void> (0) : __assert_fail ("N->getOpcode() == ISD::AND && \"N must be a AND operation to call this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1765, __PRETTY_FUNCTION__))
;
1766
1767 EVT VT = N->getValueType(0);
1768
1769 // Here we can test the type of VT and return false when the type does not
1770 // match, but since it is done prior to that call in the current context
1771 // we turned that into an assert to avoid redundant code.
1772 assert((VT == MVT::i32 || VT == MVT::i64) &&(((VT == MVT::i32 || VT == MVT::i64) && "Type checking must have been done before calling this function"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"Type checking must have been done before calling this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1773, __PRETTY_FUNCTION__))
1773 "Type checking must have been done before calling this function")(((VT == MVT::i32 || VT == MVT::i64) && "Type checking must have been done before calling this function"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"Type checking must have been done before calling this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1773, __PRETTY_FUNCTION__))
;
1774
1775 // FIXME: simplify-demanded-bits in DAGCombine will probably have
1776 // changed the AND node to a 32-bit mask operation. We'll have to
1777 // undo that as part of the transform here if we want to catch all
1778 // the opportunities.
1779 // Currently the NumberOfIgnoredLowBits argument helps to recover
1780 // form these situations when matching bigger pattern (bitfield insert).
1781
1782 // For unsigned extracts, check for a shift right and mask
1783 uint64_t AndImm = 0;
1784 if (!isOpcWithIntImmediate(N, ISD::AND, AndImm))
1785 return false;
1786
1787 const SDNode *Op0 = N->getOperand(0).getNode();
1788
1789 // Because of simplify-demanded-bits in DAGCombine, the mask may have been
1790 // simplified. Try to undo that
1791 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
1792
1793 // The immediate is a mask of the low bits iff imm & (imm+1) == 0
1794 if (AndImm & (AndImm + 1))
1795 return false;
1796
1797 bool ClampMSB = false;
1798 uint64_t SrlImm = 0;
1799 // Handle the SRL + ANY_EXTEND case.
1800 if (VT == MVT::i64 && Op0->getOpcode() == ISD::ANY_EXTEND &&
1801 isOpcWithIntImmediate(Op0->getOperand(0).getNode(), ISD::SRL, SrlImm)) {
1802 // Extend the incoming operand of the SRL to 64-bit.
1803 Opd0 = Widen(CurDAG, Op0->getOperand(0).getOperand(0));
1804 // Make sure to clamp the MSB so that we preserve the semantics of the
1805 // original operations.
1806 ClampMSB = true;
1807 } else if (VT == MVT::i32 && Op0->getOpcode() == ISD::TRUNCATE &&
1808 isOpcWithIntImmediate(Op0->getOperand(0).getNode(), ISD::SRL,
1809 SrlImm)) {
1810 // If the shift result was truncated, we can still combine them.
1811 Opd0 = Op0->getOperand(0).getOperand(0);
1812
1813 // Use the type of SRL node.
1814 VT = Opd0->getValueType(0);
1815 } else if (isOpcWithIntImmediate(Op0, ISD::SRL, SrlImm)) {
1816 Opd0 = Op0->getOperand(0);
1817 } else if (BiggerPattern) {
1818 // Let's pretend a 0 shift right has been performed.
1819 // The resulting code will be at least as good as the original one
1820 // plus it may expose more opportunities for bitfield insert pattern.
1821 // FIXME: Currently we limit this to the bigger pattern, because
1822 // some optimizations expect AND and not UBFM.
1823 Opd0 = N->getOperand(0);
1824 } else
1825 return false;
1826
1827 // Bail out on large immediates. This happens when no proper
1828 // combining/constant folding was performed.
1829 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.getSizeInBits())) {
1830 LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { (dbgs() << N << ": Found large shift immediate, this should not happen\n"
); } } while (false)
1831 (dbgs() << Ndo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { (dbgs() << N << ": Found large shift immediate, this should not happen\n"
); } } while (false)
1832 << ": Found large shift immediate, this should not happen\n"))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { (dbgs() << N << ": Found large shift immediate, this should not happen\n"
); } } while (false)
;
1833 return false;
1834 }
1835
1836 LSB = SrlImm;
1837 MSB = SrlImm + (VT == MVT::i32 ? countTrailingOnes<uint32_t>(AndImm)
1838 : countTrailingOnes<uint64_t>(AndImm)) -
1839 1;
1840 if (ClampMSB)
1841 // Since we're moving the extend before the right shift operation, we need
1842 // to clamp the MSB to make sure we don't shift in undefined bits instead of
1843 // the zeros which would get shifted in with the original right shift
1844 // operation.
1845 MSB = MSB > 31 ? 31 : MSB;
1846
1847 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
1848 return true;
1849}
1850
1851static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc,
1852 SDValue &Opd0, unsigned &Immr,
1853 unsigned &Imms) {
1854 assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG)((N->getOpcode() == ISD::SIGN_EXTEND_INREG) ? static_cast<
void> (0) : __assert_fail ("N->getOpcode() == ISD::SIGN_EXTEND_INREG"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1854, __PRETTY_FUNCTION__))
;
1855
1856 EVT VT = N->getValueType(0);
1857 unsigned BitWidth = VT.getSizeInBits();
1858 assert((VT == MVT::i32 || VT == MVT::i64) &&(((VT == MVT::i32 || VT == MVT::i64) && "Type checking must have been done before calling this function"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"Type checking must have been done before calling this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1859, __PRETTY_FUNCTION__))
1859 "Type checking must have been done before calling this function")(((VT == MVT::i32 || VT == MVT::i64) && "Type checking must have been done before calling this function"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"Type checking must have been done before calling this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1859, __PRETTY_FUNCTION__))
;
1860
1861 SDValue Op = N->getOperand(0);
1862 if (Op->getOpcode() == ISD::TRUNCATE) {
1863 Op = Op->getOperand(0);
1864 VT = Op->getValueType(0);
1865 BitWidth = VT.getSizeInBits();
1866 }
1867
1868 uint64_t ShiftImm;
1869 if (!isOpcWithIntImmediate(Op.getNode(), ISD::SRL, ShiftImm) &&
1870 !isOpcWithIntImmediate(Op.getNode(), ISD::SRA, ShiftImm))
1871 return false;
1872
1873 unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits();
1874 if (ShiftImm + Width > BitWidth)
1875 return false;
1876
1877 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
1878 Opd0 = Op.getOperand(0);
1879 Immr = ShiftImm;
1880 Imms = ShiftImm + Width - 1;
1881 return true;
1882}
1883
1884static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc,
1885 SDValue &Opd0, unsigned &LSB,
1886 unsigned &MSB) {
1887 // We are looking for the following pattern which basically extracts several
1888 // continuous bits from the source value and places it from the LSB of the
1889 // destination value, all other bits of the destination value or set to zero:
1890 //
1891 // Value2 = AND Value, MaskImm
1892 // SRL Value2, ShiftImm
1893 //
1894 // with MaskImm >> ShiftImm to search for the bit width.
1895 //
1896 // This gets selected into a single UBFM:
1897 //
1898 // UBFM Value, ShiftImm, BitWide + SrlImm -1
1899 //
1900
1901 if (N->getOpcode() != ISD::SRL)
1902 return false;
1903
1904 uint64_t AndMask = 0;
1905 if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, AndMask))
1906 return false;
1907
1908 Opd0 = N->getOperand(0).getOperand(0);
1909
1910 uint64_t SrlImm = 0;
1911 if (!isIntImmediate(N->getOperand(1), SrlImm))
1912 return false;
1913
1914 // Check whether we really have several bits extract here.
1915 unsigned BitWide = 64 - countLeadingOnes(~(AndMask >> SrlImm));
1916 if (BitWide && isMask_64(AndMask >> SrlImm)) {
1917 if (N->getValueType(0) == MVT::i32)
1918 Opc = AArch64::UBFMWri;
1919 else
1920 Opc = AArch64::UBFMXri;
1921
1922 LSB = SrlImm;
1923 MSB = BitWide + SrlImm - 1;
1924 return true;
1925 }
1926
1927 return false;
1928}
1929
1930static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0,
1931 unsigned &Immr, unsigned &Imms,
1932 bool BiggerPattern) {
1933 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&(((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::
SRL) && "N must be a SHR/SRA operation to call this function"
) ? static_cast<void> (0) : __assert_fail ("(N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) && \"N must be a SHR/SRA operation to call this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1934, __PRETTY_FUNCTION__))
1934 "N must be a SHR/SRA operation to call this function")(((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::
SRL) && "N must be a SHR/SRA operation to call this function"
) ? static_cast<void> (0) : __assert_fail ("(N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) && \"N must be a SHR/SRA operation to call this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1934, __PRETTY_FUNCTION__))
;
1935
1936 EVT VT = N->getValueType(0);
1937
1938 // Here we can test the type of VT and return false when the type does not
1939 // match, but since it is done prior to that call in the current context
1940 // we turned that into an assert to avoid redundant code.
1941 assert((VT == MVT::i32 || VT == MVT::i64) &&(((VT == MVT::i32 || VT == MVT::i64) && "Type checking must have been done before calling this function"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"Type checking must have been done before calling this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1942, __PRETTY_FUNCTION__))
1942 "Type checking must have been done before calling this function")(((VT == MVT::i32 || VT == MVT::i64) && "Type checking must have been done before calling this function"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"Type checking must have been done before calling this function\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1942, __PRETTY_FUNCTION__))
;
1943
1944 // Check for AND + SRL doing several bits extract.
1945 if (isSeveralBitsExtractOpFromShr(N, Opc, Opd0, Immr, Imms))
1946 return true;
1947
1948 // We're looking for a shift of a shift.
1949 uint64_t ShlImm = 0;
1950 uint64_t TruncBits = 0;
1951 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, ShlImm)) {
1952 Opd0 = N->getOperand(0).getOperand(0);
1953 } else if (VT == MVT::i32 && N->getOpcode() == ISD::SRL &&
1954 N->getOperand(0).getNode()->getOpcode() == ISD::TRUNCATE) {
1955 // We are looking for a shift of truncate. Truncate from i64 to i32 could
1956 // be considered as setting high 32 bits as zero. Our strategy here is to
1957 // always generate 64bit UBFM. This consistency will help the CSE pass
1958 // later find more redundancy.
1959 Opd0 = N->getOperand(0).getOperand(0);
1960 TruncBits = Opd0->getValueType(0).getSizeInBits() - VT.getSizeInBits();
1961 VT = Opd0.getValueType();
1962 assert(VT == MVT::i64 && "the promoted type should be i64")((VT == MVT::i64 && "the promoted type should be i64"
) ? static_cast<void> (0) : __assert_fail ("VT == MVT::i64 && \"the promoted type should be i64\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1962, __PRETTY_FUNCTION__))
;
1963 } else if (BiggerPattern) {
1964 // Let's pretend a 0 shift left has been performed.
1965 // FIXME: Currently we limit this to the bigger pattern case,
1966 // because some optimizations expect AND and not UBFM
1967 Opd0 = N->getOperand(0);
1968 } else
1969 return false;
1970
1971 // Missing combines/constant folding may have left us with strange
1972 // constants.
1973 if (ShlImm >= VT.getSizeInBits()) {
1974 LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { (dbgs() << N << ": Found large shift immediate, this should not happen\n"
); } } while (false)
1975 (dbgs() << Ndo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { (dbgs() << N << ": Found large shift immediate, this should not happen\n"
); } } while (false)
1976 << ": Found large shift immediate, this should not happen\n"))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { (dbgs() << N << ": Found large shift immediate, this should not happen\n"
); } } while (false)
;
1977 return false;
1978 }
1979
1980 uint64_t SrlImm = 0;
1981 if (!isIntImmediate(N->getOperand(1), SrlImm))
1982 return false;
1983
1984 assert(SrlImm > 0 && SrlImm < VT.getSizeInBits() &&((SrlImm > 0 && SrlImm < VT.getSizeInBits() &&
"bad amount in shift node!") ? static_cast<void> (0) :
__assert_fail ("SrlImm > 0 && SrlImm < VT.getSizeInBits() && \"bad amount in shift node!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1985, __PRETTY_FUNCTION__))
1985 "bad amount in shift node!")((SrlImm > 0 && SrlImm < VT.getSizeInBits() &&
"bad amount in shift node!") ? static_cast<void> (0) :
__assert_fail ("SrlImm > 0 && SrlImm < VT.getSizeInBits() && \"bad amount in shift node!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1985, __PRETTY_FUNCTION__))
;
1986 int immr = SrlImm - ShlImm;
1987 Immr = immr < 0 ? immr + VT.getSizeInBits() : immr;
1988 Imms = VT.getSizeInBits() - ShlImm - TruncBits - 1;
1989 // SRA requires a signed extraction
1990 if (VT == MVT::i32)
1991 Opc = N->getOpcode() == ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
1992 else
1993 Opc = N->getOpcode() == ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
1994 return true;
1995}
1996
1997bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *N) {
1998 assert(N->getOpcode() == ISD::SIGN_EXTEND)((N->getOpcode() == ISD::SIGN_EXTEND) ? static_cast<void
> (0) : __assert_fail ("N->getOpcode() == ISD::SIGN_EXTEND"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 1998, __PRETTY_FUNCTION__))
;
1999
2000 EVT VT = N->getValueType(0);
2001 EVT NarrowVT = N->getOperand(0)->getValueType(0);
2002 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2003 return false;
2004
2005 uint64_t ShiftImm;
2006 SDValue Op = N->getOperand(0);
2007 if (!isOpcWithIntImmediate(Op.getNode(), ISD::SRA, ShiftImm))
2008 return false;
2009
2010 SDLoc dl(N);
2011 // Extend the incoming operand of the shift to 64-bits.
2012 SDValue Opd0 = Widen(CurDAG, Op.getOperand(0));
2013 unsigned Immr = ShiftImm;
2014 unsigned Imms = NarrowVT.getSizeInBits() - 1;
2015 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2016 CurDAG->getTargetConstant(Imms, dl, VT)};
2017 CurDAG->SelectNodeTo(N, AArch64::SBFMXri, VT, Ops);
2018 return true;
2019}
2020
2021/// Try to form fcvtl2 instructions from a floating-point extend of a high-half
2022/// extract of a subvector.
2023bool AArch64DAGToDAGISel::tryHighFPExt(SDNode *N) {
2024 assert(N->getOpcode() == ISD::FP_EXTEND)((N->getOpcode() == ISD::FP_EXTEND) ? static_cast<void>
(0) : __assert_fail ("N->getOpcode() == ISD::FP_EXTEND", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2024, __PRETTY_FUNCTION__))
;
2025
2026 // There are 2 forms of fcvtl2 - extend to double or extend to float.
2027 SDValue Extract = N->getOperand(0);
2028 EVT VT = N->getValueType(0);
2029 EVT NarrowVT = Extract.getValueType();
2030 if ((VT != MVT::v2f64 || NarrowVT != MVT::v2f32) &&
2031 (VT != MVT::v4f32 || NarrowVT != MVT::v4f16))
2032 return false;
2033
2034 // Optionally look past a bitcast.
2035 Extract = peekThroughBitcasts(Extract);
2036 if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR)
2037 return false;
2038
2039 // Match extract from start of high half index.
2040 // Example: v8i16 -> v4i16 means the extract must begin at index 4.
2041 unsigned ExtractIndex = Extract.getConstantOperandVal(1);
2042 if (ExtractIndex != Extract.getValueType().getVectorNumElements())
2043 return false;
2044
2045 auto Opcode = VT == MVT::v2f64 ? AArch64::FCVTLv4i32 : AArch64::FCVTLv8i16;
2046 CurDAG->SelectNodeTo(N, Opcode, VT, Extract.getOperand(0));
2047 return true;
2048}
2049
2050static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc,
2051 SDValue &Opd0, unsigned &Immr, unsigned &Imms,
2052 unsigned NumberOfIgnoredLowBits = 0,
2053 bool BiggerPattern = false) {
2054 if (N->getValueType(0) != MVT::i32 && N->getValueType(0) != MVT::i64)
2055 return false;
2056
2057 switch (N->getOpcode()) {
2058 default:
2059 if (!N->isMachineOpcode())
2060 return false;
2061 break;
2062 case ISD::AND:
2063 return isBitfieldExtractOpFromAnd(CurDAG, N, Opc, Opd0, Immr, Imms,
2064 NumberOfIgnoredLowBits, BiggerPattern);
2065 case ISD::SRL:
2066 case ISD::SRA:
2067 return isBitfieldExtractOpFromShr(N, Opc, Opd0, Immr, Imms, BiggerPattern);
2068
2069 case ISD::SIGN_EXTEND_INREG:
2070 return isBitfieldExtractOpFromSExtInReg(N, Opc, Opd0, Immr, Imms);
2071 }
2072
2073 unsigned NOpc = N->getMachineOpcode();
2074 switch (NOpc) {
2075 default:
2076 return false;
2077 case AArch64::SBFMWri:
2078 case AArch64::UBFMWri:
2079 case AArch64::SBFMXri:
2080 case AArch64::UBFMXri:
2081 Opc = NOpc;
2082 Opd0 = N->getOperand(0);
2083 Immr = cast<ConstantSDNode>(N->getOperand(1).getNode())->getZExtValue();
2084 Imms = cast<ConstantSDNode>(N->getOperand(2).getNode())->getZExtValue();
2085 return true;
2086 }
2087 // Unreachable
2088 return false;
2089}
2090
2091bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *N) {
2092 unsigned Opc, Immr, Imms;
2093 SDValue Opd0;
2094 if (!isBitfieldExtractOp(CurDAG, N, Opc, Opd0, Immr, Imms))
2095 return false;
2096
2097 EVT VT = N->getValueType(0);
2098 SDLoc dl(N);
2099
2100 // If the bit extract operation is 64bit but the original type is 32bit, we
2101 // need to add one EXTRACT_SUBREG.
2102 if ((Opc == AArch64::SBFMXri || Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2103 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2104 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2105
2106 SDNode *BFM = CurDAG->getMachineNode(Opc, dl, MVT::i64, Ops64);
2107 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
2108 ReplaceNode(N, CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl,
2109 MVT::i32, SDValue(BFM, 0), SubReg));
2110 return true;
2111 }
2112
2113 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2114 CurDAG->getTargetConstant(Imms, dl, VT)};
2115 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2116 return true;
2117}
2118
2119/// Does DstMask form a complementary pair with the mask provided by
2120/// BitsToBeInserted, suitable for use in a BFI instruction. Roughly speaking,
2121/// this asks whether DstMask zeroes precisely those bits that will be set by
2122/// the other half.
2123static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted,
2124 unsigned NumberOfIgnoredHighBits, EVT VT) {
2125 assert((VT == MVT::i32 || VT == MVT::i64) &&(((VT == MVT::i32 || VT == MVT::i64) && "i32 or i64 mask type expected!"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"i32 or i64 mask type expected!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2126, __PRETTY_FUNCTION__))
2126 "i32 or i64 mask type expected!")(((VT == MVT::i32 || VT == MVT::i64) && "i32 or i64 mask type expected!"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"i32 or i64 mask type expected!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2126, __PRETTY_FUNCTION__))
;
2127 unsigned BitWidth = VT.getSizeInBits() - NumberOfIgnoredHighBits;
2128
2129 APInt SignificantDstMask = APInt(BitWidth, DstMask);
2130 APInt SignificantBitsToBeInserted = BitsToBeInserted.zextOrTrunc(BitWidth);
2131
2132 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2133 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnesValue();
2134}
2135
2136// Look for bits that will be useful for later uses.
2137// A bit is consider useless as soon as it is dropped and never used
2138// before it as been dropped.
2139// E.g., looking for useful bit of x
2140// 1. y = x & 0x7
2141// 2. z = y >> 2
2142// After #1, x useful bits are 0x7, then the useful bits of x, live through
2143// y.
2144// After #2, the useful bits of x are 0x4.
2145// However, if x is used on an unpredicatable instruction, then all its bits
2146// are useful.
2147// E.g.
2148// 1. y = x & 0x7
2149// 2. z = y >> 2
2150// 3. str x, [@x]
2151static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth = 0);
2152
2153static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits,
2154 unsigned Depth) {
2155 uint64_t Imm =
2156 cast<const ConstantSDNode>(Op.getOperand(1).getNode())->getZExtValue();
2157 Imm = AArch64_AM::decodeLogicalImmediate(Imm, UsefulBits.getBitWidth());
2158 UsefulBits &= APInt(UsefulBits.getBitWidth(), Imm);
2159 getUsefulBits(Op, UsefulBits, Depth + 1);
2160}
2161
2162static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits,
2163 uint64_t Imm, uint64_t MSB,
2164 unsigned Depth) {
2165 // inherit the bitwidth value
2166 APInt OpUsefulBits(UsefulBits);
2167 OpUsefulBits = 1;
2168
2169 if (MSB >= Imm) {
2170 OpUsefulBits <<= MSB - Imm + 1;
2171 --OpUsefulBits;
2172 // The interesting part will be in the lower part of the result
2173 getUsefulBits(Op, OpUsefulBits, Depth + 1);
2174 // The interesting part was starting at Imm in the argument
2175 OpUsefulBits <<= Imm;
2176 } else {
2177 OpUsefulBits <<= MSB + 1;
2178 --OpUsefulBits;
2179 // The interesting part will be shifted in the result
2180 OpUsefulBits <<= OpUsefulBits.getBitWidth() - Imm;
2181 getUsefulBits(Op, OpUsefulBits, Depth + 1);
2182 // The interesting part was at zero in the argument
2183 OpUsefulBits.lshrInPlace(OpUsefulBits.getBitWidth() - Imm);
2184 }
2185
2186 UsefulBits &= OpUsefulBits;
2187}
2188
2189static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits,
2190 unsigned Depth) {
2191 uint64_t Imm =
2192 cast<const ConstantSDNode>(Op.getOperand(1).getNode())->getZExtValue();
2193 uint64_t MSB =
2194 cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
2195
2196 getUsefulBitsFromBitfieldMoveOpd(Op, UsefulBits, Imm, MSB, Depth);
2197}
2198
2199static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits,
2200 unsigned Depth) {
2201 uint64_t ShiftTypeAndValue =
2202 cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
2203 APInt Mask(UsefulBits);
2204 Mask.clearAllBits();
2205 Mask.flipAllBits();
2206
2207 if (AArch64_AM::getShiftType(ShiftTypeAndValue) == AArch64_AM::LSL) {
2208 // Shift Left
2209 uint64_t ShiftAmt = AArch64_AM::getShiftValue(ShiftTypeAndValue);
2210 Mask <<= ShiftAmt;
2211 getUsefulBits(Op, Mask, Depth + 1);
2212 Mask.lshrInPlace(ShiftAmt);
2213 } else if (AArch64_AM::getShiftType(ShiftTypeAndValue) == AArch64_AM::LSR) {
2214 // Shift Right
2215 // We do not handle AArch64_AM::ASR, because the sign will change the
2216 // number of useful bits
2217 uint64_t ShiftAmt = AArch64_AM::getShiftValue(ShiftTypeAndValue);
2218 Mask.lshrInPlace(ShiftAmt);
2219 getUsefulBits(Op, Mask, Depth + 1);
2220 Mask <<= ShiftAmt;
2221 } else
2222 return;
2223
2224 UsefulBits &= Mask;
2225}
2226
2227static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits,
2228 unsigned Depth) {
2229 uint64_t Imm =
2230 cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
2231 uint64_t MSB =
2232 cast<const ConstantSDNode>(Op.getOperand(3).getNode())->getZExtValue();
2233
2234 APInt OpUsefulBits(UsefulBits);
2235 OpUsefulBits = 1;
2236
2237 APInt ResultUsefulBits(UsefulBits.getBitWidth(), 0);
2238 ResultUsefulBits.flipAllBits();
2239 APInt Mask(UsefulBits.getBitWidth(), 0);
2240
2241 getUsefulBits(Op, ResultUsefulBits, Depth + 1);
2242
2243 if (MSB >= Imm) {
2244 // The instruction is a BFXIL.
2245 uint64_t Width = MSB - Imm + 1;
2246 uint64_t LSB = Imm;
2247
2248 OpUsefulBits <<= Width;
2249 --OpUsefulBits;
2250
2251 if (Op.getOperand(1) == Orig) {
2252 // Copy the low bits from the result to bits starting from LSB.
2253 Mask = ResultUsefulBits & OpUsefulBits;
2254 Mask <<= LSB;
2255 }
2256
2257 if (Op.getOperand(0) == Orig)
2258 // Bits starting from LSB in the input contribute to the result.
2259 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2260 } else {
2261 // The instruction is a BFI.
2262 uint64_t Width = MSB + 1;
2263 uint64_t LSB = UsefulBits.getBitWidth() - Imm;
2264
2265 OpUsefulBits <<= Width;
2266 --OpUsefulBits;
2267 OpUsefulBits <<= LSB;
2268
2269 if (Op.getOperand(1) == Orig) {
2270 // Copy the bits from the result to the zero bits.
2271 Mask = ResultUsefulBits & OpUsefulBits;
2272 Mask.lshrInPlace(LSB);
2273 }
2274
2275 if (Op.getOperand(0) == Orig)
2276 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2277 }
2278
2279 UsefulBits &= Mask;
2280}
2281
2282static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits,
2283 SDValue Orig, unsigned Depth) {
2284
2285 // Users of this node should have already been instruction selected
2286 // FIXME: Can we turn that into an assert?
2287 if (!UserNode->isMachineOpcode())
2288 return;
2289
2290 switch (UserNode->getMachineOpcode()) {
2291 default:
2292 return;
2293 case AArch64::ANDSWri:
2294 case AArch64::ANDSXri:
2295 case AArch64::ANDWri:
2296 case AArch64::ANDXri:
2297 // We increment Depth only when we call the getUsefulBits
2298 return getUsefulBitsFromAndWithImmediate(SDValue(UserNode, 0), UsefulBits,
2299 Depth);
2300 case AArch64::UBFMWri:
2301 case AArch64::UBFMXri:
2302 return getUsefulBitsFromUBFM(SDValue(UserNode, 0), UsefulBits, Depth);
2303
2304 case AArch64::ORRWrs:
2305 case AArch64::ORRXrs:
2306 if (UserNode->getOperand(1) != Orig)
2307 return;
2308 return getUsefulBitsFromOrWithShiftedReg(SDValue(UserNode, 0), UsefulBits,
2309 Depth);
2310 case AArch64::BFMWri:
2311 case AArch64::BFMXri:
2312 return getUsefulBitsFromBFM(SDValue(UserNode, 0), Orig, UsefulBits, Depth);
2313
2314 case AArch64::STRBBui:
2315 case AArch64::STURBBi:
2316 if (UserNode->getOperand(0) != Orig)
2317 return;
2318 UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xff);
2319 return;
2320
2321 case AArch64::STRHHui:
2322 case AArch64::STURHHi:
2323 if (UserNode->getOperand(0) != Orig)
2324 return;
2325 UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xffff);
2326 return;
2327 }
2328}
2329
2330static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth) {
2331 if (Depth >= SelectionDAG::MaxRecursionDepth)
2332 return;
2333 // Initialize UsefulBits
2334 if (!Depth) {
2335 unsigned Bitwidth = Op.getScalarValueSizeInBits();
2336 // At the beginning, assume every produced bits is useful
2337 UsefulBits = APInt(Bitwidth, 0);
2338 UsefulBits.flipAllBits();
2339 }
2340 APInt UsersUsefulBits(UsefulBits.getBitWidth(), 0);
2341
2342 for (SDNode *Node : Op.getNode()->uses()) {
2343 // A use cannot produce useful bits
2344 APInt UsefulBitsForUse = APInt(UsefulBits);
2345 getUsefulBitsForUse(Node, UsefulBitsForUse, Op, Depth);
2346 UsersUsefulBits |= UsefulBitsForUse;
2347 }
2348 // UsefulBits contains the produced bits that are meaningful for the
2349 // current definition, thus a user cannot make a bit meaningful at
2350 // this point
2351 UsefulBits &= UsersUsefulBits;
2352}
2353
2354/// Create a machine node performing a notional SHL of Op by ShlAmount. If
2355/// ShlAmount is negative, do a (logical) right-shift instead. If ShlAmount is
2356/// 0, return Op unchanged.
2357static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount) {
2358 if (ShlAmount == 0)
2359 return Op;
2360
2361 EVT VT = Op.getValueType();
2362 SDLoc dl(Op);
2363 unsigned BitWidth = VT.getSizeInBits();
2364 unsigned UBFMOpc = BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2365
2366 SDNode *ShiftNode;
2367 if (ShlAmount > 0) {
2368 // LSL wD, wN, #Amt == UBFM wD, wN, #32-Amt, #31-Amt
2369 ShiftNode = CurDAG->getMachineNode(
2370 UBFMOpc, dl, VT, Op,
2371 CurDAG->getTargetConstant(BitWidth - ShlAmount, dl, VT),
2372 CurDAG->getTargetConstant(BitWidth - 1 - ShlAmount, dl, VT));
2373 } else {
2374 // LSR wD, wN, #Amt == UBFM wD, wN, #Amt, #32-1
2375 assert(ShlAmount < 0 && "expected right shift")((ShlAmount < 0 && "expected right shift") ? static_cast
<void> (0) : __assert_fail ("ShlAmount < 0 && \"expected right shift\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2375, __PRETTY_FUNCTION__))
;
2376 int ShrAmount = -ShlAmount;
2377 ShiftNode = CurDAG->getMachineNode(
2378 UBFMOpc, dl, VT, Op, CurDAG->getTargetConstant(ShrAmount, dl, VT),
2379 CurDAG->getTargetConstant(BitWidth - 1, dl, VT));
2380 }
2381
2382 return SDValue(ShiftNode, 0);
2383}
2384
2385/// Does this tree qualify as an attempt to move a bitfield into position,
2386/// essentially "(and (shl VAL, N), Mask)".
2387static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op,
2388 bool BiggerPattern,
2389 SDValue &Src, int &ShiftAmount,
2390 int &MaskWidth) {
2391 EVT VT = Op.getValueType();
2392 unsigned BitWidth = VT.getSizeInBits();
2393 (void)BitWidth;
2394 assert(BitWidth == 32 || BitWidth == 64)((BitWidth == 32 || BitWidth == 64) ? static_cast<void>
(0) : __assert_fail ("BitWidth == 32 || BitWidth == 64", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2394, __PRETTY_FUNCTION__))
;
2395
2396 KnownBits Known = CurDAG->computeKnownBits(Op);
2397
2398 // Non-zero in the sense that they're not provably zero, which is the key
2399 // point if we want to use this value
2400 uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
2401
2402 // Discard a constant AND mask if present. It's safe because the node will
2403 // already have been factored into the computeKnownBits calculation above.
2404 uint64_t AndImm;
2405 if (isOpcWithIntImmediate(Op.getNode(), ISD::AND, AndImm)) {
2406 assert((~APInt(BitWidth, AndImm) & ~Known.Zero) == 0)(((~APInt(BitWidth, AndImm) & ~Known.Zero) == 0) ? static_cast
<void> (0) : __assert_fail ("(~APInt(BitWidth, AndImm) & ~Known.Zero) == 0"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2406, __PRETTY_FUNCTION__))
;
2407 Op = Op.getOperand(0);
2408 }
2409
2410 // Don't match if the SHL has more than one use, since then we'll end up
2411 // generating SHL+UBFIZ instead of just keeping SHL+AND.
2412 if (!BiggerPattern && !Op.hasOneUse())
2413 return false;
2414
2415 uint64_t ShlImm;
2416 if (!isOpcWithIntImmediate(Op.getNode(), ISD::SHL, ShlImm))
2417 return false;
2418 Op = Op.getOperand(0);
2419
2420 if (!isShiftedMask_64(NonZeroBits))
2421 return false;
2422
2423 ShiftAmount = countTrailingZeros(NonZeroBits);
2424 MaskWidth = countTrailingOnes(NonZeroBits >> ShiftAmount);
2425
2426 // BFI encompasses sufficiently many nodes that it's worth inserting an extra
2427 // LSL/LSR if the mask in NonZeroBits doesn't quite match up with the ISD::SHL
2428 // amount. BiggerPattern is true when this pattern is being matched for BFI,
2429 // BiggerPattern is false when this pattern is being matched for UBFIZ, in
2430 // which case it is not profitable to insert an extra shift.
2431 if (ShlImm - ShiftAmount != 0 && !BiggerPattern)
2432 return false;
2433 Src = getLeftShift(CurDAG, Op, ShlImm - ShiftAmount);
2434
2435 return true;
2436}
2437
2438static bool isShiftedMask(uint64_t Mask, EVT VT) {
2439 assert(VT == MVT::i32 || VT == MVT::i64)((VT == MVT::i32 || VT == MVT::i64) ? static_cast<void>
(0) : __assert_fail ("VT == MVT::i32 || VT == MVT::i64", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2439, __PRETTY_FUNCTION__))
;
2440 if (VT == MVT::i32)
2441 return isShiftedMask_32(Mask);
2442 return isShiftedMask_64(Mask);
2443}
2444
2445// Generate a BFI/BFXIL from 'or (and X, MaskImm), OrImm' iff the value being
2446// inserted only sets known zero bits.
2447static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG) {
2448 assert(N->getOpcode() == ISD::OR && "Expect a OR operation")((N->getOpcode() == ISD::OR && "Expect a OR operation"
) ? static_cast<void> (0) : __assert_fail ("N->getOpcode() == ISD::OR && \"Expect a OR operation\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2448, __PRETTY_FUNCTION__))
;
2449
2450 EVT VT = N->getValueType(0);
2451 if (VT != MVT::i32 && VT != MVT::i64)
2452 return false;
2453
2454 unsigned BitWidth = VT.getSizeInBits();
2455
2456 uint64_t OrImm;
2457 if (!isOpcWithIntImmediate(N, ISD::OR, OrImm))
2458 return false;
2459
2460 // Skip this transformation if the ORR immediate can be encoded in the ORR.
2461 // Otherwise, we'll trade an AND+ORR for ORR+BFI/BFXIL, which is most likely
2462 // performance neutral.
2463 if (AArch64_AM::isLogicalImmediate(OrImm, BitWidth))
2464 return false;
2465
2466 uint64_t MaskImm;
2467 SDValue And = N->getOperand(0);
2468 // Must be a single use AND with an immediate operand.
2469 if (!And.hasOneUse() ||
2470 !isOpcWithIntImmediate(And.getNode(), ISD::AND, MaskImm))
2471 return false;
2472
2473 // Compute the Known Zero for the AND as this allows us to catch more general
2474 // cases than just looking for AND with imm.
2475 KnownBits Known = CurDAG->computeKnownBits(And);
2476
2477 // Non-zero in the sense that they're not provably zero, which is the key
2478 // point if we want to use this value.
2479 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
2480
2481 // The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
2482 if (!isShiftedMask(Known.Zero.getZExtValue(), VT))
2483 return false;
2484
2485 // The bits being inserted must only set those bits that are known to be zero.
2486 if ((OrImm & NotKnownZero) != 0) {
2487 // FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't
2488 // currently handle this case.
2489 return false;
2490 }
2491
2492 // BFI/BFXIL dst, src, #lsb, #width.
2493 int LSB = countTrailingOnes(NotKnownZero);
2494 int Width = BitWidth - APInt(BitWidth, NotKnownZero).countPopulation();
2495
2496 // BFI/BFXIL is an alias of BFM, so translate to BFM operands.
2497 unsigned ImmR = (BitWidth - LSB) % BitWidth;
2498 unsigned ImmS = Width - 1;
2499
2500 // If we're creating a BFI instruction avoid cases where we need more
2501 // instructions to materialize the BFI constant as compared to the original
2502 // ORR. A BFXIL will use the same constant as the original ORR, so the code
2503 // should be no worse in this case.
2504 bool IsBFI = LSB != 0;
2505 uint64_t BFIImm = OrImm >> LSB;
2506 if (IsBFI && !AArch64_AM::isLogicalImmediate(BFIImm, BitWidth)) {
2507 // We have a BFI instruction and we know the constant can't be materialized
2508 // with a ORR-immediate with the zero register.
2509 unsigned OrChunks = 0, BFIChunks = 0;
2510 for (unsigned Shift = 0; Shift < BitWidth; Shift += 16) {
2511 if (((OrImm >> Shift) & 0xFFFF) != 0)
2512 ++OrChunks;
2513 if (((BFIImm >> Shift) & 0xFFFF) != 0)
2514 ++BFIChunks;
2515 }
2516 if (BFIChunks > OrChunks)
2517 return false;
2518 }
2519
2520 // Materialize the constant to be inserted.
2521 SDLoc DL(N);
2522 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
2523 SDNode *MOVI = CurDAG->getMachineNode(
2524 MOVIOpc, DL, VT, CurDAG->getTargetConstant(BFIImm, DL, VT));
2525
2526 // Create the BFI/BFXIL instruction.
2527 SDValue Ops[] = {And.getOperand(0), SDValue(MOVI, 0),
2528 CurDAG->getTargetConstant(ImmR, DL, VT),
2529 CurDAG->getTargetConstant(ImmS, DL, VT)};
2530 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
2531 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2532 return true;
2533}
2534
2535static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits,
2536 SelectionDAG *CurDAG) {
2537 assert(N->getOpcode() == ISD::OR && "Expect a OR operation")((N->getOpcode() == ISD::OR && "Expect a OR operation"
) ? static_cast<void> (0) : __assert_fail ("N->getOpcode() == ISD::OR && \"Expect a OR operation\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2537, __PRETTY_FUNCTION__))
;
2538
2539 EVT VT = N->getValueType(0);
2540 if (VT != MVT::i32 && VT != MVT::i64)
2541 return false;
2542
2543 unsigned BitWidth = VT.getSizeInBits();
2544
2545 // Because of simplify-demanded-bits in DAGCombine, involved masks may not
2546 // have the expected shape. Try to undo that.
2547
2548 unsigned NumberOfIgnoredLowBits = UsefulBits.countTrailingZeros();
2549 unsigned NumberOfIgnoredHighBits = UsefulBits.countLeadingZeros();
2550
2551 // Given a OR operation, check if we have the following pattern
2552 // ubfm c, b, imm, imm2 (or something that does the same jobs, see
2553 // isBitfieldExtractOp)
2554 // d = e & mask2 ; where mask is a binary sequence of 1..10..0 and
2555 // countTrailingZeros(mask2) == imm2 - imm + 1
2556 // f = d | c
2557 // if yes, replace the OR instruction with:
2558 // f = BFM Opd0, Opd1, LSB, MSB ; where LSB = imm, and MSB = imm2
2559
2560 // OR is commutative, check all combinations of operand order and values of
2561 // BiggerPattern, i.e.
2562 // Opd0, Opd1, BiggerPattern=false
2563 // Opd1, Opd0, BiggerPattern=false
2564 // Opd0, Opd1, BiggerPattern=true
2565 // Opd1, Opd0, BiggerPattern=true
2566 // Several of these combinations may match, so check with BiggerPattern=false
2567 // first since that will produce better results by matching more instructions
2568 // and/or inserting fewer extra instructions.
2569 for (int I = 0; I < 4; ++I) {
2570
2571 SDValue Dst, Src;
2572 unsigned ImmR, ImmS;
2573 bool BiggerPattern = I / 2;
2574 SDValue OrOpd0Val = N->getOperand(I % 2);
2575 SDNode *OrOpd0 = OrOpd0Val.getNode();
2576 SDValue OrOpd1Val = N->getOperand((I + 1) % 2);
2577 SDNode *OrOpd1 = OrOpd1Val.getNode();
2578
2579 unsigned BFXOpc;
2580 int DstLSB, Width;
2581 if (isBitfieldExtractOp(CurDAG, OrOpd0, BFXOpc, Src, ImmR, ImmS,
2582 NumberOfIgnoredLowBits, BiggerPattern)) {
2583 // Check that the returned opcode is compatible with the pattern,
2584 // i.e., same type and zero extended (U and not S)
2585 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
2586 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
2587 continue;
2588
2589 // Compute the width of the bitfield insertion
2590 DstLSB = 0;
2591 Width = ImmS - ImmR + 1;
2592 // FIXME: This constraint is to catch bitfield insertion we may
2593 // want to widen the pattern if we want to grab general bitfied
2594 // move case
2595 if (Width <= 0)
2596 continue;
2597
2598 // If the mask on the insertee is correct, we have a BFXIL operation. We
2599 // can share the ImmR and ImmS values from the already-computed UBFM.
2600 } else if (isBitfieldPositioningOp(CurDAG, OrOpd0Val,
2601 BiggerPattern,
2602 Src, DstLSB, Width)) {
2603 ImmR = (BitWidth - DstLSB) % BitWidth;
2604 ImmS = Width - 1;
2605 } else
2606 continue;
2607
2608 // Check the second part of the pattern
2609 EVT VT = OrOpd1Val.getValueType();
2610 assert((VT == MVT::i32 || VT == MVT::i64) && "unexpected OR operand")(((VT == MVT::i32 || VT == MVT::i64) && "unexpected OR operand"
) ? static_cast<void> (0) : __assert_fail ("(VT == MVT::i32 || VT == MVT::i64) && \"unexpected OR operand\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2610, __PRETTY_FUNCTION__))
;
2611
2612 // Compute the Known Zero for the candidate of the first operand.
2613 // This allows to catch more general case than just looking for
2614 // AND with imm. Indeed, simplify-demanded-bits may have removed
2615 // the AND instruction because it proves it was useless.
2616 KnownBits Known = CurDAG->computeKnownBits(OrOpd1Val);
2617
2618 // Check if there is enough room for the second operand to appear
2619 // in the first one
2620 APInt BitsToBeInserted =
2621 APInt::getBitsSet(Known.getBitWidth(), DstLSB, DstLSB + Width);
2622
2623 if ((BitsToBeInserted & ~Known.Zero) != 0)
2624 continue;
2625
2626 // Set the first operand
2627 uint64_t Imm;
2628 if (isOpcWithIntImmediate(OrOpd1, ISD::AND, Imm) &&
2629 isBitfieldDstMask(Imm, BitsToBeInserted, NumberOfIgnoredHighBits, VT))
2630 // In that case, we can eliminate the AND
2631 Dst = OrOpd1->getOperand(0);
2632 else
2633 // Maybe the AND has been removed by simplify-demanded-bits
2634 // or is useful because it discards more bits
2635 Dst = OrOpd1Val;
2636
2637 // both parts match
2638 SDLoc DL(N);
2639 SDValue Ops[] = {Dst, Src, CurDAG->getTargetConstant(ImmR, DL, VT),
2640 CurDAG->getTargetConstant(ImmS, DL, VT)};
2641 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
2642 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2643 return true;
2644 }
2645
2646 // Generate a BFXIL from 'or (and X, Mask0Imm), (and Y, Mask1Imm)' iff
2647 // Mask0Imm and ~Mask1Imm are equivalent and one of the MaskImms is a shifted
2648 // mask (e.g., 0x000ffff0).
2649 uint64_t Mask0Imm, Mask1Imm;
2650 SDValue And0 = N->getOperand(0);
2651 SDValue And1 = N->getOperand(1);
2652 if (And0.hasOneUse() && And1.hasOneUse() &&
2653 isOpcWithIntImmediate(And0.getNode(), ISD::AND, Mask0Imm) &&
2654 isOpcWithIntImmediate(And1.getNode(), ISD::AND, Mask1Imm) &&
2655 APInt(BitWidth, Mask0Imm) == ~APInt(BitWidth, Mask1Imm) &&
2656 (isShiftedMask(Mask0Imm, VT) || isShiftedMask(Mask1Imm, VT))) {
2657
2658 // ORR is commutative, so canonicalize to the form 'or (and X, Mask0Imm),
2659 // (and Y, Mask1Imm)' where Mask1Imm is the shifted mask masking off the
2660 // bits to be inserted.
2661 if (isShiftedMask(Mask0Imm, VT)) {
2662 std::swap(And0, And1);
2663 std::swap(Mask0Imm, Mask1Imm);
2664 }
2665
2666 SDValue Src = And1->getOperand(0);
2667 SDValue Dst = And0->getOperand(0);
2668 unsigned LSB = countTrailingZeros(Mask1Imm);
2669 int Width = BitWidth - APInt(BitWidth, Mask0Imm).countPopulation();
2670
2671 // The BFXIL inserts the low-order bits from a source register, so right
2672 // shift the needed bits into place.
2673 SDLoc DL(N);
2674 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
2675 SDNode *LSR = CurDAG->getMachineNode(
2676 ShiftOpc, DL, VT, Src, CurDAG->getTargetConstant(LSB, DL, VT),
2677 CurDAG->getTargetConstant(BitWidth - 1, DL, VT));
2678
2679 // BFXIL is an alias of BFM, so translate to BFM operands.
2680 unsigned ImmR = (BitWidth - LSB) % BitWidth;
2681 unsigned ImmS = Width - 1;
2682
2683 // Create the BFXIL instruction.
2684 SDValue Ops[] = {Dst, SDValue(LSR, 0),
2685 CurDAG->getTargetConstant(ImmR, DL, VT),
2686 CurDAG->getTargetConstant(ImmS, DL, VT)};
2687 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
2688 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2689 return true;
2690 }
2691
2692 return false;
2693}
2694
2695bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *N) {
2696 if (N->getOpcode() != ISD::OR)
2697 return false;
2698
2699 APInt NUsefulBits;
2700 getUsefulBits(SDValue(N, 0), NUsefulBits);
2701
2702 // If all bits are not useful, just return UNDEF.
2703 if (!NUsefulBits) {
2704 CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->getValueType(0));
2705 return true;
2706 }
2707
2708 if (tryBitfieldInsertOpFromOr(N, NUsefulBits, CurDAG))
2709 return true;
2710
2711 return tryBitfieldInsertOpFromOrAndImm(N, CurDAG);
2712}
2713
2714/// SelectBitfieldInsertInZeroOp - Match a UBFIZ instruction that is the
2715/// equivalent of a left shift by a constant amount followed by an and masking
2716/// out a contiguous set of bits.
2717bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *N) {
2718 if (N->getOpcode() != ISD::AND)
2719 return false;
2720
2721 EVT VT = N->getValueType(0);
2722 if (VT != MVT::i32 && VT != MVT::i64)
2723 return false;
2724
2725 SDValue Op0;
2726 int DstLSB, Width;
2727 if (!isBitfieldPositioningOp(CurDAG, SDValue(N, 0), /*BiggerPattern=*/false,
2728 Op0, DstLSB, Width))
2729 return false;
2730
2731 // ImmR is the rotate right amount.
2732 unsigned ImmR = (VT.getSizeInBits() - DstLSB) % VT.getSizeInBits();
2733 // ImmS is the most significant bit of the source to be moved.
2734 unsigned ImmS = Width - 1;
2735
2736 SDLoc DL(N);
2737 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR, DL, VT),
2738 CurDAG->getTargetConstant(ImmS, DL, VT)};
2739 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
2740 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2741 return true;
2742}
2743
2744/// tryShiftAmountMod - Take advantage of built-in mod of shift amount in
2745/// variable shift/rotate instructions.
2746bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *N) {
2747 EVT VT = N->getValueType(0);
2748
2749 unsigned Opc;
2750 switch (N->getOpcode()) {
2751 case ISD::ROTR:
2752 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
2753 break;
2754 case ISD::SHL:
2755 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
2756 break;
2757 case ISD::SRL:
2758 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
2759 break;
2760 case ISD::SRA:
2761 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
2762 break;
2763 default:
2764 return false;
2765 }
2766
2767 uint64_t Size;
2768 uint64_t Bits;
2769 if (VT == MVT::i32) {
2770 Bits = 5;
2771 Size = 32;
2772 } else if (VT == MVT::i64) {
2773 Bits = 6;
2774 Size = 64;
2775 } else
2776 return false;
2777
2778 SDValue ShiftAmt = N->getOperand(1);
2779 SDLoc DL(N);
2780 SDValue NewShiftAmt;
2781
2782 // Skip over an extend of the shift amount.
2783 if (ShiftAmt->getOpcode() == ISD::ZERO_EXTEND ||
2784 ShiftAmt->getOpcode() == ISD::ANY_EXTEND)
2785 ShiftAmt = ShiftAmt->getOperand(0);
2786
2787 if (ShiftAmt->getOpcode() == ISD::ADD || ShiftAmt->getOpcode() == ISD::SUB) {
2788 SDValue Add0 = ShiftAmt->getOperand(0);
2789 SDValue Add1 = ShiftAmt->getOperand(1);
2790 uint64_t Add0Imm;
2791 uint64_t Add1Imm;
2792 // If we are shifting by X+/-N where N == 0 mod Size, then just shift by X
2793 // to avoid the ADD/SUB.
2794 if (isIntImmediate(Add1, Add1Imm) && (Add1Imm % Size == 0))
2795 NewShiftAmt = Add0;
2796 // If we are shifting by N-X where N == 0 mod Size, then just shift by -X to
2797 // generate a NEG instead of a SUB of a constant.
2798 else if (ShiftAmt->getOpcode() == ISD::SUB &&
2799 isIntImmediate(Add0, Add0Imm) && Add0Imm != 0 &&
2800 (Add0Imm % Size == 0)) {
2801 unsigned NegOpc;
2802 unsigned ZeroReg;
2803 EVT SubVT = ShiftAmt->getValueType(0);
2804 if (SubVT == MVT::i32) {
2805 NegOpc = AArch64::SUBWrr;
2806 ZeroReg = AArch64::WZR;
2807 } else {
2808 assert(SubVT == MVT::i64)((SubVT == MVT::i64) ? static_cast<void> (0) : __assert_fail
("SubVT == MVT::i64", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2808, __PRETTY_FUNCTION__))
;
2809 NegOpc = AArch64::SUBXrr;
2810 ZeroReg = AArch64::XZR;
2811 }
2812 SDValue Zero =
2813 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, ZeroReg, SubVT);
2814 MachineSDNode *Neg =
2815 CurDAG->getMachineNode(NegOpc, DL, SubVT, Zero, Add1);
2816 NewShiftAmt = SDValue(Neg, 0);
2817 } else
2818 return false;
2819 } else {
2820 // If the shift amount is masked with an AND, check that the mask covers the
2821 // bits that are implicitly ANDed off by the above opcodes and if so, skip
2822 // the AND.
2823 uint64_t MaskImm;
2824 if (!isOpcWithIntImmediate(ShiftAmt.getNode(), ISD::AND, MaskImm) &&
2825 !isOpcWithIntImmediate(ShiftAmt.getNode(), AArch64ISD::ANDS, MaskImm))
2826 return false;
2827
2828 if (countTrailingOnes(MaskImm) < Bits)
2829 return false;
2830
2831 NewShiftAmt = ShiftAmt->getOperand(0);
2832 }
2833
2834 // Narrow/widen the shift amount to match the size of the shift operation.
2835 if (VT == MVT::i32)
2836 NewShiftAmt = narrowIfNeeded(CurDAG, NewShiftAmt);
2837 else if (VT == MVT::i64 && NewShiftAmt->getValueType(0) == MVT::i32) {
2838 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, DL, MVT::i32);
2839 MachineSDNode *Ext = CurDAG->getMachineNode(
2840 AArch64::SUBREG_TO_REG, DL, VT,
2841 CurDAG->getTargetConstant(0, DL, MVT::i64), NewShiftAmt, SubReg);
2842 NewShiftAmt = SDValue(Ext, 0);
2843 }
2844
2845 SDValue Ops[] = {N->getOperand(0), NewShiftAmt};
2846 CurDAG->SelectNodeTo(N, Opc, VT, Ops);
2847 return true;
2848}
2849
2850bool
2851AArch64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos,
2852 unsigned RegWidth) {
2853 APFloat FVal(0.0);
2854 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N))
2855 FVal = CN->getValueAPF();
2856 else if (LoadSDNode *LN = dyn_cast<LoadSDNode>(N)) {
2857 // Some otherwise illegal constants are allowed in this case.
2858 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
2859 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
2860 return false;
2861
2862 ConstantPoolSDNode *CN =
2863 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
2864 FVal = cast<ConstantFP>(CN->getConstVal())->getValueAPF();
2865 } else
2866 return false;
2867
2868 // An FCVT[SU] instruction performs: convertToInt(Val * 2^fbits) where fbits
2869 // is between 1 and 32 for a destination w-register, or 1 and 64 for an
2870 // x-register.
2871 //
2872 // By this stage, we've detected (fp_to_[su]int (fmul Val, THIS_NODE)) so we
2873 // want THIS_NODE to be 2^fbits. This is much easier to deal with using
2874 // integers.
2875 bool IsExact;
2876
2877 // fbits is between 1 and 64 in the worst-case, which means the fmul
2878 // could have 2^64 as an actual operand. Need 65 bits of precision.
2879 APSInt IntVal(65, true);
2880 FVal.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact);
2881
2882 // N.b. isPowerOf2 also checks for > 0.
2883 if (!IsExact || !IntVal.isPowerOf2()) return false;
2884 unsigned FBits = IntVal.logBase2();
2885
2886 // Checks above should have guaranteed that we haven't lost information in
2887 // finding FBits, but it must still be in range.
2888 if (FBits == 0 || FBits > RegWidth) return false;
2889
2890 FixedPos = CurDAG->getTargetConstant(FBits, SDLoc(N), MVT::i32);
2891 return true;
2892}
2893
2894// Inspects a register string of the form o0:op1:CRn:CRm:op2 gets the fields
2895// of the string and obtains the integer values from them and combines these
2896// into a single value to be used in the MRS/MSR instruction.
2897static int getIntOperandFromRegisterString(StringRef RegString) {
2898 SmallVector<StringRef, 5> Fields;
2899 RegString.split(Fields, ':');
2900
2901 if (Fields.size() == 1)
2902 return -1;
2903
2904 assert(Fields.size() == 5((Fields.size() == 5 && "Invalid number of fields in read register string"
) ? static_cast<void> (0) : __assert_fail ("Fields.size() == 5 && \"Invalid number of fields in read register string\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2905, __PRETTY_FUNCTION__))
2905 && "Invalid number of fields in read register string")((Fields.size() == 5 && "Invalid number of fields in read register string"
) ? static_cast<void> (0) : __assert_fail ("Fields.size() == 5 && \"Invalid number of fields in read register string\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2905, __PRETTY_FUNCTION__))
;
2906
2907 SmallVector<int, 5> Ops;
2908 bool AllIntFields = true;
2909
2910 for (StringRef Field : Fields) {
2911 unsigned IntField;
2912 AllIntFields &= !Field.getAsInteger(10, IntField);
2913 Ops.push_back(IntField);
2914 }
2915
2916 assert(AllIntFields &&((AllIntFields && "Unexpected non-integer value in special register string."
) ? static_cast<void> (0) : __assert_fail ("AllIntFields && \"Unexpected non-integer value in special register string.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2917, __PRETTY_FUNCTION__))
2917 "Unexpected non-integer value in special register string.")((AllIntFields && "Unexpected non-integer value in special register string."
) ? static_cast<void> (0) : __assert_fail ("AllIntFields && \"Unexpected non-integer value in special register string.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2917, __PRETTY_FUNCTION__))
;
2918
2919 // Need to combine the integer fields of the string into a single value
2920 // based on the bit encoding of MRS/MSR instruction.
2921 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
2922 (Ops[3] << 3) | (Ops[4]);
2923}
2924
2925// Lower the read_register intrinsic to an MRS instruction node if the special
2926// register string argument is either of the form detailed in the ALCE (the
2927// form described in getIntOperandsFromRegsterString) or is a named register
2928// known by the MRS SysReg mapper.
2929bool AArch64DAGToDAGISel::tryReadRegister(SDNode *N) {
2930 const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1));
2931 const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0));
2932 SDLoc DL(N);
2933
2934 int Reg = getIntOperandFromRegisterString(RegString->getString());
2935 if (Reg != -1) {
2936 ReplaceNode(N, CurDAG->getMachineNode(
2937 AArch64::MRS, DL, N->getSimpleValueType(0), MVT::Other,
2938 CurDAG->getTargetConstant(Reg, DL, MVT::i32),
2939 N->getOperand(0)));
2940 return true;
2941 }
2942
2943 // Use the sysreg mapper to map the remaining possible strings to the
2944 // value for the register to be used for the instruction operand.
2945 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
2946 if (TheReg && TheReg->Readable &&
2947 TheReg->haveFeatures(Subtarget->getFeatureBits()))
2948 Reg = TheReg->Encoding;
2949 else
2950 Reg = AArch64SysReg::parseGenericRegister(RegString->getString());
2951
2952 if (Reg != -1) {
2953 ReplaceNode(N, CurDAG->getMachineNode(
2954 AArch64::MRS, DL, N->getSimpleValueType(0), MVT::Other,
2955 CurDAG->getTargetConstant(Reg, DL, MVT::i32),
2956 N->getOperand(0)));
2957 return true;
2958 }
2959
2960 if (RegString->getString() == "pc") {
2961 ReplaceNode(N, CurDAG->getMachineNode(
2962 AArch64::ADR, DL, N->getSimpleValueType(0), MVT::Other,
2963 CurDAG->getTargetConstant(0, DL, MVT::i32),
2964 N->getOperand(0)));
2965 return true;
2966 }
2967
2968 return false;
2969}
2970
2971// Lower the write_register intrinsic to an MSR instruction node if the special
2972// register string argument is either of the form detailed in the ALCE (the
2973// form described in getIntOperandsFromRegsterString) or is a named register
2974// known by the MSR SysReg mapper.
2975bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *N) {
2976 const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1));
2977 const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0));
2978 SDLoc DL(N);
2979
2980 int Reg = getIntOperandFromRegisterString(RegString->getString());
2981 if (Reg != -1) {
2982 ReplaceNode(
2983 N, CurDAG->getMachineNode(AArch64::MSR, DL, MVT::Other,
2984 CurDAG->getTargetConstant(Reg, DL, MVT::i32),
2985 N->getOperand(2), N->getOperand(0)));
2986 return true;
2987 }
2988
2989 // Check if the register was one of those allowed as the pstatefield value in
2990 // the MSR (immediate) instruction. To accept the values allowed in the
2991 // pstatefield for the MSR (immediate) instruction, we also require that an
2992 // immediate value has been provided as an argument, we know that this is
2993 // the case as it has been ensured by semantic checking.
2994 auto PMapper = AArch64PState::lookupPStateByName(RegString->getString());
2995 if (PMapper) {
2996 assert (isa<ConstantSDNode>(N->getOperand(2))((isa<ConstantSDNode>(N->getOperand(2)) && "Expected a constant integer expression."
) ? static_cast<void> (0) : __assert_fail ("isa<ConstantSDNode>(N->getOperand(2)) && \"Expected a constant integer expression.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2997, __PRETTY_FUNCTION__))
2997 && "Expected a constant integer expression.")((isa<ConstantSDNode>(N->getOperand(2)) && "Expected a constant integer expression."
) ? static_cast<void> (0) : __assert_fail ("isa<ConstantSDNode>(N->getOperand(2)) && \"Expected a constant integer expression.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 2997, __PRETTY_FUNCTION__))
;
2998 unsigned Reg = PMapper->Encoding;
2999 uint64_t Immed = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
3000 unsigned State;
3001 if (Reg == AArch64PState::PAN || Reg == AArch64PState::UAO || Reg == AArch64PState::SSBS) {
3002 assert(Immed < 2 && "Bad imm")((Immed < 2 && "Bad imm") ? static_cast<void>
(0) : __assert_fail ("Immed < 2 && \"Bad imm\"", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3002, __PRETTY_FUNCTION__))
;
3003 State = AArch64::MSRpstateImm1;
3004 } else {
3005 assert(Immed < 16 && "Bad imm")((Immed < 16 && "Bad imm") ? static_cast<void>
(0) : __assert_fail ("Immed < 16 && \"Bad imm\"",
"/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3005, __PRETTY_FUNCTION__))
;
3006 State = AArch64::MSRpstateImm4;
3007 }
3008 ReplaceNode(N, CurDAG->getMachineNode(
3009 State, DL, MVT::Other,
3010 CurDAG->getTargetConstant(Reg, DL, MVT::i32),
3011 CurDAG->getTargetConstant(Immed, DL, MVT::i16),
3012 N->getOperand(0)));
3013 return true;
3014 }
3015
3016 // Use the sysreg mapper to attempt to map the remaining possible strings
3017 // to the value for the register to be used for the MSR (register)
3018 // instruction operand.
3019 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
3020 if (TheReg && TheReg->Writeable &&
3021 TheReg->haveFeatures(Subtarget->getFeatureBits()))
3022 Reg = TheReg->Encoding;
3023 else
3024 Reg = AArch64SysReg::parseGenericRegister(RegString->getString());
3025 if (Reg != -1) {
3026 ReplaceNode(N, CurDAG->getMachineNode(
3027 AArch64::MSR, DL, MVT::Other,
3028 CurDAG->getTargetConstant(Reg, DL, MVT::i32),
3029 N->getOperand(2), N->getOperand(0)));
3030 return true;
3031 }
3032
3033 return false;
3034}
3035
3036/// We've got special pseudo-instructions for these
3037bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *N) {
3038 unsigned Opcode;
3039 EVT MemTy = cast<MemSDNode>(N)->getMemoryVT();
3040
3041 // Leave IR for LSE if subtarget supports it.
3042 if (Subtarget->hasLSE()) return false;
3043
3044 if (MemTy == MVT::i8)
3045 Opcode = AArch64::CMP_SWAP_8;
3046 else if (MemTy == MVT::i16)
3047 Opcode = AArch64::CMP_SWAP_16;
3048 else if (MemTy == MVT::i32)
3049 Opcode = AArch64::CMP_SWAP_32;
3050 else if (MemTy == MVT::i64)
3051 Opcode = AArch64::CMP_SWAP_64;
3052 else
3053 llvm_unreachable("Unknown AtomicCmpSwap type")::llvm::llvm_unreachable_internal("Unknown AtomicCmpSwap type"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3053)
;
3054
3055 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
3056 SDValue Ops[] = {N->getOperand(1), N->getOperand(2), N->getOperand(3),
3057 N->getOperand(0)};
3058 SDNode *CmpSwap = CurDAG->getMachineNode(
3059 Opcode, SDLoc(N),
3060 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops);
3061
3062 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
3063 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
3064
3065 ReplaceUses(SDValue(N, 0), SDValue(CmpSwap, 0));
3066 ReplaceUses(SDValue(N, 1), SDValue(CmpSwap, 2));
3067 CurDAG->RemoveDeadNode(N);
3068
3069 return true;
3070}
3071
3072bool AArch64DAGToDAGISel::SelectSVE8BitLslImm(SDValue N, SDValue &Base,
3073 SDValue &Offset) {
3074 auto C = dyn_cast<ConstantSDNode>(N);
3075 if (!C)
3076 return false;
3077
3078 auto Ty = N->getValueType(0);
3079
3080 int64_t Imm = C->getSExtValue();
3081 SDLoc DL(N);
3082
3083 if ((Imm >= -128) && (Imm <= 127)) {
3084 Base = CurDAG->getTargetConstant(Imm, DL, Ty);
3085 Offset = CurDAG->getTargetConstant(0, DL, Ty);
3086 return true;
3087 }
3088
3089 if (((Imm % 256) == 0) && (Imm >= -32768) && (Imm <= 32512)) {
3090 Base = CurDAG->getTargetConstant(Imm/256, DL, Ty);
3091 Offset = CurDAG->getTargetConstant(8, DL, Ty);
3092 return true;
3093 }
3094
3095 return false;
3096}
3097
3098bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift) {
3099 if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
3100 const int64_t ImmVal = CNode->getZExtValue();
3101 SDLoc DL(N);
3102
3103 switch (VT.SimpleTy) {
3104 case MVT::i8:
3105 if ((ImmVal & 0xFF) == ImmVal) {
3106 Shift = CurDAG->getTargetConstant(0, DL, MVT::i32);
3107 Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32);
3108 return true;
3109 }
3110 break;
3111 case MVT::i16:
3112 case MVT::i32:
3113 case MVT::i64:
3114 if ((ImmVal & 0xFF) == ImmVal) {
3115 Shift = CurDAG->getTargetConstant(0, DL, MVT::i32);
3116 Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32);
3117 return true;
3118 } else if ((ImmVal & 0xFF00) == ImmVal) {
3119 Shift = CurDAG->getTargetConstant(8, DL, MVT::i32);
3120 Imm = CurDAG->getTargetConstant(ImmVal >> 8, DL, MVT::i32);
3121 return true;
3122 }
3123 break;
3124 default:
3125 break;
3126 }
3127 }
3128
3129 return false;
3130}
3131
3132bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue N, SDValue &Imm) {
3133 if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
3134 int64_t ImmVal = CNode->getSExtValue();
3135 SDLoc DL(N);
3136 if (ImmVal >= -128 && ImmVal < 128) {
3137 Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32);
3138 return true;
3139 }
3140 }
3141 return false;
3142}
3143
3144bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm) {
3145 if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
3146 uint64_t ImmVal = CNode->getZExtValue();
3147
3148 switch (VT.SimpleTy) {
3149 case MVT::i8:
3150 ImmVal &= 0xFF;
3151 break;
3152 case MVT::i16:
3153 ImmVal &= 0xFFFF;
3154 break;
3155 case MVT::i32:
3156 ImmVal &= 0xFFFFFFFF;
3157 break;
3158 case MVT::i64:
3159 break;
3160 default:
3161 llvm_unreachable("Unexpected type")::llvm::llvm_unreachable_internal("Unexpected type", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3161)
;
3162 }
3163
3164 if (ImmVal < 256) {
3165 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32);
3166 return true;
3167 }
3168 }
3169 return false;
3170}
3171
3172bool AArch64DAGToDAGISel::SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm) {
3173 if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
3174 uint64_t ImmVal = CNode->getZExtValue();
3175 SDLoc DL(N);
3176
3177 // Shift mask depending on type size.
3178 switch (VT.SimpleTy) {
3179 case MVT::i8:
3180 ImmVal &= 0xFF;
3181 ImmVal |= ImmVal << 8;
3182 ImmVal |= ImmVal << 16;
3183 ImmVal |= ImmVal << 32;
3184 break;
3185 case MVT::i16:
3186 ImmVal &= 0xFFFF;
3187 ImmVal |= ImmVal << 16;
3188 ImmVal |= ImmVal << 32;
3189 break;
3190 case MVT::i32:
3191 ImmVal &= 0xFFFFFFFF;
3192 ImmVal |= ImmVal << 32;
3193 break;
3194 case MVT::i64:
3195 break;
3196 default:
3197 llvm_unreachable("Unexpected type")::llvm::llvm_unreachable_internal("Unexpected type", "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3197)
;
3198 }
3199
3200 uint64_t encoding;
3201 if (AArch64_AM::processLogicalImmediate(ImmVal, 64, encoding)) {
3202 Imm = CurDAG->getTargetConstant(encoding, DL, MVT::i64);
3203 return true;
3204 }
3205 }
3206 return false;
3207}
3208
3209// SVE shift intrinsics allow shift amounts larger than the element's bitwidth.
3210// Rather than attempt to normalise everything we can sometimes saturate the
3211// shift amount during selection. This function also allows for consistent
3212// isel patterns by ensuring the resulting "Imm" node is of the i32 type
3213// required by the instructions.
3214bool AArch64DAGToDAGISel::SelectSVEShiftImm(SDValue N, uint64_t Low,
3215 uint64_t High, bool AllowSaturation,
3216 SDValue &Imm) {
3217 if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
3218 uint64_t ImmVal = CN->getZExtValue();
3219
3220 // Reject shift amounts that are too small.
3221 if (ImmVal < Low)
3222 return false;
3223
3224 // Reject or saturate shift amounts that are too big.
3225 if (ImmVal > High) {
3226 if (!AllowSaturation)
3227 return false;
3228 ImmVal = High;
3229 }
3230
3231 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32);
3232 return true;
3233 }
3234
3235 return false;
3236}
3237
3238bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *N) {
3239 // tagp(FrameIndex, IRGstack, tag_offset):
3240 // since the offset between FrameIndex and IRGstack is a compile-time
3241 // constant, this can be lowered to a single ADDG instruction.
3242 if (!(isa<FrameIndexSDNode>(N->getOperand(1)))) {
3243 return false;
3244 }
3245
3246 SDValue IRG_SP = N->getOperand(2);
3247 if (IRG_SP->getOpcode() != ISD::INTRINSIC_W_CHAIN ||
3248 cast<ConstantSDNode>(IRG_SP->getOperand(1))->getZExtValue() !=
3249 Intrinsic::aarch64_irg_sp) {
3250 return false;
3251 }
3252
3253 const TargetLowering *TLI = getTargetLowering();
3254 SDLoc DL(N);
3255 int FI = cast<FrameIndexSDNode>(N->getOperand(1))->getIndex();
3256 SDValue FiOp = CurDAG->getTargetFrameIndex(
3257 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
3258 int TagOffset = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue();
3259
3260 SDNode *Out = CurDAG->getMachineNode(
3261 AArch64::TAGPstack, DL, MVT::i64,
3262 {FiOp, CurDAG->getTargetConstant(0, DL, MVT::i64), N->getOperand(2),
3263 CurDAG->getTargetConstant(TagOffset, DL, MVT::i64)});
3264 ReplaceNode(N, Out);
3265 return true;
3266}
3267
3268void AArch64DAGToDAGISel::SelectTagP(SDNode *N) {
3269 assert(isa<ConstantSDNode>(N->getOperand(3)) &&((isa<ConstantSDNode>(N->getOperand(3)) && "llvm.aarch64.tagp third argument must be an immediate"
) ? static_cast<void> (0) : __assert_fail ("isa<ConstantSDNode>(N->getOperand(3)) && \"llvm.aarch64.tagp third argument must be an immediate\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3270, __PRETTY_FUNCTION__))
3270 "llvm.aarch64.tagp third argument must be an immediate")((isa<ConstantSDNode>(N->getOperand(3)) && "llvm.aarch64.tagp third argument must be an immediate"
) ? static_cast<void> (0) : __assert_fail ("isa<ConstantSDNode>(N->getOperand(3)) && \"llvm.aarch64.tagp third argument must be an immediate\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3270, __PRETTY_FUNCTION__))
;
3271 if (trySelectStackSlotTagP(N))
3272 return;
3273 // FIXME: above applies in any case when offset between Op1 and Op2 is a
3274 // compile-time constant, not just for stack allocations.
3275
3276 // General case for unrelated pointers in Op1 and Op2.
3277 SDLoc DL(N);
3278 int TagOffset = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue();
3279 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP, DL, MVT::i64,
3280 {N->getOperand(1), N->getOperand(2)});
3281 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr, DL, MVT::i64,
3282 {SDValue(N1, 0), N->getOperand(2)});
3283 SDNode *N3 = CurDAG->getMachineNode(
3284 AArch64::ADDG, DL, MVT::i64,
3285 {SDValue(N2, 0), CurDAG->getTargetConstant(0, DL, MVT::i64),
3286 CurDAG->getTargetConstant(TagOffset, DL, MVT::i64)});
3287 ReplaceNode(N, N3);
3288}
3289
3290// NOTE: We cannot use EXTRACT_SUBREG in all cases because the fixed length
3291// vector types larger than NEON don't have a matching SubRegIndex.
3292static SDNode *extractSubReg(SelectionDAG *DAG, EVT VT, SDValue V) {
3293 assert(V.getValueType().isScalableVector() &&((V.getValueType().isScalableVector() && V.getValueType
().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock
&& "Expected to extract from a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("V.getValueType().isScalableVector() && V.getValueType().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to extract from a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3296, __PRETTY_FUNCTION__))
3294 V.getValueType().getSizeInBits().getKnownMinSize() ==((V.getValueType().isScalableVector() && V.getValueType
().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock
&& "Expected to extract from a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("V.getValueType().isScalableVector() && V.getValueType().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to extract from a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3296, __PRETTY_FUNCTION__))
3295 AArch64::SVEBitsPerBlock &&((V.getValueType().isScalableVector() && V.getValueType
().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock
&& "Expected to extract from a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("V.getValueType().isScalableVector() && V.getValueType().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to extract from a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3296, __PRETTY_FUNCTION__))
3296 "Expected to extract from a packed scalable vector!")((V.getValueType().isScalableVector() && V.getValueType
().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock
&& "Expected to extract from a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("V.getValueType().isScalableVector() && V.getValueType().getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to extract from a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3296, __PRETTY_FUNCTION__))
;
3297 assert(VT.isFixedLengthVector() &&((VT.isFixedLengthVector() && "Expected to extract a fixed length vector!"
) ? static_cast<void> (0) : __assert_fail ("VT.isFixedLengthVector() && \"Expected to extract a fixed length vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3298, __PRETTY_FUNCTION__))
3298 "Expected to extract a fixed length vector!")((VT.isFixedLengthVector() && "Expected to extract a fixed length vector!"
) ? static_cast<void> (0) : __assert_fail ("VT.isFixedLengthVector() && \"Expected to extract a fixed length vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3298, __PRETTY_FUNCTION__))
;
3299
3300 SDLoc DL(V);
3301 switch (VT.getSizeInBits()) {
3302 case 64: {
3303 auto SubReg = DAG->getTargetConstant(AArch64::dsub, DL, MVT::i32);
3304 return DAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, V, SubReg);
3305 }
3306 case 128: {
3307 auto SubReg = DAG->getTargetConstant(AArch64::zsub, DL, MVT::i32);
3308 return DAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, V, SubReg);
3309 }
3310 default: {
3311 auto RC = DAG->getTargetConstant(AArch64::ZPRRegClassID, DL, MVT::i64);
3312 return DAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
3313 }
3314 }
3315}
3316
3317// NOTE: We cannot use INSERT_SUBREG in all cases because the fixed length
3318// vector types larger than NEON don't have a matching SubRegIndex.
3319static SDNode *insertSubReg(SelectionDAG *DAG, EVT VT, SDValue V) {
3320 assert(VT.isScalableVector() &&((VT.isScalableVector() && VT.getSizeInBits().getKnownMinSize
() == AArch64::SVEBitsPerBlock && "Expected to insert into a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("VT.isScalableVector() && VT.getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to insert into a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3322, __PRETTY_FUNCTION__))
3321 VT.getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock &&((VT.isScalableVector() && VT.getSizeInBits().getKnownMinSize
() == AArch64::SVEBitsPerBlock && "Expected to insert into a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("VT.isScalableVector() && VT.getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to insert into a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3322, __PRETTY_FUNCTION__))
3322 "Expected to insert into a packed scalable vector!")((VT.isScalableVector() && VT.getSizeInBits().getKnownMinSize
() == AArch64::SVEBitsPerBlock && "Expected to insert into a packed scalable vector!"
) ? static_cast<void> (0) : __assert_fail ("VT.isScalableVector() && VT.getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && \"Expected to insert into a packed scalable vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3322, __PRETTY_FUNCTION__))
;
3323 assert(V.getValueType().isFixedLengthVector() &&((V.getValueType().isFixedLengthVector() && "Expected to insert a fixed length vector!"
) ? static_cast<void> (0) : __assert_fail ("V.getValueType().isFixedLengthVector() && \"Expected to insert a fixed length vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3324, __PRETTY_FUNCTION__))
3324 "Expected to insert a fixed length vector!")((V.getValueType().isFixedLengthVector() && "Expected to insert a fixed length vector!"
) ? static_cast<void> (0) : __assert_fail ("V.getValueType().isFixedLengthVector() && \"Expected to insert a fixed length vector!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 3324, __PRETTY_FUNCTION__))
;
3325
3326 SDLoc DL(V);
3327 switch (V.getValueType().getSizeInBits()) {
3328 case 64: {
3329 auto SubReg = DAG->getTargetConstant(AArch64::dsub, DL, MVT::i32);
3330 auto Container = DAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
3331 return DAG->getMachineNode(TargetOpcode::INSERT_SUBREG, DL, VT,
3332 SDValue(Container, 0), V, SubReg);
3333 }
3334 case 128: {
3335 auto SubReg = DAG->getTargetConstant(AArch64::zsub, DL, MVT::i32);
3336 auto Container = DAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
3337 return DAG->getMachineNode(TargetOpcode::INSERT_SUBREG, DL, VT,
3338 SDValue(Container, 0), V, SubReg);
3339 }
3340 default: {
3341 auto RC = DAG->getTargetConstant(AArch64::ZPRRegClassID, DL, MVT::i64);
3342 return DAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
3343 }
3344 }
3345}
3346
3347void AArch64DAGToDAGISel::Select(SDNode *Node) {
3348 // If we have a custom node, we already have selected!
3349 if (Node->isMachineOpcode()) {
3350 LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("aarch64-isel")) { errs() << "== "; Node->dump(CurDAG
); errs() << "\n"; } } while (false)
;
3351 Node->setNodeId(-1);
3352 return;
3353 }
3354
3355 // Few custom selection stuff.
3356 EVT VT = Node->getValueType(0);
3357
3358 switch (Node->getOpcode()) {
3359 default:
3360 break;
3361
3362 case ISD::ATOMIC_CMP_SWAP:
3363 if (SelectCMP_SWAP(Node))
3364 return;
3365 break;
3366
3367 case ISD::READ_REGISTER:
3368 if (tryReadRegister(Node))
3369 return;
3370 break;
3371
3372 case ISD::WRITE_REGISTER:
3373 if (tryWriteRegister(Node))
3374 return;
3375 break;
3376
3377 case ISD::ADD:
3378 if (tryMLAV64LaneV128(Node))
3379 return;
3380 break;
3381
3382 case ISD::LOAD: {
3383 // Try to select as an indexed load. Fall through to normal processing
3384 // if we can't.
3385 if (tryIndexedLoad(Node))
3386 return;
3387 break;
3388 }
3389
3390 case ISD::SRL:
3391 case ISD::AND:
3392 case ISD::SRA:
3393 case ISD::SIGN_EXTEND_INREG:
3394 if (tryBitfieldExtractOp(Node))
3395 return;
3396 if (tryBitfieldInsertInZeroOp(Node))
3397 return;
3398 LLVM_FALLTHROUGH[[gnu::fallthrough]];
3399 case ISD::ROTR:
3400 case ISD::SHL:
3401 if (tryShiftAmountMod(Node))
3402 return;
3403 break;
3404
3405 case ISD::SIGN_EXTEND:
3406 if (tryBitfieldExtractOpFromSExt(Node))
3407 return;
3408 break;
3409
3410 case ISD::FP_EXTEND:
3411 if (tryHighFPExt(Node))
3412 return;
3413 break;
3414
3415 case ISD::OR:
3416 if (tryBitfieldInsertOp(Node))
3417 return;
3418 break;
3419
3420 case ISD::EXTRACT_SUBVECTOR: {
3421 // Bail when not a "cast" like extract_subvector.
3422 if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue() != 0)
3423 break;
3424
3425 // Bail when normal isel can do the job.
3426 EVT InVT = Node->getOperand(0).getValueType();
3427 if (VT.isScalableVector() || InVT.isFixedLengthVector())
3428 break;
3429
3430 // NOTE: We can only get here when doing fixed length SVE code generation.
3431 // We do manual selection because the types involved are not linked to real
3432 // registers (despite being legal) and must be coerced into SVE registers.
3433 //
3434 // NOTE: If the above changes, be aware that selection will still not work
3435 // because the td definition of extract_vector does not support extracting
3436 // a fixed length vector from a scalable vector.
3437
3438 ReplaceNode(Node, extractSubReg(CurDAG, VT, Node->getOperand(0)));
3439 return;
3440 }
3441
3442 case ISD::INSERT_SUBVECTOR: {
3443 // Bail when not a "cast" like insert_subvector.
3444 if (cast<ConstantSDNode>(Node->getOperand(2))->getZExtValue() != 0)
3445 break;
3446 if (!Node->getOperand(0).isUndef())
3447 break;
3448
3449 // Bail when normal isel should do the job.
3450 EVT InVT = Node->getOperand(1).getValueType();
3451 if (VT.isFixedLengthVector() || InVT.isScalableVector())
3452 break;
3453
3454 // NOTE: We can only get here when doing fixed length SVE code generation.
3455 // We do manual selection because the types involved are not linked to real
3456 // registers (despite being legal) and must be coerced into SVE registers.
3457 //
3458 // NOTE: If the above changes, be aware that selection will still not work
3459 // because the td definition of insert_vector does not support inserting a
3460 // fixed length vector into a scalable vector.
3461
3462 ReplaceNode(Node, insertSubReg(CurDAG, VT, Node->getOperand(1)));
3463 return;
3464 }
3465
3466 case ISD::Constant: {
3467 // Materialize zero constants as copies from WZR/XZR. This allows
3468 // the coalescer to propagate these into other instructions.
3469 ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node);
3470 if (ConstNode->isNullValue()) {
3471 if (VT == MVT::i32) {
3472 SDValue New = CurDAG->getCopyFromReg(
3473 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
3474 ReplaceNode(Node, New.getNode());
3475 return;
3476 } else if (VT == MVT::i64) {
3477 SDValue New = CurDAG->getCopyFromReg(
3478 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
3479 ReplaceNode(Node, New.getNode());
3480 return;
3481 }
3482 }
3483 break;
3484 }
3485
3486 case ISD::FrameIndex: {
3487 // Selects to ADDXri FI, 0 which in turn will become ADDXri SP, imm.
3488 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
3489 unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
3490 const TargetLowering *TLI = getTargetLowering();
3491 SDValue TFI = CurDAG->getTargetFrameIndex(
3492 FI, TLI->getPointerTy(CurDAG->getDataLayout()));
3493 SDLoc DL(Node);
3494 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, DL, MVT::i32),
3495 CurDAG->getTargetConstant(Shifter, DL, MVT::i32) };
3496 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64, Ops);
3497 return;
3498 }
3499 case ISD::INTRINSIC_W_CHAIN: {
3500 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
3501 switch (IntNo) {
3502 default:
3503 break;
3504 case Intrinsic::aarch64_ldaxp:
3505 case Intrinsic::aarch64_ldxp: {
3506 unsigned Op =
3507 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
3508 SDValue MemAddr = Node->getOperand(2);
3509 SDLoc DL(Node);
3510 SDValue Chain = Node->getOperand(0);
3511
3512 SDNode *Ld = CurDAG->getMachineNode(Op, DL, MVT::i64, MVT::i64,
3513 MVT::Other, MemAddr, Chain);
3514
3515 // Transfer memoperands.
3516 MachineMemOperand *MemOp =
3517 cast<MemIntrinsicSDNode>(Node)->getMemOperand();
3518 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp});
3519 ReplaceNode(Node, Ld);
3520 return;
3521 }
3522 case Intrinsic::aarch64_stlxp:
3523 case Intrinsic::aarch64_stxp: {
3524 unsigned Op =
3525 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
3526 SDLoc DL(Node);
3527 SDValue Chain = Node->getOperand(0);
3528 SDValue ValLo = Node->getOperand(2);
3529 SDValue ValHi = Node->getOperand(3);
3530 SDValue MemAddr = Node->getOperand(4);
3531
3532 // Place arguments in the right order.
3533 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
3534
3535 SDNode *St = CurDAG->getMachineNode(Op, DL, MVT::i32, MVT::Other, Ops);
3536 // Transfer memoperands.
3537 MachineMemOperand *MemOp =
3538 cast<MemIntrinsicSDNode>(Node)->getMemOperand();
3539 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp});
3540
3541 ReplaceNode(Node, St);
3542 return;
3543 }
3544 case Intrinsic::aarch64_neon_ld1x2:
3545 if (VT == MVT::v8i8) {
3546 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
3547 return;
3548 } else if (VT == MVT::v16i8) {
3549 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
3550 return;
3551 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3552 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
3553 return;
3554 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3555 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
3556 return;
3557 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3558 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
3559 return;
3560 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3561 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
3562 return;
3563 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3564 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
3565 return;
3566 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3567 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
3568 return;
3569 }
3570 break;
3571 case Intrinsic::aarch64_neon_ld1x3:
3572 if (VT == MVT::v8i8) {
3573 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
3574 return;
3575 } else if (VT == MVT::v16i8) {
3576 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
3577 return;
3578 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3579 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
3580 return;
3581 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3582 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
3583 return;
3584 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3585 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
3586 return;
3587 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3588 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
3589 return;
3590 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3591 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
3592 return;
3593 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3594 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
3595 return;
3596 }
3597 break;
3598 case Intrinsic::aarch64_neon_ld1x4:
3599 if (VT == MVT::v8i8) {
3600 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
3601 return;
3602 } else if (VT == MVT::v16i8) {
3603 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
3604 return;
3605 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3606 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
3607 return;
3608 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3609 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
3610 return;
3611 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3612 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
3613 return;
3614 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3615 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
3616 return;
3617 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3618 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
3619 return;
3620 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3621 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
3622 return;
3623 }
3624 break;
3625 case Intrinsic::aarch64_neon_ld2:
3626 if (VT == MVT::v8i8) {
3627 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
3628 return;
3629 } else if (VT == MVT::v16i8) {
3630 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
3631 return;
3632 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3633 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
3634 return;
3635 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3636 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
3637 return;
3638 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3639 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
3640 return;
3641 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3642 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
3643 return;
3644 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3645 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
3646 return;
3647 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3648 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
3649 return;
3650 }
3651 break;
3652 case Intrinsic::aarch64_neon_ld3:
3653 if (VT == MVT::v8i8) {
3654 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
3655 return;
3656 } else if (VT == MVT::v16i8) {
3657 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
3658 return;
3659 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3660 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
3661 return;
3662 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3663 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
3664 return;
3665 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3666 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
3667 return;
3668 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3669 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
3670 return;
3671 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3672 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
3673 return;
3674 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3675 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
3676 return;
3677 }
3678 break;
3679 case Intrinsic::aarch64_neon_ld4:
3680 if (VT == MVT::v8i8) {
3681 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
3682 return;
3683 } else if (VT == MVT::v16i8) {
3684 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
3685 return;
3686 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3687 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
3688 return;
3689 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3690 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
3691 return;
3692 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3693 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
3694 return;
3695 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3696 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
3697 return;
3698 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3699 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
3700 return;
3701 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3702 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
3703 return;
3704 }
3705 break;
3706 case Intrinsic::aarch64_neon_ld2r:
3707 if (VT == MVT::v8i8) {
3708 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
3709 return;
3710 } else if (VT == MVT::v16i8) {
3711 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
3712 return;
3713 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3714 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
3715 return;
3716 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3717 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
3718 return;
3719 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3720 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
3721 return;
3722 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3723 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
3724 return;
3725 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3726 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
3727 return;
3728 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3729 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
3730 return;
3731 }
3732 break;
3733 case Intrinsic::aarch64_neon_ld3r:
3734 if (VT == MVT::v8i8) {
3735 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
3736 return;
3737 } else if (VT == MVT::v16i8) {
3738 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
3739 return;
3740 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3741 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
3742 return;
3743 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3744 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
3745 return;
3746 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3747 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
3748 return;
3749 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3750 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
3751 return;
3752 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3753 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
3754 return;
3755 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3756 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
3757 return;
3758 }
3759 break;
3760 case Intrinsic::aarch64_neon_ld4r:
3761 if (VT == MVT::v8i8) {
3762 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
3763 return;
3764 } else if (VT == MVT::v16i8) {
3765 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
3766 return;
3767 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
3768 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
3769 return;
3770 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
3771 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
3772 return;
3773 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3774 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
3775 return;
3776 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3777 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
3778 return;
3779 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3780 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
3781 return;
3782 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3783 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
3784 return;
3785 }
3786 break;
3787 case Intrinsic::aarch64_neon_ld2lane:
3788 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
3789 SelectLoadLane(Node, 2, AArch64::LD2i8);
3790 return;
3791 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
3792 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
3793 SelectLoadLane(Node, 2, AArch64::LD2i16);
3794 return;
3795 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
3796 VT == MVT::v2f32) {
3797 SelectLoadLane(Node, 2, AArch64::LD2i32);
3798 return;
3799 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
3800 VT == MVT::v1f64) {
3801 SelectLoadLane(Node, 2, AArch64::LD2i64);
3802 return;
3803 }
3804 break;
3805 case Intrinsic::aarch64_neon_ld3lane:
3806 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
3807 SelectLoadLane(Node, 3, AArch64::LD3i8);
3808 return;
3809 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
3810 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
3811 SelectLoadLane(Node, 3, AArch64::LD3i16);
3812 return;
3813 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
3814 VT == MVT::v2f32) {
3815 SelectLoadLane(Node, 3, AArch64::LD3i32);
3816 return;
3817 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
3818 VT == MVT::v1f64) {
3819 SelectLoadLane(Node, 3, AArch64::LD3i64);
3820 return;
3821 }
3822 break;
3823 case Intrinsic::aarch64_neon_ld4lane:
3824 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
3825 SelectLoadLane(Node, 4, AArch64::LD4i8);
3826 return;
3827 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
3828 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
3829 SelectLoadLane(Node, 4, AArch64::LD4i16);
3830 return;
3831 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
3832 VT == MVT::v2f32) {
3833 SelectLoadLane(Node, 4, AArch64::LD4i32);
3834 return;
3835 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
3836 VT == MVT::v1f64) {
3837 SelectLoadLane(Node, 4, AArch64::LD4i64);
3838 return;
3839 }
3840 break;
3841 case Intrinsic::aarch64_ld64b:
3842 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
3843 return;
3844 }
3845 } break;
3846 case ISD::INTRINSIC_WO_CHAIN: {
3847 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue();
3848 switch (IntNo) {
3849 default:
3850 break;
3851 case Intrinsic::aarch64_tagp:
3852 SelectTagP(Node);
3853 return;
3854 case Intrinsic::aarch64_neon_tbl2:
3855 SelectTable(Node, 2,
3856 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
3857 false);
3858 return;
3859 case Intrinsic::aarch64_neon_tbl3:
3860 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
3861 : AArch64::TBLv16i8Three,
3862 false);
3863 return;
3864 case Intrinsic::aarch64_neon_tbl4:
3865 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
3866 : AArch64::TBLv16i8Four,
3867 false);
3868 return;
3869 case Intrinsic::aarch64_neon_tbx2:
3870 SelectTable(Node, 2,
3871 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
3872 true);
3873 return;
3874 case Intrinsic::aarch64_neon_tbx3:
3875 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
3876 : AArch64::TBXv16i8Three,
3877 true);
3878 return;
3879 case Intrinsic::aarch64_neon_tbx4:
3880 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
3881 : AArch64::TBXv16i8Four,
3882 true);
3883 return;
3884 case Intrinsic::aarch64_neon_smull:
3885 case Intrinsic::aarch64_neon_umull:
3886 if (tryMULLV64LaneV128(IntNo, Node))
3887 return;
3888 break;
3889 }
3890 break;
3891 }
3892 case ISD::INTRINSIC_VOID: {
3893 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
3894 if (Node->getNumOperands() >= 3)
3895 VT = Node->getOperand(2)->getValueType(0);
3896 switch (IntNo) {
3897 default:
3898 break;
3899 case Intrinsic::aarch64_neon_st1x2: {
3900 if (VT == MVT::v8i8) {
3901 SelectStore(Node, 2, AArch64::ST1Twov8b);
3902 return;
3903 } else if (VT == MVT::v16i8) {
3904 SelectStore(Node, 2, AArch64::ST1Twov16b);
3905 return;
3906 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
3907 VT == MVT::v4bf16) {
3908 SelectStore(Node, 2, AArch64::ST1Twov4h);
3909 return;
3910 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
3911 VT == MVT::v8bf16) {
3912 SelectStore(Node, 2, AArch64::ST1Twov8h);
3913 return;
3914 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3915 SelectStore(Node, 2, AArch64::ST1Twov2s);
3916 return;
3917 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3918 SelectStore(Node, 2, AArch64::ST1Twov4s);
3919 return;
3920 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3921 SelectStore(Node, 2, AArch64::ST1Twov2d);
3922 return;
3923 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3924 SelectStore(Node, 2, AArch64::ST1Twov1d);
3925 return;
3926 }
3927 break;
3928 }
3929 case Intrinsic::aarch64_neon_st1x3: {
3930 if (VT == MVT::v8i8) {
3931 SelectStore(Node, 3, AArch64::ST1Threev8b);
3932 return;
3933 } else if (VT == MVT::v16i8) {
3934 SelectStore(Node, 3, AArch64::ST1Threev16b);
3935 return;
3936 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
3937 VT == MVT::v4bf16) {
3938 SelectStore(Node, 3, AArch64::ST1Threev4h);
3939 return;
3940 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
3941 VT == MVT::v8bf16) {
3942 SelectStore(Node, 3, AArch64::ST1Threev8h);
3943 return;
3944 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3945 SelectStore(Node, 3, AArch64::ST1Threev2s);
3946 return;
3947 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3948 SelectStore(Node, 3, AArch64::ST1Threev4s);
3949 return;
3950 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3951 SelectStore(Node, 3, AArch64::ST1Threev2d);
3952 return;
3953 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3954 SelectStore(Node, 3, AArch64::ST1Threev1d);
3955 return;
3956 }
3957 break;
3958 }
3959 case Intrinsic::aarch64_neon_st1x4: {
3960 if (VT == MVT::v8i8) {
3961 SelectStore(Node, 4, AArch64::ST1Fourv8b);
3962 return;
3963 } else if (VT == MVT::v16i8) {
3964 SelectStore(Node, 4, AArch64::ST1Fourv16b);
3965 return;
3966 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
3967 VT == MVT::v4bf16) {
3968 SelectStore(Node, 4, AArch64::ST1Fourv4h);
3969 return;
3970 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
3971 VT == MVT::v8bf16) {
3972 SelectStore(Node, 4, AArch64::ST1Fourv8h);
3973 return;
3974 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
3975 SelectStore(Node, 4, AArch64::ST1Fourv2s);
3976 return;
3977 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
3978 SelectStore(Node, 4, AArch64::ST1Fourv4s);
3979 return;
3980 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
3981 SelectStore(Node, 4, AArch64::ST1Fourv2d);
3982 return;
3983 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
3984 SelectStore(Node, 4, AArch64::ST1Fourv1d);
3985 return;
3986 }
3987 break;
3988 }
3989 case Intrinsic::aarch64_neon_st2: {
3990 if (VT == MVT::v8i8) {
3991 SelectStore(Node, 2, AArch64::ST2Twov8b);
3992 return;
3993 } else if (VT == MVT::v16i8) {
3994 SelectStore(Node, 2, AArch64::ST2Twov16b);
3995 return;
3996 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
3997 VT == MVT::v4bf16) {
3998 SelectStore(Node, 2, AArch64::ST2Twov4h);
3999 return;
4000 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
4001 VT == MVT::v8bf16) {
4002 SelectStore(Node, 2, AArch64::ST2Twov8h);
4003 return;
4004 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4005 SelectStore(Node, 2, AArch64::ST2Twov2s);
4006 return;
4007 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4008 SelectStore(Node, 2, AArch64::ST2Twov4s);
4009 return;
4010 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4011 SelectStore(Node, 2, AArch64::ST2Twov2d);
4012 return;
4013 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4014 SelectStore(Node, 2, AArch64::ST1Twov1d);
4015 return;
4016 }
4017 break;
4018 }
4019 case Intrinsic::aarch64_neon_st3: {
4020 if (VT == MVT::v8i8) {
4021 SelectStore(Node, 3, AArch64::ST3Threev8b);
4022 return;
4023 } else if (VT == MVT::v16i8) {
4024 SelectStore(Node, 3, AArch64::ST3Threev16b);
4025 return;
4026 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
4027 VT == MVT::v4bf16) {
4028 SelectStore(Node, 3, AArch64::ST3Threev4h);
4029 return;
4030 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
4031 VT == MVT::v8bf16) {
4032 SelectStore(Node, 3, AArch64::ST3Threev8h);
4033 return;
4034 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4035 SelectStore(Node, 3, AArch64::ST3Threev2s);
4036 return;
4037 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4038 SelectStore(Node, 3, AArch64::ST3Threev4s);
4039 return;
4040 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4041 SelectStore(Node, 3, AArch64::ST3Threev2d);
4042 return;
4043 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4044 SelectStore(Node, 3, AArch64::ST1Threev1d);
4045 return;
4046 }
4047 break;
4048 }
4049 case Intrinsic::aarch64_neon_st4: {
4050 if (VT == MVT::v8i8) {
4051 SelectStore(Node, 4, AArch64::ST4Fourv8b);
4052 return;
4053 } else if (VT == MVT::v16i8) {
4054 SelectStore(Node, 4, AArch64::ST4Fourv16b);
4055 return;
4056 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
4057 VT == MVT::v4bf16) {
4058 SelectStore(Node, 4, AArch64::ST4Fourv4h);
4059 return;
4060 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
4061 VT == MVT::v8bf16) {
4062 SelectStore(Node, 4, AArch64::ST4Fourv8h);
4063 return;
4064 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4065 SelectStore(Node, 4, AArch64::ST4Fourv2s);
4066 return;
4067 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4068 SelectStore(Node, 4, AArch64::ST4Fourv4s);
4069 return;
4070 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4071 SelectStore(Node, 4, AArch64::ST4Fourv2d);
4072 return;
4073 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4074 SelectStore(Node, 4, AArch64::ST1Fourv1d);
4075 return;
4076 }
4077 break;
4078 }
4079 case Intrinsic::aarch64_neon_st2lane: {
4080 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4081 SelectStoreLane(Node, 2, AArch64::ST2i8);
4082 return;
4083 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4084 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4085 SelectStoreLane(Node, 2, AArch64::ST2i16);
4086 return;
4087 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4088 VT == MVT::v2f32) {
4089 SelectStoreLane(Node, 2, AArch64::ST2i32);
4090 return;
4091 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4092 VT == MVT::v1f64) {
4093 SelectStoreLane(Node, 2, AArch64::ST2i64);
4094 return;
4095 }
4096 break;
4097 }
4098 case Intrinsic::aarch64_neon_st3lane: {
4099 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4100 SelectStoreLane(Node, 3, AArch64::ST3i8);
4101 return;
4102 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4103 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4104 SelectStoreLane(Node, 3, AArch64::ST3i16);
4105 return;
4106 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4107 VT == MVT::v2f32) {
4108 SelectStoreLane(Node, 3, AArch64::ST3i32);
4109 return;
4110 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4111 VT == MVT::v1f64) {
4112 SelectStoreLane(Node, 3, AArch64::ST3i64);
4113 return;
4114 }
4115 break;
4116 }
4117 case Intrinsic::aarch64_neon_st4lane: {
4118 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4119 SelectStoreLane(Node, 4, AArch64::ST4i8);
4120 return;
4121 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4122 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4123 SelectStoreLane(Node, 4, AArch64::ST4i16);
4124 return;
4125 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4126 VT == MVT::v2f32) {
4127 SelectStoreLane(Node, 4, AArch64::ST4i32);
4128 return;
4129 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4130 VT == MVT::v1f64) {
4131 SelectStoreLane(Node, 4, AArch64::ST4i64);
4132 return;
4133 }
4134 break;
4135 }
4136 case Intrinsic::aarch64_sve_st2: {
4137 if (VT == MVT::nxv16i8) {
4138 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
4139 return;
4140 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
4141 (VT == MVT::nxv8bf16 && Subtarget->hasBF16())) {
4142 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
4143 return;
4144 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
4145 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
4146 return;
4147 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
4148 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
4149 return;
4150 }
4151 break;
4152 }
4153 case Intrinsic::aarch64_sve_st3: {
4154 if (VT == MVT::nxv16i8) {
4155 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
4156 return;
4157 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
4158 (VT == MVT::nxv8bf16 && Subtarget->hasBF16())) {
4159 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
4160 return;
4161 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
4162 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
4163 return;
4164 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
4165 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
4166 return;
4167 }
4168 break;
4169 }
4170 case Intrinsic::aarch64_sve_st4: {
4171 if (VT == MVT::nxv16i8) {
4172 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
4173 return;
4174 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
4175 (VT == MVT::nxv8bf16 && Subtarget->hasBF16())) {
4176 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
4177 return;
4178 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
4179 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
4180 return;
4181 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
4182 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
4183 return;
4184 }
4185 break;
4186 }
4187 }
4188 break;
4189 }
4190 case AArch64ISD::LD2post: {
4191 if (VT == MVT::v8i8) {
4192 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
4193 return;
4194 } else if (VT == MVT::v16i8) {
4195 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
4196 return;
4197 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4198 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
4199 return;
4200 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4201 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
4202 return;
4203 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4204 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
4205 return;
4206 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4207 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
4208 return;
4209 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4210 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
4211 return;
4212 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4213 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
4214 return;
4215 }
4216 break;
4217 }
4218 case AArch64ISD::LD3post: {
4219 if (VT == MVT::v8i8) {
4220 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
4221 return;
4222 } else if (VT == MVT::v16i8) {
4223 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
4224 return;
4225 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4226 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
4227 return;
4228 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4229 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
4230 return;
4231 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4232 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
4233 return;
4234 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4235 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
4236 return;
4237 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4238 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
4239 return;
4240 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4241 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
4242 return;
4243 }
4244 break;
4245 }
4246 case AArch64ISD::LD4post: {
4247 if (VT == MVT::v8i8) {
4248 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
4249 return;
4250 } else if (VT == MVT::v16i8) {
4251 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
4252 return;
4253 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4254 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
4255 return;
4256 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4257 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
4258 return;
4259 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4260 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
4261 return;
4262 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4263 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
4264 return;
4265 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4266 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
4267 return;
4268 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4269 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
4270 return;
4271 }
4272 break;
4273 }
4274 case AArch64ISD::LD1x2post: {
4275 if (VT == MVT::v8i8) {
4276 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
4277 return;
4278 } else if (VT == MVT::v16i8) {
4279 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
4280 return;
4281 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4282 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
4283 return;
4284 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4285 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
4286 return;
4287 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4288 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
4289 return;
4290 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4291 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
4292 return;
4293 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4294 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
4295 return;
4296 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4297 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
4298 return;
4299 }
4300 break;
4301 }
4302 case AArch64ISD::LD1x3post: {
4303 if (VT == MVT::v8i8) {
4304 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
4305 return;
4306 } else if (VT == MVT::v16i8) {
4307 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
4308 return;
4309 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4310 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
4311 return;
4312 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4313 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
4314 return;
4315 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4316 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
4317 return;
4318 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4319 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
4320 return;
4321 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4322 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
4323 return;
4324 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4325 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
4326 return;
4327 }
4328 break;
4329 }
4330 case AArch64ISD::LD1x4post: {
4331 if (VT == MVT::v8i8) {
4332 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
4333 return;
4334 } else if (VT == MVT::v16i8) {
4335 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
4336 return;
4337 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4338 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
4339 return;
4340 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4341 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
4342 return;
4343 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4344 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
4345 return;
4346 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4347 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
4348 return;
4349 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4350 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
4351 return;
4352 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4353 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
4354 return;
4355 }
4356 break;
4357 }
4358 case AArch64ISD::LD1DUPpost: {
4359 if (VT == MVT::v8i8) {
4360 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
4361 return;
4362 } else if (VT == MVT::v16i8) {
4363 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
4364 return;
4365 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4366 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
4367 return;
4368 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4369 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
4370 return;
4371 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4372 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
4373 return;
4374 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4375 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
4376 return;
4377 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4378 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
4379 return;
4380 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4381 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
4382 return;
4383 }
4384 break;
4385 }
4386 case AArch64ISD::LD2DUPpost: {
4387 if (VT == MVT::v8i8) {
4388 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
4389 return;
4390 } else if (VT == MVT::v16i8) {
4391 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
4392 return;
4393 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4394 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
4395 return;
4396 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4397 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
4398 return;
4399 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4400 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
4401 return;
4402 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4403 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
4404 return;
4405 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4406 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
4407 return;
4408 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4409 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
4410 return;
4411 }
4412 break;
4413 }
4414 case AArch64ISD::LD3DUPpost: {
4415 if (VT == MVT::v8i8) {
4416 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
4417 return;
4418 } else if (VT == MVT::v16i8) {
4419 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
4420 return;
4421 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4422 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
4423 return;
4424 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4425 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
4426 return;
4427 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4428 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
4429 return;
4430 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4431 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
4432 return;
4433 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4434 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
4435 return;
4436 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4437 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
4438 return;
4439 }
4440 break;
4441 }
4442 case AArch64ISD::LD4DUPpost: {
4443 if (VT == MVT::v8i8) {
4444 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
4445 return;
4446 } else if (VT == MVT::v16i8) {
4447 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
4448 return;
4449 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4450 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
4451 return;
4452 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4453 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
4454 return;
4455 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4456 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
4457 return;
4458 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4459 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
4460 return;
4461 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4462 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
4463 return;
4464 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4465 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
4466 return;
4467 }
4468 break;
4469 }
4470 case AArch64ISD::LD1LANEpost: {
4471 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4472 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
4473 return;
4474 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4475 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4476 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
4477 return;
4478 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4479 VT == MVT::v2f32) {
4480 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
4481 return;
4482 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4483 VT == MVT::v1f64) {
4484 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
4485 return;
4486 }
4487 break;
4488 }
4489 case AArch64ISD::LD2LANEpost: {
4490 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4491 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
4492 return;
4493 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4494 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4495 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
4496 return;
4497 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4498 VT == MVT::v2f32) {
4499 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
4500 return;
4501 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4502 VT == MVT::v1f64) {
4503 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
4504 return;
4505 }
4506 break;
4507 }
4508 case AArch64ISD::LD3LANEpost: {
4509 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4510 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
4511 return;
4512 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4513 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4514 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
4515 return;
4516 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4517 VT == MVT::v2f32) {
4518 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
4519 return;
4520 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4521 VT == MVT::v1f64) {
4522 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
4523 return;
4524 }
4525 break;
4526 }
4527 case AArch64ISD::LD4LANEpost: {
4528 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4529 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
4530 return;
4531 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4532 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4533 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
4534 return;
4535 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4536 VT == MVT::v2f32) {
4537 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
4538 return;
4539 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4540 VT == MVT::v1f64) {
4541 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
4542 return;
4543 }
4544 break;
4545 }
4546 case AArch64ISD::ST2post: {
4547 VT = Node->getOperand(1).getValueType();
4548 if (VT == MVT::v8i8) {
4549 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
4550 return;
4551 } else if (VT == MVT::v16i8) {
4552 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
4553 return;
4554 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4555 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
4556 return;
4557 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4558 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
4559 return;
4560 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4561 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
4562 return;
4563 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4564 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
4565 return;
4566 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4567 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
4568 return;
4569 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4570 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
4571 return;
4572 }
4573 break;
4574 }
4575 case AArch64ISD::ST3post: {
4576 VT = Node->getOperand(1).getValueType();
4577 if (VT == MVT::v8i8) {
4578 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
4579 return;
4580 } else if (VT == MVT::v16i8) {
4581 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
4582 return;
4583 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4584 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
4585 return;
4586 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4587 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
4588 return;
4589 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4590 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
4591 return;
4592 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4593 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
4594 return;
4595 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4596 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
4597 return;
4598 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4599 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
4600 return;
4601 }
4602 break;
4603 }
4604 case AArch64ISD::ST4post: {
4605 VT = Node->getOperand(1).getValueType();
4606 if (VT == MVT::v8i8) {
4607 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
4608 return;
4609 } else if (VT == MVT::v16i8) {
4610 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
4611 return;
4612 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4613 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
4614 return;
4615 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4616 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
4617 return;
4618 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4619 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
4620 return;
4621 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4622 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
4623 return;
4624 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4625 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
4626 return;
4627 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4628 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
4629 return;
4630 }
4631 break;
4632 }
4633 case AArch64ISD::ST1x2post: {
4634 VT = Node->getOperand(1).getValueType();
4635 if (VT == MVT::v8i8) {
4636 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
4637 return;
4638 } else if (VT == MVT::v16i8) {
4639 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
4640 return;
4641 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4642 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
4643 return;
4644 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4645 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
4646 return;
4647 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4648 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
4649 return;
4650 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4651 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
4652 return;
4653 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4654 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
4655 return;
4656 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4657 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
4658 return;
4659 }
4660 break;
4661 }
4662 case AArch64ISD::ST1x3post: {
4663 VT = Node->getOperand(1).getValueType();
4664 if (VT == MVT::v8i8) {
4665 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
4666 return;
4667 } else if (VT == MVT::v16i8) {
4668 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
4669 return;
4670 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4671 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
4672 return;
4673 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
4674 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
4675 return;
4676 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4677 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
4678 return;
4679 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4680 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
4681 return;
4682 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4683 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
4684 return;
4685 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4686 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
4687 return;
4688 }
4689 break;
4690 }
4691 case AArch64ISD::ST1x4post: {
4692 VT = Node->getOperand(1).getValueType();
4693 if (VT == MVT::v8i8) {
4694 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
4695 return;
4696 } else if (VT == MVT::v16i8) {
4697 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
4698 return;
4699 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4700 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
4701 return;
4702 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4703 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
4704 return;
4705 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4706 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
4707 return;
4708 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4709 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
4710 return;
4711 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4712 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
4713 return;
4714 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4715 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
4716 return;
4717 }
4718 break;
4719 }
4720 case AArch64ISD::ST2LANEpost: {
4721 VT = Node->getOperand(1).getValueType();
4722 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4723 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
4724 return;
4725 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4726 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4727 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
4728 return;
4729 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4730 VT == MVT::v2f32) {
4731 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
4732 return;
4733 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4734 VT == MVT::v1f64) {
4735 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
4736 return;
4737 }
4738 break;
4739 }
4740 case AArch64ISD::ST3LANEpost: {
4741 VT = Node->getOperand(1).getValueType();
4742 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4743 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
4744 return;
4745 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4746 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4747 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
4748 return;
4749 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4750 VT == MVT::v2f32) {
4751 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
4752 return;
4753 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4754 VT == MVT::v1f64) {
4755 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
4756 return;
4757 }
4758 break;
4759 }
4760 case AArch64ISD::ST4LANEpost: {
4761 VT = Node->getOperand(1).getValueType();
4762 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4763 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
4764 return;
4765 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4766 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4767 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
4768 return;
4769 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4770 VT == MVT::v2f32) {
4771 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
4772 return;
4773 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4774 VT == MVT::v1f64) {
4775 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
4776 return;
4777 }
4778 break;
4779 }
4780 case AArch64ISD::SVE_LD2_MERGE_ZERO: {
4781 if (VT == MVT::nxv16i8) {
4782 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B);
4783 return;
4784 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
4785 (VT == MVT::nxv8bf16 && Subtarget->hasBF16())) {
4786 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H);
4787 return;
4788 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
4789 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W);
4790 return;
4791 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
4792 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D);
4793 return;
4794 }
4795 break;
4796 }
4797 case AArch64ISD::SVE_LD3_MERGE_ZERO: {
4798 if (VT == MVT::nxv16i8) {
4799 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B);
4800 return;
4801 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
4802 (VT == MVT::nxv8bf16 && Subtarget->hasBF16())) {
4803 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H);
4804 return;
4805 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
4806 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W);
4807 return;
4808 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
4809 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D);
4810 return;
4811 }
4812 break;
4813 }
4814 case AArch64ISD::SVE_LD4_MERGE_ZERO: {
4815 if (VT == MVT::nxv16i8) {
4816 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B);
4817 return;
4818 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
4819 (VT == MVT::nxv8bf16 && Subtarget->hasBF16())) {
4820 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H);
4821 return;
4822 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
4823 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W);
4824 return;
4825 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
4826 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D);
4827 return;
4828 }
4829 break;
4830 }
4831 }
4832
4833 // Select the default instruction
4834 SelectCode(Node);
4835}
4836
4837/// createAArch64ISelDag - This pass converts a legalized DAG into a
4838/// AArch64-specific DAG, ready for instruction scheduling.
4839FunctionPass *llvm::createAArch64ISelDag(AArch64TargetMachine &TM,
4840 CodeGenOpt::Level OptLevel) {
4841 return new AArch64DAGToDAGISel(TM, OptLevel);
4842}
4843
4844/// When \p PredVT is a scalable vector predicate in the form
4845/// MVT::nx<M>xi1, it builds the correspondent scalable vector of
4846/// integers MVT::nx<M>xi<bits> s.t. M x bits = 128. When targeting
4847/// structured vectors (NumVec >1), the output data type is
4848/// MVT::nx<M*NumVec>xi<bits> s.t. M x bits = 128. If the input
4849/// PredVT is not in the form MVT::nx<M>xi1, it returns an invalid
4850/// EVT.
4851static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT,
4852 unsigned NumVec) {
4853 assert(NumVec > 0 && NumVec < 5 && "Invalid number of vectors.")((NumVec > 0 && NumVec < 5 && "Invalid number of vectors."
) ? static_cast<void> (0) : __assert_fail ("NumVec > 0 && NumVec < 5 && \"Invalid number of vectors.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp"
, 4853, __PRETTY_FUNCTION__))
;
4854 if (!PredVT.isScalableVector() || PredVT.getVectorElementType() != MVT::i1)
4855 return EVT();
4856
4857 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
4858 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
4859 return EVT();
4860
4861 ElementCount EC = PredVT.getVectorElementCount();
4862 EVT ScalarVT =
4863 EVT::getIntegerVT(Ctx, AArch64::SVEBitsPerBlock / EC.getKnownMinValue());
4864 EVT MemVT = EVT::getVectorVT(Ctx, ScalarVT, EC * NumVec);
4865
4866 return MemVT;
4867}
4868
4869/// Return the EVT of the data associated to a memory operation in \p
4870/// Root. If such EVT cannot be retrived, it returns an invalid EVT.
4871static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root) {
4872 if (isa<MemSDNode>(Root))
4873 return cast<MemSDNode>(Root)->getMemoryVT();
4874
4875 if (isa<MemIntrinsicSDNode>(Root))
4876 return cast<MemIntrinsicSDNode>(Root)->getMemoryVT();
4877
4878 const unsigned Opcode = Root->getOpcode();
4879 // For custom ISD nodes, we have to look at them individually to extract the
4880 // type of the data moved to/from memory.
4881 switch (Opcode) {
4882 case AArch64ISD::LD1_MERGE_ZERO:
4883 case AArch64ISD::LD1S_MERGE_ZERO:
4884 case AArch64ISD::LDNF1_MERGE_ZERO:
4885 case AArch64ISD::LDNF1S_MERGE_ZERO:
4886 return cast<VTSDNode>(Root->getOperand(3))->getVT();
4887 case AArch64ISD::ST1_PRED:
4888 return cast<VTSDNode>(Root->getOperand(4))->getVT();
4889 case AArch64ISD::SVE_LD2_MERGE_ZERO:
4890 return getPackedVectorTypeFromPredicateType(
4891 Ctx, Root->getOperand(1)->getValueType(0), /*NumVec=*/2);
4892 case AArch64ISD::SVE_LD3_MERGE_ZERO:
4893 return getPackedVectorTypeFromPredicateType(
4894 Ctx, Root->getOperand(1)->getValueType(0), /*NumVec=*/3);
4895 case AArch64ISD::SVE_LD4_MERGE_ZERO:
4896 return getPackedVectorTypeFromPredicateType(
4897 Ctx, Root->getOperand(1)->getValueType(0), /*NumVec=*/4);
4898 default:
4899 break;
4900 }
4901
4902 if (Opcode != ISD::INTRINSIC_VOID)
4903 return EVT();
4904
4905 const unsigned IntNo =
4906 cast<ConstantSDNode>(Root->getOperand(1))->getZExtValue();
4907 if (IntNo != Intrinsic::aarch64_sve_prf)
4908 return EVT();
4909
4910 // We are using an SVE prefetch intrinsic. Type must be inferred
4911 // from the width of the predicate.
4912 return getPackedVectorTypeFromPredicateType(
4913 Ctx, Root->getOperand(2)->getValueType(0), /*NumVec=*/1);
4914}
4915
4916/// SelectAddrModeIndexedSVE - Attempt selection of the addressing mode:
4917/// Base + OffImm * sizeof(MemVT) for Min >= OffImm <= Max
4918/// where Root is the memory access using N for its address.
4919template <int64_t Min, int64_t Max>
4920bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root, SDValue N,
4921 SDValue &Base,
4922 SDValue &OffImm) {
4923 const EVT MemVT = getMemVTFromNode(*(CurDAG->getContext()), Root);
4924
4925 if (MemVT == EVT())
4926 return false;
4927
4928 if (N.getOpcode() != ISD::ADD)
4929 return false;
4930
4931 SDValue VScale = N.getOperand(1);
4932 if (VScale.getOpcode() != ISD::VSCALE)
4933 return false;
4934
4935 TypeSize TS = MemVT.getSizeInBits();
4936 int64_t MemWidthBytes = static_cast<int64_t>(TS.getKnownMinSize()) / 8;
4937 int64_t MulImm = cast<ConstantSDNode>(VScale.getOperand(0))->getSExtValue();
4938
4939 if ((MulImm % MemWidthBytes) != 0)
4940 return false;
4941
4942 int64_t Offset = MulImm / MemWidthBytes;
4943 if (Offset < Min || Offset > Max)
4944 return false;
4945
4946 Base = N.getOperand(0);
4947 OffImm = CurDAG->getTargetConstant(Offset, SDLoc(N), MVT::i64);
4948 return true;
4949}
4950
4951/// Select register plus register addressing mode for SVE, with scaled
4952/// offset.
4953bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(SDValue N, unsigned Scale,
4954 SDValue &Base,
4955 SDValue &Offset) {
4956 if (N.getOpcode() != ISD::ADD)
4957 return false;
4958
4959 // Process an ADD node.
4960 const SDValue LHS = N.getOperand(0);
4961 const SDValue RHS = N.getOperand(1);
4962
4963 // 8 bit data does not come with the SHL node, so it is treated
4964 // separately.
4965 if (Scale == 0) {
4966 Base = LHS;
4967 Offset = RHS;
4968 return true;
4969 }
4970
4971 // Check if the RHS is a shift node with a constant.
4972 if (RHS.getOpcode() != ISD::SHL)
4973 return false;
4974
4975 const SDValue ShiftRHS = RHS.getOperand(1);
4976 if (auto *C = dyn_cast<ConstantSDNode>(ShiftRHS))
4977 if (C->getZExtValue() == Scale) {
4978 Base = LHS;
4979 Offset = RHS.getOperand(0);
4980 return true;
4981 }
4982
4983 return false;
4984}

/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h

1//===- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ----*- C++ -*-===//
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 file declares the SDNode class and derived classes, which are used to
10// represent the nodes and operations present in a SelectionDAG. These nodes
11// and operations are machine code level operations, with some similarities to
12// the GCC RTL representation.
13//
14// Clients should include the SelectionDAG.h file instead of this file directly.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
19#define LLVM_CODEGEN_SELECTIONDAGNODES_H
20
21#include "llvm/ADT/APFloat.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/BitVector.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/ADT/GraphTraits.h"
26#include "llvm/ADT/SmallPtrSet.h"
27#include "llvm/ADT/SmallVector.h"
28#include "llvm/ADT/ilist_node.h"
29#include "llvm/ADT/iterator.h"
30#include "llvm/ADT/iterator_range.h"
31#include "llvm/CodeGen/ISDOpcodes.h"
32#include "llvm/CodeGen/MachineMemOperand.h"
33#include "llvm/CodeGen/Register.h"
34#include "llvm/CodeGen/ValueTypes.h"
35#include "llvm/IR/Constants.h"
36#include "llvm/IR/DebugLoc.h"
37#include "llvm/IR/Instruction.h"
38#include "llvm/IR/Instructions.h"
39#include "llvm/IR/Metadata.h"
40#include "llvm/IR/Operator.h"
41#include "llvm/Support/AlignOf.h"
42#include "llvm/Support/AtomicOrdering.h"
43#include "llvm/Support/Casting.h"
44#include "llvm/Support/ErrorHandling.h"
45#include "llvm/Support/MachineValueType.h"
46#include "llvm/Support/TypeSize.h"
47#include <algorithm>
48#include <cassert>
49#include <climits>
50#include <cstddef>
51#include <cstdint>
52#include <cstring>
53#include <iterator>
54#include <string>
55#include <tuple>
56
57namespace llvm {
58
59class APInt;
60class Constant;
61template <typename T> struct DenseMapInfo;
62class GlobalValue;
63class MachineBasicBlock;
64class MachineConstantPoolValue;
65class MCSymbol;
66class raw_ostream;
67class SDNode;
68class SelectionDAG;
69class Type;
70class Value;
71
72void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
73 bool force = false);
74
75/// This represents a list of ValueType's that has been intern'd by
76/// a SelectionDAG. Instances of this simple value class are returned by
77/// SelectionDAG::getVTList(...).
78///
79struct SDVTList {
80 const EVT *VTs;
81 unsigned int NumVTs;
82};
83
84namespace ISD {
85
86 /// Node predicates
87
88/// If N is a BUILD_VECTOR or SPLAT_VECTOR node whose elements are all the
89/// same constant or undefined, return true and return the constant value in
90/// \p SplatValue.
91bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
92
93/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
94/// all of the elements are ~0 or undef. If \p BuildVectorOnly is set to
95/// true, it only checks BUILD_VECTOR.
96bool isConstantSplatVectorAllOnes(const SDNode *N,
97 bool BuildVectorOnly = false);
98
99/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
100/// all of the elements are 0 or undef. If \p BuildVectorOnly is set to true, it
101/// only checks BUILD_VECTOR.
102bool isConstantSplatVectorAllZeros(const SDNode *N,
103 bool BuildVectorOnly = false);
104
105/// Return true if the specified node is a BUILD_VECTOR where all of the
106/// elements are ~0 or undef.
107bool isBuildVectorAllOnes(const SDNode *N);
108
109/// Return true if the specified node is a BUILD_VECTOR where all of the
110/// elements are 0 or undef.
111bool isBuildVectorAllZeros(const SDNode *N);
112
113/// Return true if the specified node is a BUILD_VECTOR node of all
114/// ConstantSDNode or undef.
115bool isBuildVectorOfConstantSDNodes(const SDNode *N);
116
117/// Return true if the specified node is a BUILD_VECTOR node of all
118/// ConstantFPSDNode or undef.
119bool isBuildVectorOfConstantFPSDNodes(const SDNode *N);
120
121/// Return true if the node has at least one operand and all operands of the
122/// specified node are ISD::UNDEF.
123bool allOperandsUndef(const SDNode *N);
124
125} // end namespace ISD
126
127//===----------------------------------------------------------------------===//
128/// Unlike LLVM values, Selection DAG nodes may return multiple
129/// values as the result of a computation. Many nodes return multiple values,
130/// from loads (which define a token and a return value) to ADDC (which returns
131/// a result and a carry value), to calls (which may return an arbitrary number
132/// of values).
133///
134/// As such, each use of a SelectionDAG computation must indicate the node that
135/// computes it as well as which return value to use from that node. This pair
136/// of information is represented with the SDValue value type.
137///
138class SDValue {
139 friend struct DenseMapInfo<SDValue>;
140
141 SDNode *Node = nullptr; // The node defining the value we are using.
142 unsigned ResNo = 0; // Which return value of the node we are using.
143
144public:
145 SDValue() = default;
146 SDValue(SDNode *node, unsigned resno);
147
148 /// get the index which selects a specific result in the SDNode
149 unsigned getResNo() const { return ResNo; }
150
151 /// get the SDNode which holds the desired result
152 SDNode *getNode() const { return Node; }
153
154 /// set the SDNode
155 void setNode(SDNode *N) { Node = N; }
156
157 inline SDNode *operator->() const { return Node; }
158
159 bool operator==(const SDValue &O) const {
160 return Node == O.Node && ResNo == O.ResNo;
161 }
162 bool operator!=(const SDValue &O) const {
163 return !operator==(O);
164 }
165 bool operator<(const SDValue &O) const {
166 return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
167 }
168 explicit operator bool() const {
169 return Node != nullptr;
170 }
171
172 SDValue getValue(unsigned R) const {
173 return SDValue(Node, R);
174 }
175
176 /// Return true if this node is an operand of N.
177 bool isOperandOf(const SDNode *N) const;
178
179 /// Return the ValueType of the referenced return value.
180 inline EVT getValueType() const;
181
182 /// Return the simple ValueType of the referenced return value.
183 MVT getSimpleValueType() const {
184 return getValueType().getSimpleVT();
185 }
186
187 /// Returns the size of the value in bits.
188 ///
189 /// If the value type is a scalable vector type, the scalable property will
190 /// be set and the runtime size will be a positive integer multiple of the
191 /// base size.
192 TypeSize getValueSizeInBits() const {
193 return getValueType().getSizeInBits();
194 }
195
196 uint64_t getScalarValueSizeInBits() const {
197 return getValueType().getScalarType().getFixedSizeInBits();
198 }
199
200 // Forwarding methods - These forward to the corresponding methods in SDNode.
201 inline unsigned getOpcode() const;
202 inline unsigned getNumOperands() const;
203 inline const SDValue &getOperand(unsigned i) const;
204 inline uint64_t getConstantOperandVal(unsigned i) const;
205 inline const APInt &getConstantOperandAPInt(unsigned i) const;
206 inline bool isTargetMemoryOpcode() const;
207 inline bool isTargetOpcode() const;
208 inline bool isMachineOpcode() const;
209 inline bool isUndef() const;
210 inline unsigned getMachineOpcode() const;
211 inline const DebugLoc &getDebugLoc() const;
212 inline void dump() const;
213 inline void dump(const SelectionDAG *G) const;
214 inline void dumpr() const;
215 inline void dumpr(const SelectionDAG *G) const;
216
217 /// Return true if this operand (which must be a chain) reaches the
218 /// specified operand without crossing any side-effecting instructions.
219 /// In practice, this looks through token factors and non-volatile loads.
220 /// In order to remain efficient, this only
221 /// looks a couple of nodes in, it does not do an exhaustive search.
222 bool reachesChainWithoutSideEffects(SDValue Dest,
223 unsigned Depth = 2) const;
224
225 /// Return true if there are no nodes using value ResNo of Node.
226 inline bool use_empty() const;
227
228 /// Return true if there is exactly one node using value ResNo of Node.
229 inline bool hasOneUse() const;
230};
231
232template<> struct DenseMapInfo<SDValue> {
233 static inline SDValue getEmptyKey() {
234 SDValue V;
235 V.ResNo = -1U;
236 return V;
237 }
238
239 static inline SDValue getTombstoneKey() {
240 SDValue V;
241 V.ResNo = -2U;
242 return V;
243 }
244
245 static unsigned getHashValue(const SDValue &Val) {
246 return ((unsigned)((uintptr_t)Val.getNode() >> 4) ^
247 (unsigned)((uintptr_t)Val.getNode() >> 9)) + Val.getResNo();
248 }
249
250 static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
251 return LHS == RHS;
252 }
253};
254
255/// Allow casting operators to work directly on
256/// SDValues as if they were SDNode*'s.
257template<> struct simplify_type<SDValue> {
258 using SimpleType = SDNode *;
259
260 static SimpleType getSimplifiedValue(SDValue &Val) {
261 return Val.getNode();
262 }
263};
264template<> struct simplify_type<const SDValue> {
265 using SimpleType = /*const*/ SDNode *;
266
267 static SimpleType getSimplifiedValue(const SDValue &Val) {
268 return Val.getNode();
269 }
270};
271
272/// Represents a use of a SDNode. This class holds an SDValue,
273/// which records the SDNode being used and the result number, a
274/// pointer to the SDNode using the value, and Next and Prev pointers,
275/// which link together all the uses of an SDNode.
276///
277class SDUse {
278 /// Val - The value being used.
279 SDValue Val;
280 /// User - The user of this value.
281 SDNode *User = nullptr;
282 /// Prev, Next - Pointers to the uses list of the SDNode referred by
283 /// this operand.
284 SDUse **Prev = nullptr;
285 SDUse *Next = nullptr;
286
287public:
288 SDUse() = default;
289 SDUse(const SDUse &U) = delete;
290 SDUse &operator=(const SDUse &) = delete;
291
292 /// Normally SDUse will just implicitly convert to an SDValue that it holds.
293 operator const SDValue&() const { return Val; }
294
295 /// If implicit conversion to SDValue doesn't work, the get() method returns
296 /// the SDValue.
297 const SDValue &get() const { return Val; }
298
299 /// This returns the SDNode that contains this Use.
300 SDNode *getUser() { return User; }
301
302 /// Get the next SDUse in the use list.
303 SDUse *getNext() const { return Next; }
304
305 /// Convenience function for get().getNode().
306 SDNode *getNode() const { return Val.getNode(); }
307 /// Convenience function for get().getResNo().
308 unsigned getResNo() const { return Val.getResNo(); }
309 /// Convenience function for get().getValueType().
310 EVT getValueType() const { return Val.getValueType(); }
311
312 /// Convenience function for get().operator==
313 bool operator==(const SDValue &V) const {
314 return Val == V;
315 }
316
317 /// Convenience function for get().operator!=
318 bool operator!=(const SDValue &V) const {
319 return Val != V;
320 }
321
322 /// Convenience function for get().operator<
323 bool operator<(const SDValue &V) const {
324 return Val < V;
325 }
326
327private:
328 friend class SelectionDAG;
329 friend class SDNode;
330 // TODO: unfriend HandleSDNode once we fix its operand handling.
331 friend class HandleSDNode;
332
333 void setUser(SDNode *p) { User = p; }
334
335 /// Remove this use from its existing use list, assign it the
336 /// given value, and add it to the new value's node's use list.
337 inline void set(const SDValue &V);
338 /// Like set, but only supports initializing a newly-allocated
339 /// SDUse with a non-null value.
340 inline void setInitial(const SDValue &V);
341 /// Like set, but only sets the Node portion of the value,
342 /// leaving the ResNo portion unmodified.
343 inline void setNode(SDNode *N);
344
345 void addToList(SDUse **List) {
346 Next = *List;
347 if (Next) Next->Prev = &Next;
348 Prev = List;
349 *List = this;
350 }
351
352 void removeFromList() {
353 *Prev = Next;
354 if (Next) Next->Prev = Prev;
355 }
356};
357
358/// simplify_type specializations - Allow casting operators to work directly on
359/// SDValues as if they were SDNode*'s.
360template<> struct simplify_type<SDUse> {
361 using SimpleType = SDNode *;
362
363 static SimpleType getSimplifiedValue(SDUse &Val) {
364 return Val.getNode();
365 }
366};
367
368/// These are IR-level optimization flags that may be propagated to SDNodes.
369/// TODO: This data structure should be shared by the IR optimizer and the
370/// the backend.
371struct SDNodeFlags {
372private:
373 bool NoUnsignedWrap : 1;
374 bool NoSignedWrap : 1;
375 bool Exact : 1;
376 bool NoNaNs : 1;
377 bool NoInfs : 1;
378 bool NoSignedZeros : 1;
379 bool AllowReciprocal : 1;
380 bool AllowContract : 1;
381 bool ApproximateFuncs : 1;
382 bool AllowReassociation : 1;
383
384 // We assume instructions do not raise floating-point exceptions by default,
385 // and only those marked explicitly may do so. We could choose to represent
386 // this via a positive "FPExcept" flags like on the MI level, but having a
387 // negative "NoFPExcept" flag here (that defaults to true) makes the flag
388 // intersection logic more straightforward.
389 bool NoFPExcept : 1;
390
391public:
392 /// Default constructor turns off all optimization flags.
393 SDNodeFlags()
394 : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NoNaNs(false),
395 NoInfs(false), NoSignedZeros(false), AllowReciprocal(false),
396 AllowContract(false), ApproximateFuncs(false),
397 AllowReassociation(false), NoFPExcept(false) {}
398
399 /// Propagate the fast-math-flags from an IR FPMathOperator.
400 void copyFMF(const FPMathOperator &FPMO) {
401 setNoNaNs(FPMO.hasNoNaNs());
402 setNoInfs(FPMO.hasNoInfs());
403 setNoSignedZeros(FPMO.hasNoSignedZeros());
404 setAllowReciprocal(FPMO.hasAllowReciprocal());
405 setAllowContract(FPMO.hasAllowContract());
406 setApproximateFuncs(FPMO.hasApproxFunc());
407 setAllowReassociation(FPMO.hasAllowReassoc());
408 }
409
410 // These are mutators for each flag.
411 void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
412 void setNoSignedWrap(bool b) { NoSignedWrap = b; }
413 void setExact(bool b) { Exact = b; }
414 void setNoNaNs(bool b) { NoNaNs = b; }
415 void setNoInfs(bool b) { NoInfs = b; }
416 void setNoSignedZeros(bool b) { NoSignedZeros = b; }
417 void setAllowReciprocal(bool b) { AllowReciprocal = b; }
418 void setAllowContract(bool b) { AllowContract = b; }
419 void setApproximateFuncs(bool b) { ApproximateFuncs = b; }
420 void setAllowReassociation(bool b) { AllowReassociation = b; }
421 void setNoFPExcept(bool b) { NoFPExcept = b; }
422
423 // These are accessors for each flag.
424 bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
425 bool hasNoSignedWrap() const { return NoSignedWrap; }
426 bool hasExact() const { return Exact; }
427 bool hasNoNaNs() const { return NoNaNs; }
428 bool hasNoInfs() const { return NoInfs; }
429 bool hasNoSignedZeros() const { return NoSignedZeros; }
430 bool hasAllowReciprocal() const { return AllowReciprocal; }
431 bool hasAllowContract() const { return AllowContract; }
432 bool hasApproximateFuncs() const { return ApproximateFuncs; }
433 bool hasAllowReassociation() const { return AllowReassociation; }
434 bool hasNoFPExcept() const { return NoFPExcept; }
435
436 /// Clear any flags in this flag set that aren't also set in Flags. All
437 /// flags will be cleared if Flags are undefined.
438 void intersectWith(const SDNodeFlags Flags) {
439 NoUnsignedWrap &= Flags.NoUnsignedWrap;
440 NoSignedWrap &= Flags.NoSignedWrap;
441 Exact &= Flags.Exact;
442 NoNaNs &= Flags.NoNaNs;
443 NoInfs &= Flags.NoInfs;
444 NoSignedZeros &= Flags.NoSignedZeros;
445 AllowReciprocal &= Flags.AllowReciprocal;
446 AllowContract &= Flags.AllowContract;
447 ApproximateFuncs &= Flags.ApproximateFuncs;
448 AllowReassociation &= Flags.AllowReassociation;
449 NoFPExcept &= Flags.NoFPExcept;
450 }
451};
452
453/// Represents one node in the SelectionDAG.
454///
455class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
456private:
457 /// The operation that this node performs.
458 int16_t NodeType;
459
460protected:
461 // We define a set of mini-helper classes to help us interpret the bits in our
462 // SubclassData. These are designed to fit within a uint16_t so they pack
463 // with NodeType.
464
465#if defined(_AIX) && (!defined(__GNUC__4) || defined(__ibmxl__))
466// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
467// and give the `pack` pragma push semantics.
468#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")pack(2)
469#define END_TWO_BYTE_PACK() _Pragma("pack(pop)")pack(pop)
470#else
471#define BEGIN_TWO_BYTE_PACK()
472#define END_TWO_BYTE_PACK()
473#endif
474
475BEGIN_TWO_BYTE_PACK()
476 class SDNodeBitfields {
477 friend class SDNode;
478 friend class MemIntrinsicSDNode;
479 friend class MemSDNode;
480 friend class SelectionDAG;
481
482 uint16_t HasDebugValue : 1;
483 uint16_t IsMemIntrinsic : 1;
484 uint16_t IsDivergent : 1;
485 };
486 enum { NumSDNodeBits = 3 };
487
488 class ConstantSDNodeBitfields {
489 friend class ConstantSDNode;
490
491 uint16_t : NumSDNodeBits;
492
493 uint16_t IsOpaque : 1;
494 };
495
496 class MemSDNodeBitfields {
497 friend class MemSDNode;
498 friend class MemIntrinsicSDNode;
499 friend class AtomicSDNode;
500
501 uint16_t : NumSDNodeBits;
502
503 uint16_t IsVolatile : 1;
504 uint16_t IsNonTemporal : 1;
505 uint16_t IsDereferenceable : 1;
506 uint16_t IsInvariant : 1;
507 };
508 enum { NumMemSDNodeBits = NumSDNodeBits + 4 };
509
510 class LSBaseSDNodeBitfields {
511 friend class LSBaseSDNode;
512 friend class MaskedLoadStoreSDNode;
513 friend class MaskedGatherScatterSDNode;
514
515 uint16_t : NumMemSDNodeBits;
516
517 // This storage is shared between disparate class hierarchies to hold an
518 // enumeration specific to the class hierarchy in use.
519 // LSBaseSDNode => enum ISD::MemIndexedMode
520 // MaskedLoadStoreBaseSDNode => enum ISD::MemIndexedMode
521 // MaskedGatherScatterSDNode => enum ISD::MemIndexType
522 uint16_t AddressingMode : 3;
523 };
524 enum { NumLSBaseSDNodeBits = NumMemSDNodeBits + 3 };
525
526 class LoadSDNodeBitfields {
527 friend class LoadSDNode;
528 friend class MaskedLoadSDNode;
529 friend class MaskedGatherSDNode;
530
531 uint16_t : NumLSBaseSDNodeBits;
532
533 uint16_t ExtTy : 2; // enum ISD::LoadExtType
534 uint16_t IsExpanding : 1;
535 };
536
537 class StoreSDNodeBitfields {
538 friend class StoreSDNode;
539 friend class MaskedStoreSDNode;
540 friend class MaskedScatterSDNode;
541
542 uint16_t : NumLSBaseSDNodeBits;
543
544 uint16_t IsTruncating : 1;
545 uint16_t IsCompressing : 1;
546 };
547
548 union {
549 char RawSDNodeBits[sizeof(uint16_t)];
550 SDNodeBitfields SDNodeBits;
551 ConstantSDNodeBitfields ConstantSDNodeBits;
552 MemSDNodeBitfields MemSDNodeBits;
553 LSBaseSDNodeBitfields LSBaseSDNodeBits;
554 LoadSDNodeBitfields LoadSDNodeBits;
555 StoreSDNodeBitfields StoreSDNodeBits;
556 };
557END_TWO_BYTE_PACK()
558#undef BEGIN_TWO_BYTE_PACK
559#undef END_TWO_BYTE_PACK
560
561 // RawSDNodeBits must cover the entirety of the union. This means that all of
562 // the union's members must have size <= RawSDNodeBits. We write the RHS as
563 // "2" instead of sizeof(RawSDNodeBits) because MSVC can't handle the latter.
564 static_assert(sizeof(SDNodeBitfields) <= 2, "field too wide");
565 static_assert(sizeof(ConstantSDNodeBitfields) <= 2, "field too wide");
566 static_assert(sizeof(MemSDNodeBitfields) <= 2, "field too wide");
567 static_assert(sizeof(LSBaseSDNodeBitfields) <= 2, "field too wide");
568 static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide");
569 static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide");
570
571private:
572 friend class SelectionDAG;
573 // TODO: unfriend HandleSDNode once we fix its operand handling.
574 friend class HandleSDNode;
575
576 /// Unique id per SDNode in the DAG.
577 int NodeId = -1;
578
579 /// The values that are used by this operation.
580 SDUse *OperandList = nullptr;
581
582 /// The types of the values this node defines. SDNode's may
583 /// define multiple values simultaneously.
584 const EVT *ValueList;
585
586 /// List of uses for this SDNode.
587 SDUse *UseList = nullptr;
588
589 /// The number of entries in the Operand/Value list.
590 unsigned short NumOperands = 0;
591 unsigned short NumValues;
592
593 // The ordering of the SDNodes. It roughly corresponds to the ordering of the
594 // original LLVM instructions.
595 // This is used for turning off scheduling, because we'll forgo
596 // the normal scheduling algorithms and output the instructions according to
597 // this ordering.
598 unsigned IROrder;
599
600 /// Source line information.
601 DebugLoc debugLoc;
602
603 /// Return a pointer to the specified value type.
604 static const EVT *getValueTypeList(EVT VT);
605
606 SDNodeFlags Flags;
607
608public:
609 /// Unique and persistent id per SDNode in the DAG.
610 /// Used for debug printing.
611 uint16_t PersistentId;
612
613 //===--------------------------------------------------------------------===//
614 // Accessors
615 //
616
617 /// Return the SelectionDAG opcode value for this node. For
618 /// pre-isel nodes (those for which isMachineOpcode returns false), these
619 /// are the opcode values in the ISD and <target>ISD namespaces. For
620 /// post-isel opcodes, see getMachineOpcode.
621 unsigned getOpcode() const { return (unsigned short)NodeType; }
622
623 /// Test if this node has a target-specific opcode (in the
624 /// \<target\>ISD namespace).
625 bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
626
627 /// Test if this node has a target-specific opcode that may raise
628 /// FP exceptions (in the \<target\>ISD namespace and greater than
629 /// FIRST_TARGET_STRICTFP_OPCODE). Note that all target memory
630 /// opcode are currently automatically considered to possibly raise
631 /// FP exceptions as well.
632 bool isTargetStrictFPOpcode() const {
633 return NodeType >= ISD::FIRST_TARGET_STRICTFP_OPCODE;
634 }
635
636 /// Test if this node has a target-specific
637 /// memory-referencing opcode (in the \<target\>ISD namespace and
638 /// greater than FIRST_TARGET_MEMORY_OPCODE).
639 bool isTargetMemoryOpcode() const {
640 return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
641 }
642
643 /// Return true if the type of the node type undefined.
644 bool isUndef() const { return NodeType == ISD::UNDEF; }
645
646 /// Test if this node is a memory intrinsic (with valid pointer information).
647 /// INTRINSIC_W_CHAIN and INTRINSIC_VOID nodes are sometimes created for
648 /// non-memory intrinsics (with chains) that are not really instances of
649 /// MemSDNode. For such nodes, we need some extra state to determine the
650 /// proper classof relationship.
651 bool isMemIntrinsic() const {
652 return (NodeType == ISD::INTRINSIC_W_CHAIN ||
653 NodeType == ISD::INTRINSIC_VOID) &&
654 SDNodeBits.IsMemIntrinsic;
655 }
656
657 /// Test if this node is a strict floating point pseudo-op.
658 bool isStrictFPOpcode() {
659 switch (NodeType) {
660 default:
661 return false;
662 case ISD::STRICT_FP16_TO_FP:
663 case ISD::STRICT_FP_TO_FP16:
664#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
665 case ISD::STRICT_##DAGN:
666#include "llvm/IR/ConstrainedOps.def"
667 return true;
668 }
669 }
670
671 /// Test if this node has a post-isel opcode, directly
672 /// corresponding to a MachineInstr opcode.
673 bool isMachineOpcode() const { return NodeType < 0; }
674
675 /// This may only be called if isMachineOpcode returns
676 /// true. It returns the MachineInstr opcode value that the node's opcode
677 /// corresponds to.
678 unsigned getMachineOpcode() const {
679 assert(isMachineOpcode() && "Not a MachineInstr opcode!")((isMachineOpcode() && "Not a MachineInstr opcode!") ?
static_cast<void> (0) : __assert_fail ("isMachineOpcode() && \"Not a MachineInstr opcode!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 679, __PRETTY_FUNCTION__))
;
680 return ~NodeType;
681 }
682
683 bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; }
684 void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; }
685
686 bool isDivergent() const { return SDNodeBits.IsDivergent; }
687
688 /// Return true if there are no uses of this node.
689 bool use_empty() const { return UseList == nullptr; }
690
691 /// Return true if there is exactly one use of this node.
692 bool hasOneUse() const { return hasSingleElement(uses()); }
693
694 /// Return the number of uses of this node. This method takes
695 /// time proportional to the number of uses.
696 size_t use_size() const { return std::distance(use_begin(), use_end()); }
697
698 /// Return the unique node id.
699 int getNodeId() const { return NodeId; }
700
701 /// Set unique node id.
702 void setNodeId(int Id) { NodeId = Id; }
703
704 /// Return the node ordering.
705 unsigned getIROrder() const { return IROrder; }
706
707 /// Set the node ordering.
708 void setIROrder(unsigned Order) { IROrder = Order; }
709
710 /// Return the source location info.
711 const DebugLoc &getDebugLoc() const { return debugLoc; }
712
713 /// Set source location info. Try to avoid this, putting
714 /// it in the constructor is preferable.
715 void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); }
716
717 /// This class provides iterator support for SDUse
718 /// operands that use a specific SDNode.
719 class use_iterator {
720 friend class SDNode;
721
722 SDUse *Op = nullptr;
723
724 explicit use_iterator(SDUse *op) : Op(op) {}
725
726 public:
727 using iterator_category = std::forward_iterator_tag;
728 using value_type = SDUse;
729 using difference_type = std::ptrdiff_t;
730 using pointer = value_type *;
731 using reference = value_type &;
732
733 use_iterator() = default;
734 use_iterator(const use_iterator &I) : Op(I.Op) {}
735
736 bool operator==(const use_iterator &x) const {
737 return Op == x.Op;
738 }
739 bool operator!=(const use_iterator &x) const {
740 return !operator==(x);
741 }
742
743 /// Return true if this iterator is at the end of uses list.
744 bool atEnd() const { return Op == nullptr; }
745
746 // Iterator traversal: forward iteration only.
747 use_iterator &operator++() { // Preincrement
748 assert(Op && "Cannot increment end iterator!")((Op && "Cannot increment end iterator!") ? static_cast
<void> (0) : __assert_fail ("Op && \"Cannot increment end iterator!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 748, __PRETTY_FUNCTION__))
;
749 Op = Op->getNext();
750 return *this;
751 }
752
753 use_iterator operator++(int) { // Postincrement
754 use_iterator tmp = *this; ++*this; return tmp;
755 }
756
757 /// Retrieve a pointer to the current user node.
758 SDNode *operator*() const {
759 assert(Op && "Cannot dereference end iterator!")((Op && "Cannot dereference end iterator!") ? static_cast
<void> (0) : __assert_fail ("Op && \"Cannot dereference end iterator!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 759, __PRETTY_FUNCTION__))
;
760 return Op->getUser();
761 }
762
763 SDNode *operator->() const { return operator*(); }
764
765 SDUse &getUse() const { return *Op; }
766
767 /// Retrieve the operand # of this use in its user.
768 unsigned getOperandNo() const {
769 assert(Op && "Cannot dereference end iterator!")((Op && "Cannot dereference end iterator!") ? static_cast
<void> (0) : __assert_fail ("Op && \"Cannot dereference end iterator!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 769, __PRETTY_FUNCTION__))
;
770 return (unsigned)(Op - Op->getUser()->OperandList);
771 }
772 };
773
774 /// Provide iteration support to walk over all uses of an SDNode.
775 use_iterator use_begin() const {
776 return use_iterator(UseList);
777 }
778
779 static use_iterator use_end() { return use_iterator(nullptr); }
780
781 inline iterator_range<use_iterator> uses() {
782 return make_range(use_begin(), use_end());
783 }
784 inline iterator_range<use_iterator> uses() const {
785 return make_range(use_begin(), use_end());
786 }
787
788 /// Return true if there are exactly NUSES uses of the indicated value.
789 /// This method ignores uses of other values defined by this operation.
790 bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
791
792 /// Return true if there are any use of the indicated value.
793 /// This method ignores uses of other values defined by this operation.
794 bool hasAnyUseOfValue(unsigned Value) const;
795
796 /// Return true if this node is the only use of N.
797 bool isOnlyUserOf(const SDNode *N) const;
798
799 /// Return true if this node is an operand of N.
800 bool isOperandOf(const SDNode *N) const;
801
802 /// Return true if this node is a predecessor of N.
803 /// NOTE: Implemented on top of hasPredecessor and every bit as
804 /// expensive. Use carefully.
805 bool isPredecessorOf(const SDNode *N) const {
806 return N->hasPredecessor(this);
807 }
808
809 /// Return true if N is a predecessor of this node.
810 /// N is either an operand of this node, or can be reached by recursively
811 /// traversing up the operands.
812 /// NOTE: This is an expensive method. Use it carefully.
813 bool hasPredecessor(const SDNode *N) const;
814
815 /// Returns true if N is a predecessor of any node in Worklist. This
816 /// helper keeps Visited and Worklist sets externally to allow unions
817 /// searches to be performed in parallel, caching of results across
818 /// queries and incremental addition to Worklist. Stops early if N is
819 /// found but will resume. Remember to clear Visited and Worklists
820 /// if DAG changes. MaxSteps gives a maximum number of nodes to visit before
821 /// giving up. The TopologicalPrune flag signals that positive NodeIds are
822 /// topologically ordered (Operands have strictly smaller node id) and search
823 /// can be pruned leveraging this.
824 static bool hasPredecessorHelper(const SDNode *N,
825 SmallPtrSetImpl<const SDNode *> &Visited,
826 SmallVectorImpl<const SDNode *> &Worklist,
827 unsigned int MaxSteps = 0,
828 bool TopologicalPrune = false) {
829 SmallVector<const SDNode *, 8> DeferredNodes;
830 if (Visited.count(N))
831 return true;
832
833 // Node Id's are assigned in three places: As a topological
834 // ordering (> 0), during legalization (results in values set to
835 // 0), new nodes (set to -1). If N has a topolgical id then we
836 // know that all nodes with ids smaller than it cannot be
837 // successors and we need not check them. Filter out all node
838 // that can't be matches. We add them to the worklist before exit
839 // in case of multiple calls. Note that during selection the topological id
840 // may be violated if a node's predecessor is selected before it. We mark
841 // this at selection negating the id of unselected successors and
842 // restricting topological pruning to positive ids.
843
844 int NId = N->getNodeId();
845 // If we Invalidated the Id, reconstruct original NId.
846 if (NId < -1)
847 NId = -(NId + 1);
848
849 bool Found = false;
850 while (!Worklist.empty()) {
851 const SDNode *M = Worklist.pop_back_val();
852 int MId = M->getNodeId();
853 if (TopologicalPrune && M->getOpcode() != ISD::TokenFactor && (NId > 0) &&
854 (MId > 0) && (MId < NId)) {
855 DeferredNodes.push_back(M);
856 continue;
857 }
858 for (const SDValue &OpV : M->op_values()) {
859 SDNode *Op = OpV.getNode();
860 if (Visited.insert(Op).second)
861 Worklist.push_back(Op);
862 if (Op == N)
863 Found = true;
864 }
865 if (Found)
866 break;
867 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
868 break;
869 }
870 // Push deferred nodes back on worklist.
871 Worklist.append(DeferredNodes.begin(), DeferredNodes.end());
872 // If we bailed early, conservatively return found.
873 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
874 return true;
875 return Found;
876 }
877
878 /// Return true if all the users of N are contained in Nodes.
879 /// NOTE: Requires at least one match, but doesn't require them all.
880 static bool areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N);
881
882 /// Return the number of values used by this operation.
883 unsigned getNumOperands() const { return NumOperands; }
884
885 /// Return the maximum number of operands that a SDNode can hold.
886 static constexpr size_t getMaxNumOperands() {
887 return std::numeric_limits<decltype(SDNode::NumOperands)>::max();
888 }
889
890 /// Helper method returns the integer value of a ConstantSDNode operand.
891 inline uint64_t getConstantOperandVal(unsigned Num) const;
892
893 /// Helper method returns the APInt of a ConstantSDNode operand.
894 inline const APInt &getConstantOperandAPInt(unsigned Num) const;
895
896 const SDValue &getOperand(unsigned Num) const {
897 assert(Num < NumOperands && "Invalid child # of SDNode!")((Num < NumOperands && "Invalid child # of SDNode!"
) ? static_cast<void> (0) : __assert_fail ("Num < NumOperands && \"Invalid child # of SDNode!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 897, __PRETTY_FUNCTION__))
;
898 return OperandList[Num];
899 }
900
901 using op_iterator = SDUse *;
902
903 op_iterator op_begin() const { return OperandList; }
904 op_iterator op_end() const { return OperandList+NumOperands; }
905 ArrayRef<SDUse> ops() const { return makeArrayRef(op_begin(), op_end()); }
906
907 /// Iterator for directly iterating over the operand SDValue's.
908 struct value_op_iterator
909 : iterator_adaptor_base<value_op_iterator, op_iterator,
910 std::random_access_iterator_tag, SDValue,
911 ptrdiff_t, value_op_iterator *,
912 value_op_iterator *> {
913 explicit value_op_iterator(SDUse *U = nullptr)
914 : iterator_adaptor_base(U) {}
915
916 const SDValue &operator*() const { return I->get(); }
917 };
918
919 iterator_range<value_op_iterator> op_values() const {
920 return make_range(value_op_iterator(op_begin()),
921 value_op_iterator(op_end()));
922 }
923
924 SDVTList getVTList() const {
925 SDVTList X = { ValueList, NumValues };
926 return X;
927 }
928
929 /// If this node has a glue operand, return the node
930 /// to which the glue operand points. Otherwise return NULL.
931 SDNode *getGluedNode() const {
932 if (getNumOperands() != 0 &&
933 getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
934 return getOperand(getNumOperands()-1).getNode();
935 return nullptr;
936 }
937
938 /// If this node has a glue value with a user, return
939 /// the user (there is at most one). Otherwise return NULL.
940 SDNode *getGluedUser() const {
941 for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
942 if (UI.getUse().get().getValueType() == MVT::Glue)
943 return *UI;
944 return nullptr;
945 }
946
947 SDNodeFlags getFlags() const { return Flags; }
948 void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
949
950 /// Clear any flags in this node that aren't also set in Flags.
951 /// If Flags is not in a defined state then this has no effect.
952 void intersectFlagsWith(const SDNodeFlags Flags);
953
954 /// Return the number of values defined/returned by this operator.
955 unsigned getNumValues() const { return NumValues; }
956
957 /// Return the type of a specified result.
958 EVT getValueType(unsigned ResNo) const {
959 assert(ResNo < NumValues && "Illegal result number!")((ResNo < NumValues && "Illegal result number!") ?
static_cast<void> (0) : __assert_fail ("ResNo < NumValues && \"Illegal result number!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 959, __PRETTY_FUNCTION__))
;
960 return ValueList[ResNo];
961 }
962
963 /// Return the type of a specified result as a simple type.
964 MVT getSimpleValueType(unsigned ResNo) const {
965 return getValueType(ResNo).getSimpleVT();
966 }
967
968 /// Returns MVT::getSizeInBits(getValueType(ResNo)).
969 ///
970 /// If the value type is a scalable vector type, the scalable property will
971 /// be set and the runtime size will be a positive integer multiple of the
972 /// base size.
973 TypeSize getValueSizeInBits(unsigned ResNo) const {
974 return getValueType(ResNo).getSizeInBits();
975 }
976
977 using value_iterator = const EVT *;
978
979 value_iterator value_begin() const { return ValueList; }
980 value_iterator value_end() const { return ValueList+NumValues; }
981 iterator_range<value_iterator> values() const {
982 return llvm::make_range(value_begin(), value_end());
983 }
984
985 /// Return the opcode of this operation for printing.
986 std::string getOperationName(const SelectionDAG *G = nullptr) const;
987 static const char* getIndexedModeName(ISD::MemIndexedMode AM);
988 void print_types(raw_ostream &OS, const SelectionDAG *G) const;
989 void print_details(raw_ostream &OS, const SelectionDAG *G) const;
990 void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
991 void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
992
993 /// Print a SelectionDAG node and all children down to
994 /// the leaves. The given SelectionDAG allows target-specific nodes
995 /// to be printed in human-readable form. Unlike printr, this will
996 /// print the whole DAG, including children that appear multiple
997 /// times.
998 ///
999 void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const;
1000
1001 /// Print a SelectionDAG node and children up to
1002 /// depth "depth." The given SelectionDAG allows target-specific
1003 /// nodes to be printed in human-readable form. Unlike printr, this
1004 /// will print children that appear multiple times wherever they are
1005 /// used.
1006 ///
1007 void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr,
1008 unsigned depth = 100) const;
1009
1010 /// Dump this node, for debugging.
1011 void dump() const;
1012
1013 /// Dump (recursively) this node and its use-def subgraph.
1014 void dumpr() const;
1015
1016 /// Dump this node, for debugging.
1017 /// The given SelectionDAG allows target-specific nodes to be printed
1018 /// in human-readable form.
1019 void dump(const SelectionDAG *G) const;
1020
1021 /// Dump (recursively) this node and its use-def subgraph.
1022 /// The given SelectionDAG allows target-specific nodes to be printed
1023 /// in human-readable form.
1024 void dumpr(const SelectionDAG *G) const;
1025
1026 /// printrFull to dbgs(). The given SelectionDAG allows
1027 /// target-specific nodes to be printed in human-readable form.
1028 /// Unlike dumpr, this will print the whole DAG, including children
1029 /// that appear multiple times.
1030 void dumprFull(const SelectionDAG *G = nullptr) const;
1031
1032 /// printrWithDepth to dbgs(). The given
1033 /// SelectionDAG allows target-specific nodes to be printed in
1034 /// human-readable form. Unlike dumpr, this will print children
1035 /// that appear multiple times wherever they are used.
1036 ///
1037 void dumprWithDepth(const SelectionDAG *G = nullptr,
1038 unsigned depth = 100) const;
1039
1040 /// Gather unique data for the node.
1041 void Profile(FoldingSetNodeID &ID) const;
1042
1043 /// This method should only be used by the SDUse class.
1044 void addUse(SDUse &U) { U.addToList(&UseList); }
1045
1046protected:
1047 static SDVTList getSDVTList(EVT VT) {
1048 SDVTList Ret = { getValueTypeList(VT), 1 };
1049 return Ret;
1050 }
1051
1052 /// Create an SDNode.
1053 ///
1054 /// SDNodes are created without any operands, and never own the operand
1055 /// storage. To add operands, see SelectionDAG::createOperands.
1056 SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
1057 : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs),
1058 IROrder(Order), debugLoc(std::move(dl)) {
1059 memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits));
1060 assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor")((debugLoc.hasTrivialDestructor() && "Expected trivial destructor"
) ? static_cast<void> (0) : __assert_fail ("debugLoc.hasTrivialDestructor() && \"Expected trivial destructor\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1060, __PRETTY_FUNCTION__))
;
1061 assert(NumValues == VTs.NumVTs &&((NumValues == VTs.NumVTs && "NumValues wasn't wide enough for its operands!"
) ? static_cast<void> (0) : __assert_fail ("NumValues == VTs.NumVTs && \"NumValues wasn't wide enough for its operands!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1062, __PRETTY_FUNCTION__))
1062 "NumValues wasn't wide enough for its operands!")((NumValues == VTs.NumVTs && "NumValues wasn't wide enough for its operands!"
) ? static_cast<void> (0) : __assert_fail ("NumValues == VTs.NumVTs && \"NumValues wasn't wide enough for its operands!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1062, __PRETTY_FUNCTION__))
;
1063 }
1064
1065 /// Release the operands and set this node to have zero operands.
1066 void DropOperands();
1067};
1068
1069/// Wrapper class for IR location info (IR ordering and DebugLoc) to be passed
1070/// into SDNode creation functions.
1071/// When an SDNode is created from the DAGBuilder, the DebugLoc is extracted
1072/// from the original Instruction, and IROrder is the ordinal position of
1073/// the instruction.
1074/// When an SDNode is created after the DAG is being built, both DebugLoc and
1075/// the IROrder are propagated from the original SDNode.
1076/// So SDLoc class provides two constructors besides the default one, one to
1077/// be used by the DAGBuilder, the other to be used by others.
1078class SDLoc {
1079private:
1080 DebugLoc DL;
1081 int IROrder = 0;
1082
1083public:
1084 SDLoc() = default;
1085 SDLoc(const SDNode *N) : DL(N->getDebugLoc()), IROrder(N->getIROrder()) {}
1086 SDLoc(const SDValue V) : SDLoc(V.getNode()) {}
1087 SDLoc(const Instruction *I, int Order) : IROrder(Order) {
1088 assert(Order >= 0 && "bad IROrder")((Order >= 0 && "bad IROrder") ? static_cast<void
> (0) : __assert_fail ("Order >= 0 && \"bad IROrder\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1088, __PRETTY_FUNCTION__))
;
1089 if (I)
1090 DL = I->getDebugLoc();
1091 }
1092
1093 unsigned getIROrder() const { return IROrder; }
1094 const DebugLoc &getDebugLoc() const { return DL; }
1095};
1096
1097// Define inline functions from the SDValue class.
1098
1099inline SDValue::SDValue(SDNode *node, unsigned resno)
1100 : Node(node), ResNo(resno) {
1101 // Explicitly check for !ResNo to avoid use-after-free, because there are
1102 // callers that use SDValue(N, 0) with a deleted N to indicate successful
1103 // combines.
1104 assert((!Node || !ResNo || ResNo < Node->getNumValues()) &&(((!Node || !ResNo || ResNo < Node->getNumValues()) &&
"Invalid result number for the given node!") ? static_cast<
void> (0) : __assert_fail ("(!Node || !ResNo || ResNo < Node->getNumValues()) && \"Invalid result number for the given node!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1105, __PRETTY_FUNCTION__))
1105 "Invalid result number for the given node!")(((!Node || !ResNo || ResNo < Node->getNumValues()) &&
"Invalid result number for the given node!") ? static_cast<
void> (0) : __assert_fail ("(!Node || !ResNo || ResNo < Node->getNumValues()) && \"Invalid result number for the given node!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1105, __PRETTY_FUNCTION__))
;
1106 assert(ResNo < -2U && "Cannot use result numbers reserved for DenseMaps.")((ResNo < -2U && "Cannot use result numbers reserved for DenseMaps."
) ? static_cast<void> (0) : __assert_fail ("ResNo < -2U && \"Cannot use result numbers reserved for DenseMaps.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1106, __PRETTY_FUNCTION__))
;
1107}
1108
1109inline unsigned SDValue::getOpcode() const {
1110 return Node->getOpcode();
1111}
1112
1113inline EVT SDValue::getValueType() const {
1114 return Node->getValueType(ResNo);
9
Called C++ object pointer is null
1115}
1116
1117inline unsigned SDValue::getNumOperands() const {
1118 return Node->getNumOperands();
1119}
1120
1121inline const SDValue &SDValue::getOperand(unsigned i) const {
1122 return Node->getOperand(i);
1123}
1124
1125inline uint64_t SDValue::getConstantOperandVal(unsigned i) const {
1126 return Node->getConstantOperandVal(i);
1127}
1128
1129inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
1130 return Node->getConstantOperandAPInt(i);
1131}
1132
1133inline bool SDValue::isTargetOpcode() const {
1134 return Node->isTargetOpcode();
1135}
1136
1137inline bool SDValue::isTargetMemoryOpcode() const {
1138 return Node->isTargetMemoryOpcode();
1139}
1140
1141inline bool SDValue::isMachineOpcode() const {
1142 return Node->isMachineOpcode();
1143}
1144
1145inline unsigned SDValue::getMachineOpcode() const {
1146 return Node->getMachineOpcode();
1147}
1148
1149inline bool SDValue::isUndef() const {
1150 return Node->isUndef();
1151}
1152
1153inline bool SDValue::use_empty() const {
1154 return !Node->hasAnyUseOfValue(ResNo);
1155}
1156
1157inline bool SDValue::hasOneUse() const {
1158 return Node->hasNUsesOfValue(1, ResNo);
1159}
1160
1161inline const DebugLoc &SDValue::getDebugLoc() const {
1162 return Node->getDebugLoc();
1163}
1164
1165inline void SDValue::dump() const {
1166 return Node->dump();
1167}
1168
1169inline void SDValue::dump(const SelectionDAG *G) const {
1170 return Node->dump(G);
1171}
1172
1173inline void SDValue::dumpr() const {
1174 return Node->dumpr();
1175}
1176
1177inline void SDValue::dumpr(const SelectionDAG *G) const {
1178 return Node->dumpr(G);
1179}
1180
1181// Define inline functions from the SDUse class.
1182
1183inline void SDUse::set(const SDValue &V) {
1184 if (Val.getNode()) removeFromList();
1185 Val = V;
1186 if (V.getNode()) V.getNode()->addUse(*this);
1187}
1188
1189inline void SDUse::setInitial(const SDValue &V) {
1190 Val = V;
1191 V.getNode()->addUse(*this);
1192}
1193
1194inline void SDUse::setNode(SDNode *N) {
1195 if (Val.getNode()) removeFromList();
1196 Val.setNode(N);
1197 if (N) N->addUse(*this);
1198}
1199
1200/// This class is used to form a handle around another node that
1201/// is persistent and is updated across invocations of replaceAllUsesWith on its
1202/// operand. This node should be directly created by end-users and not added to
1203/// the AllNodes list.
1204class HandleSDNode : public SDNode {
1205 SDUse Op;
1206
1207public:
1208 explicit HandleSDNode(SDValue X)
1209 : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) {
1210 // HandleSDNodes are never inserted into the DAG, so they won't be
1211 // auto-numbered. Use ID 65535 as a sentinel.
1212 PersistentId = 0xffff;
1213
1214 // Manually set up the operand list. This node type is special in that it's
1215 // always stack allocated and SelectionDAG does not manage its operands.
1216 // TODO: This should either (a) not be in the SDNode hierarchy, or (b) not
1217 // be so special.
1218 Op.setUser(this);
1219 Op.setInitial(X);
1220 NumOperands = 1;
1221 OperandList = &Op;
1222 }
1223 ~HandleSDNode();
1224
1225 const SDValue &getValue() const { return Op; }
1226};
1227
1228class AddrSpaceCastSDNode : public SDNode {
1229private:
1230 unsigned SrcAddrSpace;
1231 unsigned DestAddrSpace;
1232
1233public:
1234 AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, EVT VT,
1235 unsigned SrcAS, unsigned DestAS);
1236
1237 unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
1238 unsigned getDestAddressSpace() const { return DestAddrSpace; }
1239
1240 static bool classof(const SDNode *N) {
1241 return N->getOpcode() == ISD::ADDRSPACECAST;
1242 }
1243};
1244
1245/// This is an abstract virtual class for memory operations.
1246class MemSDNode : public SDNode {
1247private:
1248 // VT of in-memory value.
1249 EVT MemoryVT;
1250
1251protected:
1252 /// Memory reference information.
1253 MachineMemOperand *MMO;
1254
1255public:
1256 MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1257 EVT memvt, MachineMemOperand *MMO);
1258
1259 bool readMem() const { return MMO->isLoad(); }
1260 bool writeMem() const { return MMO->isStore(); }
1261
1262 /// Returns alignment and volatility of the memory access
1263 Align getOriginalAlign() const { return MMO->getBaseAlign(); }
1264 Align getAlign() const { return MMO->getAlign(); }
1265 LLVM_ATTRIBUTE_DEPRECATED(unsigned getOriginalAlignment() const,[[deprecated("Use getOriginalAlign() instead")]] unsigned getOriginalAlignment
() const
1266 "Use getOriginalAlign() instead")[[deprecated("Use getOriginalAlign() instead")]] unsigned getOriginalAlignment
() const
{
1267 return MMO->getBaseAlign().value();
1268 }
1269 // FIXME: Remove once transition to getAlign is over.
1270 unsigned getAlignment() const { return MMO->getAlign().value(); }
1271
1272 /// Return the SubclassData value, without HasDebugValue. This contains an
1273 /// encoding of the volatile flag, as well as bits used by subclasses. This
1274 /// function should only be used to compute a FoldingSetNodeID value.
1275 /// The HasDebugValue bit is masked out because CSE map needs to match
1276 /// nodes with debug info with nodes without debug info. Same is about
1277 /// isDivergent bit.
1278 unsigned getRawSubclassData() const {
1279 uint16_t Data;
1280 union {
1281 char RawSDNodeBits[sizeof(uint16_t)];
1282 SDNodeBitfields SDNodeBits;
1283 };
1284 memcpy(&RawSDNodeBits, &this->RawSDNodeBits, sizeof(this->RawSDNodeBits));
1285 SDNodeBits.HasDebugValue = 0;
1286 SDNodeBits.IsDivergent = false;
1287 memcpy(&Data, &RawSDNodeBits, sizeof(RawSDNodeBits));
1288 return Data;
1289 }
1290
1291 bool isVolatile() const { return MemSDNodeBits.IsVolatile; }
1292 bool isNonTemporal() const { return MemSDNodeBits.IsNonTemporal; }
1293 bool isDereferenceable() const { return MemSDNodeBits.IsDereferenceable; }
1294 bool isInvariant() const { return MemSDNodeBits.IsInvariant; }
1295
1296 // Returns the offset from the location of the access.
1297 int64_t getSrcValueOffset() const { return MMO->getOffset(); }
1298
1299 /// Returns the AA info that describes the dereference.
1300 AAMDNodes getAAInfo() const { return MMO->getAAInfo(); }
1301
1302 /// Returns the Ranges that describes the dereference.
1303 const MDNode *getRanges() const { return MMO->getRanges(); }
1304
1305 /// Returns the synchronization scope ID for this memory operation.
1306 SyncScope::ID getSyncScopeID() const { return MMO->getSyncScopeID(); }
1307
1308 /// Return the atomic ordering requirements for this memory operation. For
1309 /// cmpxchg atomic operations, return the atomic ordering requirements when
1310 /// store occurs.
1311 AtomicOrdering getOrdering() const { return MMO->getOrdering(); }
1312
1313 /// Return true if the memory operation ordering is Unordered or higher.
1314 bool isAtomic() const { return MMO->isAtomic(); }
1315
1316 /// Returns true if the memory operation doesn't imply any ordering
1317 /// constraints on surrounding memory operations beyond the normal memory
1318 /// aliasing rules.
1319 bool isUnordered() const { return MMO->isUnordered(); }
1320
1321 /// Returns true if the memory operation is neither atomic or volatile.
1322 bool isSimple() const { return !isAtomic() && !isVolatile(); }
1323
1324 /// Return the type of the in-memory value.
1325 EVT getMemoryVT() const { return MemoryVT; }
1326
1327 /// Return a MachineMemOperand object describing the memory
1328 /// reference performed by operation.
1329 MachineMemOperand *getMemOperand() const { return MMO; }
1330
1331 const MachinePointerInfo &getPointerInfo() const {
1332 return MMO->getPointerInfo();
1333 }
1334
1335 /// Return the address space for the associated pointer
1336 unsigned getAddressSpace() const {
1337 return getPointerInfo().getAddrSpace();
1338 }
1339
1340 /// Update this MemSDNode's MachineMemOperand information
1341 /// to reflect the alignment of NewMMO, if it has a greater alignment.
1342 /// This must only be used when the new alignment applies to all users of
1343 /// this MachineMemOperand.
1344 void refineAlignment(const MachineMemOperand *NewMMO) {
1345 MMO->refineAlignment(NewMMO);
1346 }
1347
1348 const SDValue &getChain() const { return getOperand(0); }
1349
1350 const SDValue &getBasePtr() const {
1351 switch (getOpcode()) {
1352 case ISD::STORE:
1353 case ISD::MSTORE:
1354 return getOperand(2);
1355 case ISD::MGATHER:
1356 case ISD::MSCATTER:
1357 return getOperand(3);
1358 default:
1359 return getOperand(1);
1360 }
1361 }
1362
1363 // Methods to support isa and dyn_cast
1364 static bool classof(const SDNode *N) {
1365 // For some targets, we lower some target intrinsics to a MemIntrinsicNode
1366 // with either an intrinsic or a target opcode.
1367 return N->getOpcode() == ISD::LOAD ||
1368 N->getOpcode() == ISD::STORE ||
1369 N->getOpcode() == ISD::PREFETCH ||
1370 N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1371 N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1372 N->getOpcode() == ISD::ATOMIC_SWAP ||
1373 N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1374 N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1375 N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1376 N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1377 N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1378 N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1379 N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1380 N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1381 N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1382 N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1383 N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1384 N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1385 N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1386 N->getOpcode() == ISD::ATOMIC_LOAD ||
1387 N->getOpcode() == ISD::ATOMIC_STORE ||
1388 N->getOpcode() == ISD::MLOAD ||
1389 N->getOpcode() == ISD::MSTORE ||
1390 N->getOpcode() == ISD::MGATHER ||
1391 N->getOpcode() == ISD::MSCATTER ||
1392 N->isMemIntrinsic() ||
1393 N->isTargetMemoryOpcode();
1394 }
1395};
1396
1397/// This is an SDNode representing atomic operations.
1398class AtomicSDNode : public MemSDNode {
1399public:
1400 AtomicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTL,
1401 EVT MemVT, MachineMemOperand *MMO)
1402 : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
1403 assert(((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) ||((((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE
) || MMO->isAtomic()) && "then why are we using an AtomicSDNode?"
) ? static_cast<void> (0) : __assert_fail ("((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) || MMO->isAtomic()) && \"then why are we using an AtomicSDNode?\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1404, __PRETTY_FUNCTION__))
1404 MMO->isAtomic()) && "then why are we using an AtomicSDNode?")((((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE
) || MMO->isAtomic()) && "then why are we using an AtomicSDNode?"
) ? static_cast<void> (0) : __assert_fail ("((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) || MMO->isAtomic()) && \"then why are we using an AtomicSDNode?\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1404, __PRETTY_FUNCTION__))
;
1405 }
1406
1407 const SDValue &getBasePtr() const { return getOperand(1); }
1408 const SDValue &getVal() const { return getOperand(2); }
1409
1410 /// Returns true if this SDNode represents cmpxchg atomic operation, false
1411 /// otherwise.
1412 bool isCompareAndSwap() const {
1413 unsigned Op = getOpcode();
1414 return Op == ISD::ATOMIC_CMP_SWAP ||
1415 Op == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS;
1416 }
1417
1418 /// For cmpxchg atomic operations, return the atomic ordering requirements
1419 /// when store does not occur.
1420 AtomicOrdering getFailureOrdering() const {
1421 assert(isCompareAndSwap() && "Must be cmpxchg operation")((isCompareAndSwap() && "Must be cmpxchg operation") ?
static_cast<void> (0) : __assert_fail ("isCompareAndSwap() && \"Must be cmpxchg operation\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1421, __PRETTY_FUNCTION__))
;
1422 return MMO->getFailureOrdering();
1423 }
1424
1425 // Methods to support isa and dyn_cast
1426 static bool classof(const SDNode *N) {
1427 return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1428 N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1429 N->getOpcode() == ISD::ATOMIC_SWAP ||
1430 N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1431 N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1432 N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1433 N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1434 N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1435 N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1436 N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1437 N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1438 N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1439 N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1440 N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1441 N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1442 N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1443 N->getOpcode() == ISD::ATOMIC_LOAD ||
1444 N->getOpcode() == ISD::ATOMIC_STORE;
1445 }
1446};
1447
1448/// This SDNode is used for target intrinsics that touch
1449/// memory and need an associated MachineMemOperand. Its opcode may be
1450/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
1451/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
1452class MemIntrinsicSDNode : public MemSDNode {
1453public:
1454 MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
1455 SDVTList VTs, EVT MemoryVT, MachineMemOperand *MMO)
1456 : MemSDNode(Opc, Order, dl, VTs, MemoryVT, MMO) {
1457 SDNodeBits.IsMemIntrinsic = true;
1458 }
1459
1460 // Methods to support isa and dyn_cast
1461 static bool classof(const SDNode *N) {
1462 // We lower some target intrinsics to their target opcode
1463 // early a node with a target opcode can be of this class
1464 return N->isMemIntrinsic() ||
1465 N->getOpcode() == ISD::PREFETCH ||
1466 N->isTargetMemoryOpcode();
1467 }
1468};
1469
1470/// This SDNode is used to implement the code generator
1471/// support for the llvm IR shufflevector instruction. It combines elements
1472/// from two input vectors into a new input vector, with the selection and
1473/// ordering of elements determined by an array of integers, referred to as
1474/// the shuffle mask. For input vectors of width N, mask indices of 0..N-1
1475/// refer to elements from the LHS input, and indices from N to 2N-1 the RHS.
1476/// An index of -1 is treated as undef, such that the code generator may put
1477/// any value in the corresponding element of the result.
1478class ShuffleVectorSDNode : public SDNode {
1479 // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and
1480 // is freed when the SelectionDAG object is destroyed.
1481 const int *Mask;
1482
1483protected:
1484 friend class SelectionDAG;
1485
1486 ShuffleVectorSDNode(EVT VT, unsigned Order, const DebugLoc &dl, const int *M)
1487 : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) {}
1488
1489public:
1490 ArrayRef<int> getMask() const {
1491 EVT VT = getValueType(0);
1492 return makeArrayRef(Mask, VT.getVectorNumElements());
1493 }
1494
1495 int getMaskElt(unsigned Idx) const {
1496 assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!")((Idx < getValueType(0).getVectorNumElements() && "Idx out of range!"
) ? static_cast<void> (0) : __assert_fail ("Idx < getValueType(0).getVectorNumElements() && \"Idx out of range!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1496, __PRETTY_FUNCTION__))
;
1497 return Mask[Idx];
1498 }
1499
1500 bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
1501
1502 int getSplatIndex() const {
1503 assert(isSplat() && "Cannot get splat index for non-splat!")((isSplat() && "Cannot get splat index for non-splat!"
) ? static_cast<void> (0) : __assert_fail ("isSplat() && \"Cannot get splat index for non-splat!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1503, __PRETTY_FUNCTION__))
;
1504 EVT VT = getValueType(0);
1505 for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i)
1506 if (Mask[i] >= 0)
1507 return Mask[i];
1508
1509 // We can choose any index value here and be correct because all elements
1510 // are undefined. Return 0 for better potential for callers to simplify.
1511 return 0;
1512 }
1513
1514 static bool isSplatMask(const int *Mask, EVT VT);
1515
1516 /// Change values in a shuffle permute mask assuming
1517 /// the two vector operands have swapped position.
1518 static void commuteMask(MutableArrayRef<int> Mask) {
1519 unsigned NumElems = Mask.size();
1520 for (unsigned i = 0; i != NumElems; ++i) {
1521 int idx = Mask[i];
1522 if (idx < 0)
1523 continue;
1524 else if (idx < (int)NumElems)
1525 Mask[i] = idx + NumElems;
1526 else
1527 Mask[i] = idx - NumElems;
1528 }
1529 }
1530
1531 static bool classof(const SDNode *N) {
1532 return N->getOpcode() == ISD::VECTOR_SHUFFLE;
1533 }
1534};
1535
1536class ConstantSDNode : public SDNode {
1537 friend class SelectionDAG;
1538
1539 const ConstantInt *Value;
1540
1541 ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val, EVT VT)
1542 : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(),
1543 getSDVTList(VT)),
1544 Value(val) {
1545 ConstantSDNodeBits.IsOpaque = isOpaque;
1546 }
1547
1548public:
1549 const ConstantInt *getConstantIntValue() const { return Value; }
1550 const APInt &getAPIntValue() const { return Value->getValue(); }
1551 uint64_t getZExtValue() const { return Value->getZExtValue(); }
1552 int64_t getSExtValue() const { return Value->getSExtValue(); }
1553 uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX(18446744073709551615UL)) {
1554 return Value->getLimitedValue(Limit);
1555 }
1556 MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); }
1557 Align getAlignValue() const { return Value->getAlignValue(); }
1558
1559 bool isOne() const { return Value->isOne(); }
1560 bool isNullValue() const { return Value->isZero(); }
1561 bool isAllOnesValue() const { return Value->isMinusOne(); }
1562
1563 bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; }
1564
1565 static bool classof(const SDNode *N) {
1566 return N->getOpcode() == ISD::Constant ||
1567 N->getOpcode() == ISD::TargetConstant;
1568 }
1569};
1570
1571uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
1572 return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
1573}
1574
1575const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const {
1576 return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue();
1577}
1578
1579class ConstantFPSDNode : public SDNode {
1580 friend class SelectionDAG;
1581
1582 const ConstantFP *Value;
1583
1584 ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT)
1585 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0,
1586 DebugLoc(), getSDVTList(VT)),
1587 Value(val) {}
1588
1589public:
1590 const APFloat& getValueAPF() const { return Value->getValueAPF(); }
1591 const ConstantFP *getConstantFPValue() const { return Value; }
1592
1593 /// Return true if the value is positive or negative zero.
1594 bool isZero() const { return Value->isZero(); }
1595
1596 /// Return true if the value is a NaN.
1597 bool isNaN() const { return Value->isNaN(); }
1598
1599 /// Return true if the value is an infinity
1600 bool isInfinity() const { return Value->isInfinity(); }
1601
1602 /// Return true if the value is negative.
1603 bool isNegative() const { return Value->isNegative(); }
1604
1605 /// We don't rely on operator== working on double values, as
1606 /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
1607 /// As such, this method can be used to do an exact bit-for-bit comparison of
1608 /// two floating point values.
1609
1610 /// We leave the version with the double argument here because it's just so
1611 /// convenient to write "2.0" and the like. Without this function we'd
1612 /// have to duplicate its logic everywhere it's called.
1613 bool isExactlyValue(double V) const {
1614 return Value->getValueAPF().isExactlyValue(V);
1615 }
1616 bool isExactlyValue(const APFloat& V) const;
1617
1618 static bool isValueValidForType(EVT VT, const APFloat& Val);
1619
1620 static bool classof(const SDNode *N) {
1621 return N->getOpcode() == ISD::ConstantFP ||
1622 N->getOpcode() == ISD::TargetConstantFP;
1623 }
1624};
1625
1626/// Returns true if \p V is a constant integer zero.
1627bool isNullConstant(SDValue V);
1628
1629/// Returns true if \p V is an FP constant with a value of positive zero.
1630bool isNullFPConstant(SDValue V);
1631
1632/// Returns true if \p V is an integer constant with all bits set.
1633bool isAllOnesConstant(SDValue V);
1634
1635/// Returns true if \p V is a constant integer one.
1636bool isOneConstant(SDValue V);
1637
1638/// Return the non-bitcasted source operand of \p V if it exists.
1639/// If \p V is not a bitcasted value, it is returned as-is.
1640SDValue peekThroughBitcasts(SDValue V);
1641
1642/// Return the non-bitcasted and one-use source operand of \p V if it exists.
1643/// If \p V is not a bitcasted one-use value, it is returned as-is.
1644SDValue peekThroughOneUseBitcasts(SDValue V);
1645
1646/// Return the non-extracted vector source operand of \p V if it exists.
1647/// If \p V is not an extracted subvector, it is returned as-is.
1648SDValue peekThroughExtractSubvectors(SDValue V);
1649
1650/// Returns true if \p V is a bitwise not operation. Assumes that an all ones
1651/// constant is canonicalized to be operand 1.
1652bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
1653
1654/// Returns the SDNode if it is a constant splat BuildVector or constant int.
1655ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false,
1656 bool AllowTruncation = false);
1657
1658/// Returns the SDNode if it is a demanded constant splat BuildVector or
1659/// constant int.
1660ConstantSDNode *isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
1661 bool AllowUndefs = false,
1662 bool AllowTruncation = false);
1663
1664/// Returns the SDNode if it is a constant splat BuildVector or constant float.
1665ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
1666
1667/// Returns the SDNode if it is a demanded constant splat BuildVector or
1668/// constant float.
1669ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, const APInt &DemandedElts,
1670 bool AllowUndefs = false);
1671
1672/// Return true if the value is a constant 0 integer or a splatted vector of
1673/// a constant 0 integer (with no undefs by default).
1674/// Build vector implicit truncation is not an issue for null values.
1675bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
1676
1677/// Return true if the value is a constant 1 integer or a splatted vector of a
1678/// constant 1 integer (with no undefs).
1679/// Does not permit build vector implicit truncation.
1680bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false);
1681
1682/// Return true if the value is a constant -1 integer or a splatted vector of a
1683/// constant -1 integer (with no undefs).
1684/// Does not permit build vector implicit truncation.
1685bool isAllOnesOrAllOnesSplat(SDValue V, bool AllowUndefs = false);
1686
1687/// Return true if \p V is either a integer or FP constant.
1688inline bool isIntOrFPConstant(SDValue V) {
1689 return isa<ConstantSDNode>(V) || isa<ConstantFPSDNode>(V);
1690}
1691
1692class GlobalAddressSDNode : public SDNode {
1693 friend class SelectionDAG;
1694
1695 const GlobalValue *TheGlobal;
1696 int64_t Offset;
1697 unsigned TargetFlags;
1698
1699 GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL,
1700 const GlobalValue *GA, EVT VT, int64_t o,
1701 unsigned TF);
1702
1703public:
1704 const GlobalValue *getGlobal() const { return TheGlobal; }
1705 int64_t getOffset() const { return Offset; }
1706 unsigned getTargetFlags() const { return TargetFlags; }
1707 // Return the address space this GlobalAddress belongs to.
1708 unsigned getAddressSpace() const;
1709
1710 static bool classof(const SDNode *N) {
1711 return N->getOpcode() == ISD::GlobalAddress ||
1712 N->getOpcode() == ISD::TargetGlobalAddress ||
1713 N->getOpcode() == ISD::GlobalTLSAddress ||
1714 N->getOpcode() == ISD::TargetGlobalTLSAddress;
1715 }
1716};
1717
1718class FrameIndexSDNode : public SDNode {
1719 friend class SelectionDAG;
1720
1721 int FI;
1722
1723 FrameIndexSDNode(int fi, EVT VT, bool isTarg)
1724 : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
1725 0, DebugLoc(), getSDVTList(VT)), FI(fi) {
1726 }
1727
1728public:
1729 int getIndex() const { return FI; }
1730
1731 static bool classof(const SDNode *N) {
1732 return N->getOpcode() == ISD::FrameIndex ||
1733 N->getOpcode() == ISD::TargetFrameIndex;
1734 }
1735};
1736
1737/// This SDNode is used for LIFETIME_START/LIFETIME_END values, which indicate
1738/// the offet and size that are started/ended in the underlying FrameIndex.
1739class LifetimeSDNode : public SDNode {
1740 friend class SelectionDAG;
1741 int64_t Size;
1742 int64_t Offset; // -1 if offset is unknown.
1743
1744 LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
1745 SDVTList VTs, int64_t Size, int64_t Offset)
1746 : SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {}
1747public:
1748 int64_t getFrameIndex() const {
1749 return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
1750 }
1751
1752 bool hasOffset() const { return Offset >= 0; }
1753 int64_t getOffset() const {
1754 assert(hasOffset() && "offset is unknown")((hasOffset() && "offset is unknown") ? static_cast<
void> (0) : __assert_fail ("hasOffset() && \"offset is unknown\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1754, __PRETTY_FUNCTION__))
;
1755 return Offset;
1756 }
1757 int64_t getSize() const {
1758 assert(hasOffset() && "offset is unknown")((hasOffset() && "offset is unknown") ? static_cast<
void> (0) : __assert_fail ("hasOffset() && \"offset is unknown\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1758, __PRETTY_FUNCTION__))
;
1759 return Size;
1760 }
1761
1762 // Methods to support isa and dyn_cast
1763 static bool classof(const SDNode *N) {
1764 return N->getOpcode() == ISD::LIFETIME_START ||
1765 N->getOpcode() == ISD::LIFETIME_END;
1766 }
1767};
1768
1769/// This SDNode is used for PSEUDO_PROBE values, which are the function guid and
1770/// the index of the basic block being probed. A pseudo probe serves as a place
1771/// holder and will be removed at the end of compilation. It does not have any
1772/// operand because we do not want the instruction selection to deal with any.
1773class PseudoProbeSDNode : public SDNode {
1774 friend class SelectionDAG;
1775 uint64_t Guid;
1776 uint64_t Index;
1777 uint32_t Attributes;
1778
1779 PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
1780 SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
1781 : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
1782 Attributes(Attr) {}
1783
1784public:
1785 uint64_t getGuid() const { return Guid; }
1786 uint64_t getIndex() const { return Index; }
1787 uint32_t getAttributes() const { return Attributes; }
1788
1789 // Methods to support isa and dyn_cast
1790 static bool classof(const SDNode *N) {
1791 return N->getOpcode() == ISD::PSEUDO_PROBE;
1792 }
1793};
1794
1795class JumpTableSDNode : public SDNode {
1796 friend class SelectionDAG;
1797
1798 int JTI;
1799 unsigned TargetFlags;
1800
1801 JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned TF)
1802 : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
1803 0, DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
1804 }
1805
1806public:
1807 int getIndex() const { return JTI; }
1808 unsigned getTargetFlags() const { return TargetFlags; }
1809
1810 static bool classof(const SDNode *N) {
1811 return N->getOpcode() == ISD::JumpTable ||
1812 N->getOpcode() == ISD::TargetJumpTable;
1813 }
1814};
1815
1816class ConstantPoolSDNode : public SDNode {
1817 friend class SelectionDAG;
1818
1819 union {
1820 const Constant *ConstVal;
1821 MachineConstantPoolValue *MachineCPVal;
1822 } Val;
1823 int Offset; // It's a MachineConstantPoolValue if top bit is set.
1824 Align Alignment; // Minimum alignment requirement of CP.
1825 unsigned TargetFlags;
1826
1827 ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o,
1828 Align Alignment, unsigned TF)
1829 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
1830 DebugLoc(), getSDVTList(VT)),
1831 Offset(o), Alignment(Alignment), TargetFlags(TF) {
1832 assert(Offset >= 0 && "Offset is too large")((Offset >= 0 && "Offset is too large") ? static_cast
<void> (0) : __assert_fail ("Offset >= 0 && \"Offset is too large\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1832, __PRETTY_FUNCTION__))
;
1833 Val.ConstVal = c;
1834 }
1835
1836 ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, EVT VT, int o,
1837 Align Alignment, unsigned TF)
1838 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
1839 DebugLoc(), getSDVTList(VT)),
1840 Offset(o), Alignment(Alignment), TargetFlags(TF) {
1841 assert(Offset >= 0 && "Offset is too large")((Offset >= 0 && "Offset is too large") ? static_cast
<void> (0) : __assert_fail ("Offset >= 0 && \"Offset is too large\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1841, __PRETTY_FUNCTION__))
;
1842 Val.MachineCPVal = v;
1843 Offset |= 1 << (sizeof(unsigned)*CHAR_BIT8-1);
1844 }
1845
1846public:
1847 bool isMachineConstantPoolEntry() const {
1848 return Offset < 0;
1849 }
1850
1851 const Constant *getConstVal() const {
1852 assert(!isMachineConstantPoolEntry() && "Wrong constantpool type")((!isMachineConstantPoolEntry() && "Wrong constantpool type"
) ? static_cast<void> (0) : __assert_fail ("!isMachineConstantPoolEntry() && \"Wrong constantpool type\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1852, __PRETTY_FUNCTION__))
;
1853 return Val.ConstVal;
1854 }
1855
1856 MachineConstantPoolValue *getMachineCPVal() const {
1857 assert(isMachineConstantPoolEntry() && "Wrong constantpool type")((isMachineConstantPoolEntry() && "Wrong constantpool type"
) ? static_cast<void> (0) : __assert_fail ("isMachineConstantPoolEntry() && \"Wrong constantpool type\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 1857, __PRETTY_FUNCTION__))
;
1858 return Val.MachineCPVal;
1859 }
1860
1861 int getOffset() const {
1862 return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT8-1));
1863 }
1864
1865 // Return the alignment of this constant pool object, which is either 0 (for
1866 // default alignment) or the desired value.
1867 Align getAlign() const { return Alignment; }
1868 unsigned getTargetFlags() const { return TargetFlags; }
1869
1870 Type *getType() const;
1871
1872 static bool classof(const SDNode *N) {
1873 return N->getOpcode() == ISD::ConstantPool ||
1874 N->getOpcode() == ISD::TargetConstantPool;
1875 }
1876};
1877
1878/// Completely target-dependent object reference.
1879class TargetIndexSDNode : public SDNode {
1880 friend class SelectionDAG;
1881
1882 unsigned TargetFlags;
1883 int Index;
1884 int64_t Offset;
1885
1886public:
1887 TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned TF)
1888 : SDNode(ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)),
1889 TargetFlags(TF), Index(Idx), Offset(Ofs) {}
1890
1891 unsigned getTargetFlags() const { return TargetFlags; }
1892 int getIndex() const { return Index; }
1893 int64_t getOffset() const { return Offset; }
1894
1895 static bool classof(const SDNode *N) {
1896 return N->getOpcode() == ISD::TargetIndex;
1897 }
1898};
1899
1900class BasicBlockSDNode : public SDNode {
1901 friend class SelectionDAG;
1902
1903 MachineBasicBlock *MBB;
1904
1905 /// Debug info is meaningful and potentially useful here, but we create
1906 /// blocks out of order when they're jumped to, which makes it a bit
1907 /// harder. Let's see if we need it first.
1908 explicit BasicBlockSDNode(MachineBasicBlock *mbb)
1909 : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb)
1910 {}
1911
1912public:
1913 MachineBasicBlock *getBasicBlock() const { return MBB; }
1914
1915 static bool classof(const SDNode *N) {
1916 return N->getOpcode() == ISD::BasicBlock;
1917 }
1918};
1919
1920/// A "pseudo-class" with methods for operating on BUILD_VECTORs.
1921class BuildVectorSDNode : public SDNode {
1922public:
1923 // These are constructed as SDNodes and then cast to BuildVectorSDNodes.
1924 explicit BuildVectorSDNode() = delete;
1925
1926 /// Check if this is a constant splat, and if so, find the
1927 /// smallest element size that splats the vector. If MinSplatBits is
1928 /// nonzero, the element size must be at least that large. Note that the
1929 /// splat element may be the entire vector (i.e., a one element vector).
1930 /// Returns the splat element value in SplatValue. Any undefined bits in
1931 /// that value are zero, and the corresponding bits in the SplatUndef mask
1932 /// are set. The SplatBitSize value is set to the splat element size in
1933 /// bits. HasAnyUndefs is set to true if any bits in the vector are
1934 /// undefined. isBigEndian describes the endianness of the target.
1935 bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
1936 unsigned &SplatBitSize, bool &HasAnyUndefs,
1937 unsigned MinSplatBits = 0,
1938 bool isBigEndian = false) const;
1939
1940 /// Returns the demanded splatted value or a null value if this is not a
1941 /// splat.
1942 ///
1943 /// The DemandedElts mask indicates the elements that must be in the splat.
1944 /// If passed a non-null UndefElements bitvector, it will resize it to match
1945 /// the vector width and set the bits where elements are undef.
1946 SDValue getSplatValue(const APInt &DemandedElts,
1947 BitVector *UndefElements = nullptr) const;
1948
1949 /// Returns the splatted value or a null value if this is not a splat.
1950 ///
1951 /// If passed a non-null UndefElements bitvector, it will resize it to match
1952 /// the vector width and set the bits where elements are undef.
1953 SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
1954
1955 /// Find the shortest repeating sequence of values in the build vector.
1956 ///
1957 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
1958 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
1959 ///
1960 /// Currently this must be a power-of-2 build vector.
1961 /// The DemandedElts mask indicates the elements that must be present,
1962 /// undemanded elements in Sequence may be null (SDValue()). If passed a
1963 /// non-null UndefElements bitvector, it will resize it to match the original
1964 /// vector width and set the bits where elements are undef. If result is
1965 /// false, Sequence will be empty.
1966 bool getRepeatedSequence(const APInt &DemandedElts,
1967 SmallVectorImpl<SDValue> &Sequence,
1968 BitVector *UndefElements = nullptr) const;
1969
1970 /// Find the shortest repeating sequence of values in the build vector.
1971 ///
1972 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
1973 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
1974 ///
1975 /// Currently this must be a power-of-2 build vector.
1976 /// If passed a non-null UndefElements bitvector, it will resize it to match
1977 /// the original vector width and set the bits where elements are undef.
1978 /// If result is false, Sequence will be empty.
1979 bool getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence,
1980 BitVector *UndefElements = nullptr) const;
1981
1982 /// Returns the demanded splatted constant or null if this is not a constant
1983 /// splat.
1984 ///
1985 /// The DemandedElts mask indicates the elements that must be in the splat.
1986 /// If passed a non-null UndefElements bitvector, it will resize it to match
1987 /// the vector width and set the bits where elements are undef.
1988 ConstantSDNode *
1989 getConstantSplatNode(const APInt &DemandedElts,
1990 BitVector *UndefElements = nullptr) const;
1991
1992 /// Returns the splatted constant or null if this is not a constant
1993 /// splat.
1994 ///
1995 /// If passed a non-null UndefElements bitvector, it will resize it to match
1996 /// the vector width and set the bits where elements are undef.
1997 ConstantSDNode *
1998 getConstantSplatNode(BitVector *UndefElements = nullptr) const;
1999
2000 /// Returns the demanded splatted constant FP or null if this is not a
2001 /// constant FP splat.
2002 ///
2003 /// The DemandedElts mask indicates the elements that must be in the splat.
2004 /// If passed a non-null UndefElements bitvector, it will resize it to match
2005 /// the vector width and set the bits where elements are undef.
2006 ConstantFPSDNode *
2007 getConstantFPSplatNode(const APInt &DemandedElts,
2008 BitVector *UndefElements = nullptr) const;
2009
2010 /// Returns the splatted constant FP or null if this is not a constant
2011 /// FP splat.
2012 ///
2013 /// If passed a non-null UndefElements bitvector, it will resize it to match
2014 /// the vector width and set the bits where elements are undef.
2015 ConstantFPSDNode *
2016 getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
2017
2018 /// If this is a constant FP splat and the splatted constant FP is an
2019 /// exact power or 2, return the log base 2 integer value. Otherwise,
2020 /// return -1.
2021 ///
2022 /// The BitWidth specifies the necessary bit precision.
2023 int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements,
2024 uint32_t BitWidth) const;
2025
2026 bool isConstant() const;
2027
2028 static bool classof(const SDNode *N) {
2029 return N->getOpcode() == ISD::BUILD_VECTOR;
2030 }
2031};
2032
2033/// An SDNode that holds an arbitrary LLVM IR Value. This is
2034/// used when the SelectionDAG needs to make a simple reference to something
2035/// in the LLVM IR representation.
2036///
2037class SrcValueSDNode : public SDNode {
2038 friend class SelectionDAG;
2039
2040 const Value *V;
2041
2042 /// Create a SrcValue for a general value.
2043 explicit SrcValueSDNode(const Value *v)
2044 : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
2045
2046public:
2047 /// Return the contained Value.
2048 const Value *getValue() const { return V; }
2049
2050 static bool classof(const SDNode *N) {
2051 return N->getOpcode() == ISD::SRCVALUE;
2052 }
2053};
2054
2055class MDNodeSDNode : public SDNode {
2056 friend class SelectionDAG;
2057
2058 const MDNode *MD;
2059
2060 explicit MDNodeSDNode(const MDNode *md)
2061 : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
2062 {}
2063
2064public:
2065 const MDNode *getMD() const { return MD; }
2066
2067 static bool classof(const SDNode *N) {
2068 return N->getOpcode() == ISD::MDNODE_SDNODE;
2069 }
2070};
2071
2072class RegisterSDNode : public SDNode {
2073 friend class SelectionDAG;
2074
2075 Register Reg;
2076
2077 RegisterSDNode(Register reg, EVT VT)
2078 : SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) {}
2079
2080public:
2081 Register getReg() const { return Reg; }
2082
2083 static bool classof(const SDNode *N) {
2084 return N->getOpcode() == ISD::Register;
2085 }
2086};
2087
2088class RegisterMaskSDNode : public SDNode {
2089 friend class SelectionDAG;
2090
2091 // The memory for RegMask is not owned by the node.
2092 const uint32_t *RegMask;
2093
2094 RegisterMaskSDNode(const uint32_t *mask)
2095 : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
2096 RegMask(mask) {}
2097
2098public:
2099 const uint32_t *getRegMask() const { return RegMask; }
2100
2101 static bool classof(const SDNode *N) {
2102 return N->getOpcode() == ISD::RegisterMask;
2103 }
2104};
2105
2106class BlockAddressSDNode : public SDNode {
2107 friend class SelectionDAG;
2108
2109 const BlockAddress *BA;
2110 int64_t Offset;
2111 unsigned TargetFlags;
2112
2113 BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
2114 int64_t o, unsigned Flags)
2115 : SDNode(NodeTy, 0, DebugLoc(), getSDVTList(VT)),
2116 BA(ba), Offset(o), TargetFlags(Flags) {}
2117
2118public:
2119 const BlockAddress *getBlockAddress() const { return BA; }
2120 int64_t getOffset() const { return Offset; }
2121 unsigned getTargetFlags() const { return TargetFlags; }
2122
2123 static bool classof(const SDNode *N) {
2124 return N->getOpcode() == ISD::BlockAddress ||
2125 N->getOpcode() == ISD::TargetBlockAddress;
2126 }
2127};
2128
2129class LabelSDNode : public SDNode {
2130 friend class SelectionDAG;
2131
2132 MCSymbol *Label;
2133
2134 LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L)
2135 : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) {
2136 assert(LabelSDNode::classof(this) && "not a label opcode")((LabelSDNode::classof(this) && "not a label opcode")
? static_cast<void> (0) : __assert_fail ("LabelSDNode::classof(this) && \"not a label opcode\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2136, __PRETTY_FUNCTION__))
;
2137 }
2138
2139public:
2140 MCSymbol *getLabel() const { return Label; }
2141
2142 static bool classof(const SDNode *N) {
2143 return N->getOpcode() == ISD::EH_LABEL ||
2144 N->getOpcode() == ISD::ANNOTATION_LABEL;
2145 }
2146};
2147
2148class ExternalSymbolSDNode : public SDNode {
2149 friend class SelectionDAG;
2150
2151 const char *Symbol;
2152 unsigned TargetFlags;
2153
2154 ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF, EVT VT)
2155 : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0,
2156 DebugLoc(), getSDVTList(VT)),
2157 Symbol(Sym), TargetFlags(TF) {}
2158
2159public:
2160 const char *getSymbol() const { return Symbol; }
2161 unsigned getTargetFlags() const { return TargetFlags; }
2162
2163 static bool classof(const SDNode *N) {
2164 return N->getOpcode() == ISD::ExternalSymbol ||
2165 N->getOpcode() == ISD::TargetExternalSymbol;
2166 }
2167};
2168
2169class MCSymbolSDNode : public SDNode {
2170 friend class SelectionDAG;
2171
2172 MCSymbol *Symbol;
2173
2174 MCSymbolSDNode(MCSymbol *Symbol, EVT VT)
2175 : SDNode(ISD::MCSymbol, 0, DebugLoc(), getSDVTList(VT)), Symbol(Symbol) {}
2176
2177public:
2178 MCSymbol *getMCSymbol() const { return Symbol; }
2179
2180 static bool classof(const SDNode *N) {
2181 return N->getOpcode() == ISD::MCSymbol;
2182 }
2183};
2184
2185class CondCodeSDNode : public SDNode {
2186 friend class SelectionDAG;
2187
2188 ISD::CondCode Condition;
2189
2190 explicit CondCodeSDNode(ISD::CondCode Cond)
2191 : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2192 Condition(Cond) {}
2193
2194public:
2195 ISD::CondCode get() const { return Condition; }
2196
2197 static bool classof(const SDNode *N) {
2198 return N->getOpcode() == ISD::CONDCODE;
2199 }
2200};
2201
2202/// This class is used to represent EVT's, which are used
2203/// to parameterize some operations.
2204class VTSDNode : public SDNode {
2205 friend class SelectionDAG;
2206
2207 EVT ValueType;
2208
2209 explicit VTSDNode(EVT VT)
2210 : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2211 ValueType(VT) {}
2212
2213public:
2214 EVT getVT() const { return ValueType; }
2215
2216 static bool classof(const SDNode *N) {
2217 return N->getOpcode() == ISD::VALUETYPE;
2218 }
2219};
2220
2221/// Base class for LoadSDNode and StoreSDNode
2222class LSBaseSDNode : public MemSDNode {
2223public:
2224 LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl,
2225 SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT,
2226 MachineMemOperand *MMO)
2227 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2228 LSBaseSDNodeBits.AddressingMode = AM;
2229 assert(getAddressingMode() == AM && "Value truncated")((getAddressingMode() == AM && "Value truncated") ? static_cast
<void> (0) : __assert_fail ("getAddressingMode() == AM && \"Value truncated\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2229, __PRETTY_FUNCTION__))
;
2230 }
2231
2232 const SDValue &getOffset() const {
2233 return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
2234 }
2235
2236 /// Return the addressing mode for this load or store:
2237 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2238 ISD::MemIndexedMode getAddressingMode() const {
2239 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2240 }
2241
2242 /// Return true if this is a pre/post inc/dec load/store.
2243 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2244
2245 /// Return true if this is NOT a pre/post inc/dec load/store.
2246 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2247
2248 static bool classof(const SDNode *N) {
2249 return N->getOpcode() == ISD::LOAD ||
2250 N->getOpcode() == ISD::STORE;
2251 }
2252};
2253
2254/// This class is used to represent ISD::LOAD nodes.
2255class LoadSDNode : public LSBaseSDNode {
2256 friend class SelectionDAG;
2257
2258 LoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2259 ISD::MemIndexedMode AM, ISD::LoadExtType ETy, EVT MemVT,
2260 MachineMemOperand *MMO)
2261 : LSBaseSDNode(ISD::LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2262 LoadSDNodeBits.ExtTy = ETy;
2263 assert(readMem() && "Load MachineMemOperand is not a load!")((readMem() && "Load MachineMemOperand is not a load!"
) ? static_cast<void> (0) : __assert_fail ("readMem() && \"Load MachineMemOperand is not a load!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2263, __PRETTY_FUNCTION__))
;
2264 assert(!writeMem() && "Load MachineMemOperand is a store!")((!writeMem() && "Load MachineMemOperand is a store!"
) ? static_cast<void> (0) : __assert_fail ("!writeMem() && \"Load MachineMemOperand is a store!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2264, __PRETTY_FUNCTION__))
;
2265 }
2266
2267public:
2268 /// Return whether this is a plain node,
2269 /// or one of the varieties of value-extending loads.
2270 ISD::LoadExtType getExtensionType() const {
2271 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2272 }
2273
2274 const SDValue &getBasePtr() const { return getOperand(1); }
2275 const SDValue &getOffset() const { return getOperand(2); }
2276
2277 static bool classof(const SDNode *N) {
2278 return N->getOpcode() == ISD::LOAD;
2279 }
2280};
2281
2282/// This class is used to represent ISD::STORE nodes.
2283class StoreSDNode : public LSBaseSDNode {
2284 friend class SelectionDAG;
2285
2286 StoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2287 ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
2288 MachineMemOperand *MMO)
2289 : LSBaseSDNode(ISD::STORE, Order, dl, VTs, AM, MemVT, MMO) {
2290 StoreSDNodeBits.IsTruncating = isTrunc;
2291 assert(!readMem() && "Store MachineMemOperand is a load!")((!readMem() && "Store MachineMemOperand is a load!")
? static_cast<void> (0) : __assert_fail ("!readMem() && \"Store MachineMemOperand is a load!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2291, __PRETTY_FUNCTION__))
;
2292 assert(writeMem() && "Store MachineMemOperand is not a store!")((writeMem() && "Store MachineMemOperand is not a store!"
) ? static_cast<void> (0) : __assert_fail ("writeMem() && \"Store MachineMemOperand is not a store!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2292, __PRETTY_FUNCTION__))
;
2293 }
2294
2295public:
2296 /// Return true if the op does a truncation before store.
2297 /// For integers this is the same as doing a TRUNCATE and storing the result.
2298 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2299 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2300 void setTruncatingStore(bool Truncating) {
2301 StoreSDNodeBits.IsTruncating = Truncating;
2302 }
2303
2304 const SDValue &getValue() const { return getOperand(1); }
2305 const SDValue &getBasePtr() const { return getOperand(2); }
2306 const SDValue &getOffset() const { return getOperand(3); }
2307
2308 static bool classof(const SDNode *N) {
2309 return N->getOpcode() == ISD::STORE;
2310 }
2311};
2312
2313/// This base class is used to represent MLOAD and MSTORE nodes
2314class MaskedLoadStoreSDNode : public MemSDNode {
2315public:
2316 friend class SelectionDAG;
2317
2318 MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2319 const DebugLoc &dl, SDVTList VTs,
2320 ISD::MemIndexedMode AM, EVT MemVT,
2321 MachineMemOperand *MMO)
2322 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2323 LSBaseSDNodeBits.AddressingMode = AM;
2324 assert(getAddressingMode() == AM && "Value truncated")((getAddressingMode() == AM && "Value truncated") ? static_cast
<void> (0) : __assert_fail ("getAddressingMode() == AM && \"Value truncated\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2324, __PRETTY_FUNCTION__))
;
2325 }
2326
2327 // MaskedLoadSDNode (Chain, ptr, offset, mask, passthru)
2328 // MaskedStoreSDNode (Chain, data, ptr, offset, mask)
2329 // Mask is a vector of i1 elements
2330 const SDValue &getOffset() const {
2331 return getOperand(getOpcode() == ISD::MLOAD ? 2 : 3);
2332 }
2333 const SDValue &getMask() const {
2334 return getOperand(getOpcode() == ISD::MLOAD ? 3 : 4);
2335 }
2336
2337 /// Return the addressing mode for this load or store:
2338 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2339 ISD::MemIndexedMode getAddressingMode() const {
2340 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2341 }
2342
2343 /// Return true if this is a pre/post inc/dec load/store.
2344 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2345
2346 /// Return true if this is NOT a pre/post inc/dec load/store.
2347 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2348
2349 static bool classof(const SDNode *N) {
2350 return N->getOpcode() == ISD::MLOAD ||
2351 N->getOpcode() == ISD::MSTORE;
2352 }
2353};
2354
2355/// This class is used to represent an MLOAD node
2356class MaskedLoadSDNode : public MaskedLoadStoreSDNode {
2357public:
2358 friend class SelectionDAG;
2359
2360 MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2361 ISD::MemIndexedMode AM, ISD::LoadExtType ETy,
2362 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2363 : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, VTs, AM, MemVT, MMO) {
2364 LoadSDNodeBits.ExtTy = ETy;
2365 LoadSDNodeBits.IsExpanding = IsExpanding;
2366 }
2367
2368 ISD::LoadExtType getExtensionType() const {
2369 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2370 }
2371
2372 const SDValue &getBasePtr() const { return getOperand(1); }
2373 const SDValue &getOffset() const { return getOperand(2); }
2374 const SDValue &getMask() const { return getOperand(3); }
2375 const SDValue &getPassThru() const { return getOperand(4); }
2376
2377 static bool classof(const SDNode *N) {
2378 return N->getOpcode() == ISD::MLOAD;
2379 }
2380
2381 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2382};
2383
2384/// This class is used to represent an MSTORE node
2385class MaskedStoreSDNode : public MaskedLoadStoreSDNode {
2386public:
2387 friend class SelectionDAG;
2388
2389 MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2390 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2391 EVT MemVT, MachineMemOperand *MMO)
2392 : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, AM, MemVT, MMO) {
2393 StoreSDNodeBits.IsTruncating = isTrunc;
2394 StoreSDNodeBits.IsCompressing = isCompressing;
2395 }
2396
2397 /// Return true if the op does a truncation before store.
2398 /// For integers this is the same as doing a TRUNCATE and storing the result.
2399 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2400 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2401
2402 /// Returns true if the op does a compression to the vector before storing.
2403 /// The node contiguously stores the active elements (integers or floats)
2404 /// in src (those with their respective bit set in writemask k) to unaligned
2405 /// memory at base_addr.
2406 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2407
2408 const SDValue &getValue() const { return getOperand(1); }
2409 const SDValue &getBasePtr() const { return getOperand(2); }
2410 const SDValue &getOffset() const { return getOperand(3); }
2411 const SDValue &getMask() const { return getOperand(4); }
2412
2413 static bool classof(const SDNode *N) {
2414 return N->getOpcode() == ISD::MSTORE;
2415 }
2416};
2417
2418/// This is a base class used to represent
2419/// MGATHER and MSCATTER nodes
2420///
2421class MaskedGatherScatterSDNode : public MemSDNode {
2422public:
2423 friend class SelectionDAG;
2424
2425 MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
2426 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2427 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
2428 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2429 LSBaseSDNodeBits.AddressingMode = IndexType;
2430 assert(getIndexType() == IndexType && "Value truncated")((getIndexType() == IndexType && "Value truncated") ?
static_cast<void> (0) : __assert_fail ("getIndexType() == IndexType && \"Value truncated\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2430, __PRETTY_FUNCTION__))
;
2431 }
2432
2433 /// How is Index applied to BasePtr when computing addresses.
2434 ISD::MemIndexType getIndexType() const {
2435 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
2436 }
2437 void setIndexType(ISD::MemIndexType IndexType) {
2438 LSBaseSDNodeBits.AddressingMode = IndexType;
2439 }
2440 bool isIndexScaled() const {
2441 return (getIndexType() == ISD::SIGNED_SCALED) ||
2442 (getIndexType() == ISD::UNSIGNED_SCALED);
2443 }
2444 bool isIndexSigned() const {
2445 return (getIndexType() == ISD::SIGNED_SCALED) ||
2446 (getIndexType() == ISD::SIGNED_UNSCALED);
2447 }
2448
2449 // In the both nodes address is Op1, mask is Op2:
2450 // MaskedGatherSDNode (Chain, passthru, mask, base, index, scale)
2451 // MaskedScatterSDNode (Chain, value, mask, base, index, scale)
2452 // Mask is a vector of i1 elements
2453 const SDValue &getBasePtr() const { return getOperand(3); }
2454 const SDValue &getIndex() const { return getOperand(4); }
2455 const SDValue &getMask() const { return getOperand(2); }
2456 const SDValue &getScale() const { return getOperand(5); }
2457
2458 static bool classof(const SDNode *N) {
2459 return N->getOpcode() == ISD::MGATHER ||
2460 N->getOpcode() == ISD::MSCATTER;
2461 }
2462};
2463
2464/// This class is used to represent an MGATHER node
2465///
2466class MaskedGatherSDNode : public MaskedGatherScatterSDNode {
2467public:
2468 friend class SelectionDAG;
2469
2470 MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2471 EVT MemVT, MachineMemOperand *MMO,
2472 ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
2473 : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO,
2474 IndexType) {
2475 LoadSDNodeBits.ExtTy = ETy;
2476 }
2477
2478 const SDValue &getPassThru() const { return getOperand(1); }
2479
2480 ISD::LoadExtType getExtensionType() const {
2481 return ISD::LoadExtType(LoadSDNodeBits.ExtTy);
2482 }
2483
2484 static bool classof(const SDNode *N) {
2485 return N->getOpcode() == ISD::MGATHER;
2486 }
2487};
2488
2489/// This class is used to represent an MSCATTER node
2490///
2491class MaskedScatterSDNode : public MaskedGatherScatterSDNode {
2492public:
2493 friend class SelectionDAG;
2494
2495 MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2496 EVT MemVT, MachineMemOperand *MMO,
2497 ISD::MemIndexType IndexType, bool IsTrunc)
2498 : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO,
2499 IndexType) {
2500 StoreSDNodeBits.IsTruncating = IsTrunc;
2501 }
2502
2503 /// Return true if the op does a truncation before store.
2504 /// For integers this is the same as doing a TRUNCATE and storing the result.
2505 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2506 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2507
2508 const SDValue &getValue() const { return getOperand(1); }
2509
2510 static bool classof(const SDNode *N) {
2511 return N->getOpcode() == ISD::MSCATTER;
2512 }
2513};
2514
2515/// An SDNode that represents everything that will be needed
2516/// to construct a MachineInstr. These nodes are created during the
2517/// instruction selection proper phase.
2518///
2519/// Note that the only supported way to set the `memoperands` is by calling the
2520/// `SelectionDAG::setNodeMemRefs` function as the memory management happens
2521/// inside the DAG rather than in the node.
2522class MachineSDNode : public SDNode {
2523private:
2524 friend class SelectionDAG;
2525
2526 MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs)
2527 : SDNode(Opc, Order, DL, VTs) {}
2528
2529 // We use a pointer union between a single `MachineMemOperand` pointer and
2530 // a pointer to an array of `MachineMemOperand` pointers. This is null when
2531 // the number of these is zero, the single pointer variant used when the
2532 // number is one, and the array is used for larger numbers.
2533 //
2534 // The array is allocated via the `SelectionDAG`'s allocator and so will
2535 // always live until the DAG is cleaned up and doesn't require ownership here.
2536 //
2537 // We can't use something simpler like `TinyPtrVector` here because `SDNode`
2538 // subclasses aren't managed in a conforming C++ manner. See the comments on
2539 // `SelectionDAG::MorphNodeTo` which details what all goes on, but the
2540 // constraint here is that these don't manage memory with their constructor or
2541 // destructor and can be initialized to a good state even if they start off
2542 // uninitialized.
2543 PointerUnion<MachineMemOperand *, MachineMemOperand **> MemRefs = {};
2544
2545 // Note that this could be folded into the above `MemRefs` member if doing so
2546 // is advantageous at some point. We don't need to store this in most cases.
2547 // However, at the moment this doesn't appear to make the allocation any
2548 // smaller and makes the code somewhat simpler to read.
2549 int NumMemRefs = 0;
2550
2551public:
2552 using mmo_iterator = ArrayRef<MachineMemOperand *>::const_iterator;
2553
2554 ArrayRef<MachineMemOperand *> memoperands() const {
2555 // Special case the common cases.
2556 if (NumMemRefs == 0)
2557 return {};
2558 if (NumMemRefs == 1)
2559 return makeArrayRef(MemRefs.getAddrOfPtr1(), 1);
2560
2561 // Otherwise we have an actual array.
2562 return makeArrayRef(MemRefs.get<MachineMemOperand **>(), NumMemRefs);
2563 }
2564 mmo_iterator memoperands_begin() const { return memoperands().begin(); }
2565 mmo_iterator memoperands_end() const { return memoperands().end(); }
2566 bool memoperands_empty() const { return memoperands().empty(); }
2567
2568 /// Clear out the memory reference descriptor list.
2569 void clearMemRefs() {
2570 MemRefs = nullptr;
2571 NumMemRefs = 0;
2572 }
2573
2574 static bool classof(const SDNode *N) {
2575 return N->isMachineOpcode();
2576 }
2577};
2578
2579/// An SDNode that records if a register contains a value that is guaranteed to
2580/// be aligned accordingly.
2581class AssertAlignSDNode : public SDNode {
2582 Align Alignment;
2583
2584public:
2585 AssertAlignSDNode(unsigned Order, const DebugLoc &DL, EVT VT, Align A)
2586 : SDNode(ISD::AssertAlign, Order, DL, getSDVTList(VT)), Alignment(A) {}
2587
2588 Align getAlign() const { return Alignment; }
2589
2590 static bool classof(const SDNode *N) {
2591 return N->getOpcode() == ISD::AssertAlign;
2592 }
2593};
2594
2595class SDNodeIterator {
2596 const SDNode *Node;
2597 unsigned Operand;
2598
2599 SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
2600
2601public:
2602 using iterator_category = std::forward_iterator_tag;
2603 using value_type = SDNode;
2604 using difference_type = std::ptrdiff_t;
2605 using pointer = value_type *;
2606 using reference = value_type &;
2607
2608 bool operator==(const SDNodeIterator& x) const {
2609 return Operand == x.Operand;
2610 }
2611 bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
2612
2613 pointer operator*() const {
2614 return Node->getOperand(Operand).getNode();
2615 }
2616 pointer operator->() const { return operator*(); }
2617
2618 SDNodeIterator& operator++() { // Preincrement
2619 ++Operand;
2620 return *this;
2621 }
2622 SDNodeIterator operator++(int) { // Postincrement
2623 SDNodeIterator tmp = *this; ++*this; return tmp;
2624 }
2625 size_t operator-(SDNodeIterator Other) const {
2626 assert(Node == Other.Node &&((Node == Other.Node && "Cannot compare iterators of two different nodes!"
) ? static_cast<void> (0) : __assert_fail ("Node == Other.Node && \"Cannot compare iterators of two different nodes!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2627, __PRETTY_FUNCTION__))
2627 "Cannot compare iterators of two different nodes!")((Node == Other.Node && "Cannot compare iterators of two different nodes!"
) ? static_cast<void> (0) : __assert_fail ("Node == Other.Node && \"Cannot compare iterators of two different nodes!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/CodeGen/SelectionDAGNodes.h"
, 2627, __PRETTY_FUNCTION__))
;
2628 return Operand - Other.Operand;
2629 }
2630
2631 static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); }
2632 static SDNodeIterator end (const SDNode *N) {
2633 return SDNodeIterator(N, N->getNumOperands());
2634 }
2635
2636 unsigned getOperand() const { return Operand; }
2637 const SDNode *getNode() const { return Node; }
2638};
2639
2640template <> struct GraphTraits<SDNode*> {
2641 using NodeRef = SDNode *;
2642 using ChildIteratorType = SDNodeIterator;
2643
2644 static NodeRef getEntryNode(SDNode *N) { return N; }
2645
2646 static ChildIteratorType child_begin(NodeRef N) {
2647 return SDNodeIterator::begin(N);
2648 }
2649
2650 static ChildIteratorType child_end(NodeRef N) {
2651 return SDNodeIterator::end(N);
2652 }
2653};
2654
2655/// A representation of the largest SDNode, for use in sizeof().
2656///
2657/// This needs to be a union because the largest node differs on 32 bit systems
2658/// with 4 and 8 byte pointer alignment, respectively.
2659using LargestSDNode = AlignedCharArrayUnion<AtomicSDNode, TargetIndexSDNode,
2660 BlockAddressSDNode,
2661 GlobalAddressSDNode,
2662 PseudoProbeSDNode>;
2663
2664/// The SDNode class with the greatest alignment requirement.
2665using MostAlignedSDNode = GlobalAddressSDNode;
2666
2667namespace ISD {
2668
2669 /// Returns true if the specified node is a non-extending and unindexed load.
2670 inline bool isNormalLoad(const SDNode *N) {
2671 const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N);
2672 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
2673 Ld->getAddressingMode() == ISD::UNINDEXED;
2674 }
2675
2676 /// Returns true if the specified node is a non-extending load.
2677 inline bool isNON_EXTLoad(const SDNode *N) {
2678 return isa<LoadSDNode>(N) &&
2679 cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
2680 }
2681
2682 /// Returns true if the specified node is a EXTLOAD.
2683 inline bool isEXTLoad(const SDNode *N) {
2684 return isa<LoadSDNode>(N) &&
2685 cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
2686 }
2687
2688 /// Returns true if the specified node is a SEXTLOAD.
2689 inline bool isSEXTLoad(const SDNode *N) {
2690 return isa<LoadSDNode>(N) &&
2691 cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
2692 }
2693
2694 /// Returns true if the specified node is a ZEXTLOAD.
2695 inline bool isZEXTLoad(const SDNode *N) {
2696 return isa<LoadSDNode>(N) &&
2697 cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
2698 }
2699
2700 /// Returns true if the specified node is an unindexed load.
2701 inline bool isUNINDEXEDLoad(const SDNode *N) {
2702 return isa<LoadSDNode>(N) &&
2703 cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
2704 }
2705
2706 /// Returns true if the specified node is a non-truncating
2707 /// and unindexed store.
2708 inline bool isNormalStore(const SDNode *N) {
2709 const StoreSDNode *St = dyn_cast<StoreSDNode>(N);
2710 return St && !St->isTruncatingStore() &&
2711 St->getAddressingMode() == ISD::UNINDEXED;
2712 }
2713
2714 /// Returns true if the specified node is a non-truncating store.
2715 inline bool isNON_TRUNCStore(const SDNode *N) {
2716 return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore();
2717 }
2718
2719 /// Returns true if the specified node is a truncating store.
2720 inline bool isTRUNCStore(const SDNode *N) {
2721 return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore();
2722 }
2723
2724 /// Returns true if the specified node is an unindexed store.
2725 inline bool isUNINDEXEDStore(const SDNode *N) {
2726 return isa<StoreSDNode>(N) &&
2727 cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
2728 }
2729
2730 /// Attempt to match a unary predicate against a scalar/splat constant or
2731 /// every element of a constant BUILD_VECTOR.
2732 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
2733 bool matchUnaryPredicate(SDValue Op,
2734 std::function<bool(ConstantSDNode *)> Match,
2735 bool AllowUndefs = false);
2736
2737 /// Attempt to match a binary predicate against a pair of scalar/splat
2738 /// constants or every element of a pair of constant BUILD_VECTORs.
2739 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
2740 /// If AllowTypeMismatch is true then RetType + ArgTypes don't need to match.
2741 bool matchBinaryPredicate(
2742 SDValue LHS, SDValue RHS,
2743 std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
2744 bool AllowUndefs = false, bool AllowTypeMismatch = false);
2745
2746 /// Returns true if the specified value is the overflow result from one
2747 /// of the overflow intrinsic nodes.
2748 inline bool isOverflowIntrOpRes(SDValue Op) {
2749 unsigned Opc = Op.getOpcode();
2750 return (Op.getResNo() == 1 &&
2751 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
2752 Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
2753 }
2754
2755} // end namespace ISD
2756
2757} // end namespace llvm
2758
2759#endif // LLVM_CODEGEN_SELECTIONDAGNODES_H