LLVM 22.0.0git
VEISelLowering.cpp
Go to the documentation of this file.
1//===-- VEISelLowering.cpp - VE DAG Lowering Implementation ---------------===//
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 implements the interfaces that VE uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "VEISelLowering.h"
16#include "VECustomDAG.h"
17#include "VEInstrBuilder.h"
19#include "VERegisterInfo.h"
20#include "VETargetMachine.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/IRBuilder.h"
34#include "llvm/IR/Module.h"
36using namespace llvm;
37
38#define DEBUG_TYPE "ve-lower"
39
40//===----------------------------------------------------------------------===//
41// Calling Convention Implementation
42//===----------------------------------------------------------------------===//
43
44#include "VEGenCallingConv.inc"
45
47 switch (CallConv) {
48 default:
49 return RetCC_VE_C;
51 return RetCC_VE_Fast;
52 }
53}
54
55CCAssignFn *getParamCC(CallingConv::ID CallConv, bool IsVarArg) {
56 if (IsVarArg)
57 return CC_VE2;
58 switch (CallConv) {
59 default:
60 return CC_VE_C;
62 return CC_VE_Fast;
63 }
64}
65
67 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
68 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
69 const Type *RetTy) const {
70 CCAssignFn *RetCC = getReturnCC(CallConv);
72 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
73 return CCInfo.CheckReturn(Outs, RetCC);
74}
75
76static const MVT AllVectorVTs[] = {MVT::v256i32, MVT::v512i32, MVT::v256i64,
77 MVT::v256f32, MVT::v512f32, MVT::v256f64};
78
79static const MVT AllMaskVTs[] = {MVT::v256i1, MVT::v512i1};
80
81static const MVT AllPackedVTs[] = {MVT::v512i32, MVT::v512f32};
82
83void VETargetLowering::initRegisterClasses() {
84 // Set up the register classes.
85 addRegisterClass(MVT::i32, &VE::I32RegClass);
86 addRegisterClass(MVT::i64, &VE::I64RegClass);
87 addRegisterClass(MVT::f32, &VE::F32RegClass);
88 addRegisterClass(MVT::f64, &VE::I64RegClass);
89 addRegisterClass(MVT::f128, &VE::F128RegClass);
90
91 if (Subtarget->enableVPU()) {
92 for (MVT VecVT : AllVectorVTs)
93 addRegisterClass(VecVT, &VE::V64RegClass);
94 addRegisterClass(MVT::v256i1, &VE::VMRegClass);
95 addRegisterClass(MVT::v512i1, &VE::VM512RegClass);
96 }
97}
98
99void VETargetLowering::initSPUActions() {
100 const auto &TM = getTargetMachine();
101 /// Load & Store {
102
103 // VE doesn't have i1 sign extending load.
104 for (MVT VT : MVT::integer_valuetypes()) {
108 setTruncStoreAction(VT, MVT::i1, Expand);
109 }
110
111 // VE doesn't have floating point extload/truncstore, so expand them.
112 for (MVT FPVT : MVT::fp_valuetypes()) {
113 for (MVT OtherFPVT : MVT::fp_valuetypes()) {
114 setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand);
115 setTruncStoreAction(FPVT, OtherFPVT, Expand);
116 }
117 }
118
119 // VE doesn't have fp128 load/store, so expand them in custom lower.
120 setOperationAction(ISD::LOAD, MVT::f128, Custom);
121 setOperationAction(ISD::STORE, MVT::f128, Custom);
122
123 /// } Load & Store
124
125 // Custom legalize address nodes into LO/HI parts.
126 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
132
133 /// VAARG handling {
134 setOperationAction(ISD::VASTART, MVT::Other, Custom);
135 // VAARG needs to be lowered to access with 8 bytes alignment.
136 setOperationAction(ISD::VAARG, MVT::Other, Custom);
137 // Use the default implementation.
138 setOperationAction(ISD::VACOPY, MVT::Other, Expand);
139 setOperationAction(ISD::VAEND, MVT::Other, Expand);
140 /// } VAARG handling
141
142 /// Stack {
143 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
144 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
145
146 // Use the default implementation.
147 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
148 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
149 /// } Stack
150
151 /// Branch {
152
153 // VE doesn't have BRCOND
154 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
155
156 // BR_JT is not implemented yet.
157 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
158
159 /// } Branch
160
161 /// Int Ops {
162 for (MVT IntVT : {MVT::i32, MVT::i64}) {
163 // VE has no REM or DIVREM operations.
168
169 // VE has no SHL_PARTS/SRA_PARTS/SRL_PARTS operations.
173
174 // VE has no MULHU/S or U/SMUL_LOHI operations.
175 // TODO: Use MPD instruction to implement SMUL_LOHI for i32 type.
180
181 // VE has no CTTZ, ROTL, ROTR operations.
185
186 // VE has 64 bits instruction which works as i64 BSWAP operation. This
187 // instruction works fine as i32 BSWAP operation with an additional
188 // parameter. Use isel patterns to lower BSWAP.
190
191 // VE has only 64 bits instructions which work as i64 BITREVERSE/CTLZ/CTPOP
192 // operations. Use isel patterns for i64, promote for i32.
193 LegalizeAction Act = (IntVT == MVT::i32) ? Promote : Legal;
195 setOperationAction(ISD::CTLZ, IntVT, Act);
197 setOperationAction(ISD::CTPOP, IntVT, Act);
198
199 // VE has only 64 bits instructions which work as i64 AND/OR/XOR operations.
200 // Use isel patterns for i64, promote for i32.
201 setOperationAction(ISD::AND, IntVT, Act);
202 setOperationAction(ISD::OR, IntVT, Act);
203 setOperationAction(ISD::XOR, IntVT, Act);
204
205 // Legal smax and smin
208 }
209 /// } Int Ops
210
211 /// Conversion {
212 // VE doesn't have instructions for fp<->uint, so expand them by llvm
213 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64
214 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64
217
218 // fp16 not supported
219 for (MVT FPVT : MVT::fp_valuetypes()) {
220 setOperationAction(ISD::FP16_TO_FP, FPVT, Expand);
221 setOperationAction(ISD::FP_TO_FP16, FPVT, Expand);
222 }
223 /// } Conversion
224
225 /// Floating-point Ops {
226 /// Note: Floating-point operations are fneg, fadd, fsub, fmul, fdiv, frem,
227 /// and fcmp.
228
229 // VE doesn't have following floating point operations.
230 for (MVT VT : MVT::fp_valuetypes()) {
231 setOperationAction(ISD::FNEG, VT, Expand);
233 }
234
235 // VE doesn't have fdiv of f128.
237
238 for (MVT FPVT : {MVT::f32, MVT::f64}) {
239 // f32 and f64 uses ConstantFP. f128 uses ConstantPool.
241 }
242 /// } Floating-point Ops
243
244 /// Floating-point math functions {
245
246 // VE doesn't have following floating point math functions.
247 for (MVT VT : MVT::fp_valuetypes()) {
248 setOperationAction(ISD::FABS, VT, Expand);
250 setOperationAction(ISD::FCOS, VT, Expand);
252 setOperationAction(ISD::FPOW, VT, Expand);
253 setOperationAction(ISD::FSIN, VT, Expand);
254 setOperationAction(ISD::FSQRT, VT, Expand);
255 }
256
257 // VE has single and double FMINNUM and FMAXNUM
258 for (MVT VT : {MVT::f32, MVT::f64}) {
259 setOperationAction({ISD::FMAXNUM, ISD::FMINNUM}, VT, Legal);
260 }
261
262 /// } Floating-point math functions
263
264 /// Atomic instructions {
265
269
270 // Use custom inserter for ATOMIC_FENCE.
271 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
272
273 // Other atomic instructions.
274 for (MVT VT : MVT::integer_valuetypes()) {
275 // Support i8/i16 atomic swap.
276 setOperationAction(ISD::ATOMIC_SWAP, VT, Custom);
277
278 // FIXME: Support "atmam" instructions.
279 setOperationAction(ISD::ATOMIC_LOAD_ADD, VT, Expand);
280 setOperationAction(ISD::ATOMIC_LOAD_SUB, VT, Expand);
281 setOperationAction(ISD::ATOMIC_LOAD_AND, VT, Expand);
282 setOperationAction(ISD::ATOMIC_LOAD_OR, VT, Expand);
283
284 // VE doesn't have follwing instructions.
285 setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Expand);
286 setOperationAction(ISD::ATOMIC_LOAD_CLR, VT, Expand);
287 setOperationAction(ISD::ATOMIC_LOAD_XOR, VT, Expand);
288 setOperationAction(ISD::ATOMIC_LOAD_NAND, VT, Expand);
289 setOperationAction(ISD::ATOMIC_LOAD_MIN, VT, Expand);
290 setOperationAction(ISD::ATOMIC_LOAD_MAX, VT, Expand);
291 setOperationAction(ISD::ATOMIC_LOAD_UMIN, VT, Expand);
292 setOperationAction(ISD::ATOMIC_LOAD_UMAX, VT, Expand);
293 }
294
295 /// } Atomic instructions
296
297 /// SJLJ instructions {
301 /// } SJLJ instructions
302
303 // Intrinsic instructions
305}
306
307void VETargetLowering::initVPUActions() {
308 for (MVT LegalMaskVT : AllMaskVTs)
310
311 for (unsigned Opc : {ISD::AND, ISD::OR, ISD::XOR})
312 setOperationAction(Opc, MVT::v512i1, Custom);
313
314 for (MVT LegalVecVT : AllVectorVTs) {
318 // Translate all vector instructions with legal element types to VVP_*
319 // nodes.
320 // TODO We will custom-widen into VVP_* nodes in the future. While we are
321 // buildling the infrastructure for this, we only do this for legal vector
322 // VTs.
323#define HANDLE_VP_TO_VVP(VP_OPC, VVP_NAME) \
324 setOperationAction(ISD::VP_OPC, LegalVecVT, Custom);
325#define ADD_VVP_OP(VVP_NAME, ISD_NAME) \
326 setOperationAction(ISD::ISD_NAME, LegalVecVT, Custom);
327 setOperationAction(ISD::EXPERIMENTAL_VP_STRIDED_LOAD, LegalVecVT, Custom);
328 setOperationAction(ISD::EXPERIMENTAL_VP_STRIDED_STORE, LegalVecVT, Custom);
329#include "VVPNodes.def"
330 }
331
332 for (MVT LegalPackedVT : AllPackedVTs) {
335 }
336
337 // vNt32, vNt64 ops (legal element types)
338 for (MVT VT : MVT::vector_valuetypes()) {
339 MVT ElemVT = VT.getVectorElementType();
340 unsigned ElemBits = ElemVT.getScalarSizeInBits();
341 if (ElemBits != 32 && ElemBits != 64)
342 continue;
343
344 for (unsigned MemOpc : {ISD::MLOAD, ISD::MSTORE, ISD::LOAD, ISD::STORE})
345 setOperationAction(MemOpc, VT, Custom);
346
347 const ISD::NodeType IntReductionOCs[] = {
348 ISD::VECREDUCE_ADD, ISD::VECREDUCE_MUL, ISD::VECREDUCE_AND,
349 ISD::VECREDUCE_OR, ISD::VECREDUCE_XOR, ISD::VECREDUCE_SMIN,
350 ISD::VECREDUCE_SMAX, ISD::VECREDUCE_UMIN, ISD::VECREDUCE_UMAX};
351
352 for (unsigned IntRedOpc : IntReductionOCs)
353 setOperationAction(IntRedOpc, VT, Custom);
354 }
355
356 // v256i1 and v512i1 ops
357 for (MVT MaskVT : AllMaskVTs) {
358 // Custom lower mask ops
359 setOperationAction(ISD::STORE, MaskVT, Custom);
360 setOperationAction(ISD::LOAD, MaskVT, Custom);
361 }
362}
363
366 bool IsVarArg,
368 const SmallVectorImpl<SDValue> &OutVals,
369 const SDLoc &DL, SelectionDAG &DAG) const {
370 // CCValAssign - represent the assignment of the return value to locations.
372
373 // CCState - Info about the registers and stack slot.
374 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
375 *DAG.getContext());
376
377 // Analyze return values.
378 CCInfo.AnalyzeReturn(Outs, getReturnCC(CallConv));
379
380 SDValue Glue;
381 SmallVector<SDValue, 4> RetOps(1, Chain);
382
383 // Copy the result values into the output registers.
384 for (unsigned i = 0; i != RVLocs.size(); ++i) {
385 CCValAssign &VA = RVLocs[i];
386 assert(VA.isRegLoc() && "Can only return in registers!");
387 assert(!VA.needsCustom() && "Unexpected custom lowering");
388 SDValue OutVal = OutVals[i];
389
390 // Integer return values must be sign or zero extended by the callee.
391 switch (VA.getLocInfo()) {
393 break;
395 OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
396 break;
398 OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
399 break;
401 OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
402 break;
403 case CCValAssign::BCvt: {
404 // Convert a float return value to i64 with padding.
405 // 63 31 0
406 // +------+------+
407 // | float| 0 |
408 // +------+------+
409 assert(VA.getLocVT() == MVT::i64);
410 assert(VA.getValVT() == MVT::f32);
411 SDValue Undef = SDValue(
412 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0);
413 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
414 OutVal = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL,
415 MVT::i64, Undef, OutVal, Sub_f32),
416 0);
417 break;
418 }
419 default:
420 llvm_unreachable("Unknown loc info!");
421 }
422
423 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Glue);
424
425 // Guarantee that all emitted copies are stuck together with flags.
426 Glue = Chain.getValue(1);
427 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
428 }
429
430 RetOps[0] = Chain; // Update chain.
431
432 // Add the glue if we have it.
433 if (Glue.getNode())
434 RetOps.push_back(Glue);
435
436 return DAG.getNode(VEISD::RET_GLUE, DL, MVT::Other, RetOps);
437}
438
440 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
441 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
442 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
444
445 // Get the base offset of the incoming arguments stack space.
446 unsigned ArgsBaseOffset = Subtarget->getRsaSize();
447 // Get the size of the preserved arguments area
448 unsigned ArgsPreserved = 64;
449
450 // Analyze arguments according to CC_VE.
452 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
453 *DAG.getContext());
454 // Allocate the preserved area first.
455 CCInfo.AllocateStack(ArgsPreserved, Align(8));
456 // We already allocated the preserved area, so the stack offset computed
457 // by CC_VE would be correct now.
458 CCInfo.AnalyzeFormalArguments(Ins, getParamCC(CallConv, false));
459
460 for (const CCValAssign &VA : ArgLocs) {
461 assert(!VA.needsCustom() && "Unexpected custom lowering");
462 if (VA.isRegLoc()) {
463 // This argument is passed in a register.
464 // All integer register arguments are promoted by the caller to i64.
465
466 // Create a virtual register for the promoted live-in value.
467 Register VReg =
468 MF.addLiveIn(VA.getLocReg(), getRegClassFor(VA.getLocVT()));
469 SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
470
471 // The caller promoted the argument, so insert an Assert?ext SDNode so we
472 // won't promote the value again in this function.
473 switch (VA.getLocInfo()) {
475 Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
476 DAG.getValueType(VA.getValVT()));
477 break;
479 Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
480 DAG.getValueType(VA.getValVT()));
481 break;
482 case CCValAssign::BCvt: {
483 // Extract a float argument from i64 with padding.
484 // 63 31 0
485 // +------+------+
486 // | float| 0 |
487 // +------+------+
488 assert(VA.getLocVT() == MVT::i64);
489 assert(VA.getValVT() == MVT::f32);
490 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
491 Arg = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
492 MVT::f32, Arg, Sub_f32),
493 0);
494 break;
495 }
496 default:
497 break;
498 }
499
500 // Truncate the register down to the argument type.
501 if (VA.isExtInLoc())
502 Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
503
504 InVals.push_back(Arg);
505 continue;
506 }
507
508 // The registers are exhausted. This argument was passed on the stack.
509 assert(VA.isMemLoc());
510 // The CC_VE_Full/Half functions compute stack offsets relative to the
511 // beginning of the arguments area at %fp + the size of reserved area.
512 unsigned Offset = VA.getLocMemOffset() + ArgsBaseOffset;
513 unsigned ValSize = VA.getValVT().getSizeInBits() / 8;
514
515 // Adjust offset for a float argument by adding 4 since the argument is
516 // stored in 8 bytes buffer with offset like below. LLVM generates
517 // 4 bytes load instruction, so need to adjust offset here. This
518 // adjustment is required in only LowerFormalArguments. In LowerCall,
519 // a float argument is converted to i64 first, and stored as 8 bytes
520 // data, which is required by ABI, so no need for adjustment.
521 // 0 4
522 // +------+------+
523 // | empty| float|
524 // +------+------+
525 if (VA.getValVT() == MVT::f32)
526 Offset += 4;
527
528 int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true);
529 InVals.push_back(
530 DAG.getLoad(VA.getValVT(), DL, Chain,
533 }
534
535 if (!IsVarArg)
536 return Chain;
537
538 // This function takes variable arguments, some of which may have been passed
539 // in registers %s0-%s8.
540 //
541 // The va_start intrinsic needs to know the offset to the first variable
542 // argument.
543 // TODO: need to calculate offset correctly once we support f128.
544 unsigned ArgOffset = ArgLocs.size() * 8;
546 // Skip the reserved area at the top of stack.
547 FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgsBaseOffset);
548
549 return Chain;
550}
551
552// FIXME? Maybe this could be a TableGen attribute on some registers and
553// this table could be generated automatically from RegInfo.
555 const MachineFunction &MF) const {
557 .Case("sp", VE::SX11) // Stack pointer
558 .Case("fp", VE::SX9) // Frame pointer
559 .Case("sl", VE::SX8) // Stack limit
560 .Case("lr", VE::SX10) // Link register
561 .Case("tp", VE::SX14) // Thread pointer
562 .Case("outer", VE::SX12) // Outer regiser
563 .Case("info", VE::SX17) // Info area register
564 .Case("got", VE::SX15) // Global offset table register
565 .Case("plt", VE::SX16) // Procedure linkage table register
566 .Default(Register());
567 return Reg;
568}
569
570//===----------------------------------------------------------------------===//
571// TargetLowering Implementation
572//===----------------------------------------------------------------------===//
573
575 SmallVectorImpl<SDValue> &InVals) const {
576 SelectionDAG &DAG = CLI.DAG;
577 SDLoc DL = CLI.DL;
578 SDValue Chain = CLI.Chain;
579 auto PtrVT = getPointerTy(DAG.getDataLayout());
580
581 // VE target does not yet support tail call optimization.
582 CLI.IsTailCall = false;
583
584 // Get the base offset of the outgoing arguments stack space.
585 unsigned ArgsBaseOffset = Subtarget->getRsaSize();
586 // Get the size of the preserved arguments area
587 unsigned ArgsPreserved = 8 * 8u;
588
589 // Analyze operands of the call, assigning locations to each operand.
591 CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs,
592 *DAG.getContext());
593 // Allocate the preserved area first.
594 CCInfo.AllocateStack(ArgsPreserved, Align(8));
595 // We already allocated the preserved area, so the stack offset computed
596 // by CC_VE would be correct now.
597 CCInfo.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, false));
598
599 // VE requires to use both register and stack for varargs or no-prototyped
600 // functions.
601 bool UseBoth = CLI.IsVarArg;
602
603 // Analyze operands again if it is required to store BOTH.
605 CCState CCInfo2(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
606 ArgLocs2, *DAG.getContext());
607 if (UseBoth)
608 CCInfo2.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, true));
609
610 // Get the size of the outgoing arguments stack space requirement.
611 unsigned ArgsSize = CCInfo.getStackSize();
612
613 // Keep stack frames 16-byte aligned.
614 ArgsSize = alignTo(ArgsSize, 16);
615
616 // Adjust the stack pointer to make room for the arguments.
617 // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
618 // with more than 6 arguments.
619 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL);
620
621 // Collect the set of registers to pass to the function and their values.
622 // This will be emitted as a sequence of CopyToReg nodes glued to the call
623 // instruction.
625
626 // Collect chains from all the memory opeations that copy arguments to the
627 // stack. They must follow the stack pointer adjustment above and precede the
628 // call instruction itself.
629 SmallVector<SDValue, 8> MemOpChains;
630
631 // VE needs to get address of callee function in a register
632 // So, prepare to copy it to SX12 here.
633
634 // If the callee is a GlobalAddress node (quite common, every direct call is)
635 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
636 // Likewise ExternalSymbol -> TargetExternalSymbol.
637 SDValue Callee = CLI.Callee;
638
639 bool IsPICCall = isPositionIndependent();
640
641 // PC-relative references to external symbols should go through $stub.
642 // If so, we need to prepare GlobalBaseReg first.
643 const TargetMachine &TM = DAG.getTarget();
644 const GlobalValue *GV = nullptr;
645 auto *CalleeG = dyn_cast<GlobalAddressSDNode>(Callee);
646 if (CalleeG)
647 GV = CalleeG->getGlobal();
648 bool Local = TM.shouldAssumeDSOLocal(GV);
649 bool UsePlt = !Local;
651
652 // Turn GlobalAddress/ExternalSymbol node into a value node
653 // containing the address of them here.
654 if (CalleeG) {
655 if (IsPICCall) {
656 if (UsePlt)
657 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF);
658 Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0);
659 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee);
660 } else {
661 Callee = makeHiLoPair(Callee, VE::S_HI32, VE::S_LO32, DAG);
662 }
664 if (IsPICCall) {
665 if (UsePlt)
666 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF);
667 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
668 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee);
669 } else {
670 Callee = makeHiLoPair(Callee, VE::S_HI32, VE::S_LO32, DAG);
671 }
672 }
673
674 RegsToPass.push_back(std::make_pair(VE::SX12, Callee));
675
676 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
677 CCValAssign &VA = ArgLocs[i];
678 SDValue Arg = CLI.OutVals[i];
679
680 // Promote the value if needed.
681 switch (VA.getLocInfo()) {
682 default:
683 llvm_unreachable("Unknown location info!");
685 break;
687 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
688 break;
690 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
691 break;
693 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
694 break;
695 case CCValAssign::BCvt: {
696 // Convert a float argument to i64 with padding.
697 // 63 31 0
698 // +------+------+
699 // | float| 0 |
700 // +------+------+
701 assert(VA.getLocVT() == MVT::i64);
702 assert(VA.getValVT() == MVT::f32);
703 SDValue Undef = SDValue(
704 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0);
705 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
706 Arg = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL,
707 MVT::i64, Undef, Arg, Sub_f32),
708 0);
709 break;
710 }
711 }
712
713 if (VA.isRegLoc()) {
714 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
715 if (!UseBoth)
716 continue;
717 VA = ArgLocs2[i];
718 }
719
720 assert(VA.isMemLoc());
721
722 // Create a store off the stack pointer for this argument.
723 SDValue StackPtr = DAG.getRegister(VE::SX11, PtrVT);
724 // The argument area starts at %fp/%sp + the size of reserved area.
725 SDValue PtrOff =
726 DAG.getIntPtrConstant(VA.getLocMemOffset() + ArgsBaseOffset, DL);
727 PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff);
728 MemOpChains.push_back(
729 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
730 }
731
732 // Emit all stores, make sure they occur before the call.
733 if (!MemOpChains.empty())
734 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
735
736 // Build a sequence of CopyToReg nodes glued together with token chain and
737 // glue operands which copy the outgoing args into registers. The InGlue is
738 // necessary since all emitted instructions must be stuck together in order
739 // to pass the live physical registers.
740 SDValue InGlue;
741 for (const auto &[Reg, N] : RegsToPass) {
742 Chain = DAG.getCopyToReg(Chain, DL, Reg, N, InGlue);
743 InGlue = Chain.getValue(1);
744 }
745
746 // Build the operands for the call instruction itself.
748 Ops.push_back(Chain);
749 for (const auto &[Reg, N] : RegsToPass)
750 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
751
752 // Add a register mask operand representing the call-preserved registers.
753 const VERegisterInfo *TRI = Subtarget->getRegisterInfo();
754 const uint32_t *Mask =
755 TRI->getCallPreservedMask(DAG.getMachineFunction(), CLI.CallConv);
756 assert(Mask && "Missing call preserved mask for calling convention");
757 Ops.push_back(DAG.getRegisterMask(Mask));
758
759 // Make sure the CopyToReg nodes are glued to the call instruction which
760 // consumes the registers.
761 if (InGlue.getNode())
762 Ops.push_back(InGlue);
763
764 // Now the call itself.
765 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
766 Chain = DAG.getNode(VEISD::CALL, DL, NodeTys, Ops);
767 InGlue = Chain.getValue(1);
768
769 // Revert the stack pointer immediately after the call.
770 Chain = DAG.getCALLSEQ_END(Chain, ArgsSize, 0, InGlue, DL);
771 InGlue = Chain.getValue(1);
772
773 // Now extract the return values. This is more or less the same as
774 // LowerFormalArguments.
775
776 // Assign locations to each value returned by this call.
778 CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs,
779 *DAG.getContext());
780
781 // Set inreg flag manually for codegen generated library calls that
782 // return float.
783 if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CB)
784 CLI.Ins[0].Flags.setInReg();
785
786 RVInfo.AnalyzeCallResult(CLI.Ins, getReturnCC(CLI.CallConv));
787
788 // Copy all of the result registers out of their specified physreg.
789 for (unsigned i = 0; i != RVLocs.size(); ++i) {
790 CCValAssign &VA = RVLocs[i];
791 assert(!VA.needsCustom() && "Unexpected custom lowering");
792 Register Reg = VA.getLocReg();
793
794 // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
795 // reside in the same register in the high and low bits. Reuse the
796 // CopyFromReg previous node to avoid duplicate copies.
797 SDValue RV;
798 if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1)))
799 if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg)
800 RV = Chain.getValue(0);
801
802 // But usually we'll create a new CopyFromReg for a different register.
803 if (!RV.getNode()) {
804 RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue);
805 Chain = RV.getValue(1);
806 InGlue = Chain.getValue(2);
807 }
808
809 // The callee promoted the return value, so insert an Assert?ext SDNode so
810 // we won't promote the value again in this function.
811 switch (VA.getLocInfo()) {
813 RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV,
814 DAG.getValueType(VA.getValVT()));
815 break;
817 RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV,
818 DAG.getValueType(VA.getValVT()));
819 break;
820 case CCValAssign::BCvt: {
821 // Extract a float return value from i64 with padding.
822 // 63 31 0
823 // +------+------+
824 // | float| 0 |
825 // +------+------+
826 assert(VA.getLocVT() == MVT::i64);
827 assert(VA.getValVT() == MVT::f32);
828 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
829 RV = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
830 MVT::f32, RV, Sub_f32),
831 0);
832 break;
833 }
834 default:
835 break;
836 }
837
838 // Truncate the register down to the return value type.
839 if (VA.isExtInLoc())
840 RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV);
841
842 InVals.push_back(RV);
843 }
844
845 return Chain;
846}
847
849 const GlobalAddressSDNode *GA) const {
850 // VE uses 64 bit addressing, so we need multiple instructions to generate
851 // an address. Folding address with offset increases the number of
852 // instructions, so that we disable it here. Offsets will be folded in
853 // the DAG combine later if it worth to do so.
854 return false;
855}
856
857/// isFPImmLegal - Returns true if the target can instruction select the
858/// specified FP immediate natively. If false, the legalizer will
859/// materialize the FP immediate as a load from a constant pool.
861 bool ForCodeSize) const {
862 return VT == MVT::f32 || VT == MVT::f64;
863}
864
865/// Determine if the target supports unaligned memory accesses.
866///
867/// This function returns true if the target allows unaligned memory accesses
868/// of the specified type in the given address space. If true, it also returns
869/// whether the unaligned memory access is "fast" in the last argument by
870/// reference. This is used, for example, in situations where an array
871/// copy/move/set is converted to a sequence of store operations. Its use
872/// helps to ensure that such replacements don't generate code that causes an
873/// alignment error (trap) on the target machine.
875 unsigned AddrSpace,
876 Align A,
878 unsigned *Fast) const {
879 if (Fast) {
880 // It's fast anytime on VE
881 *Fast = 1;
882 }
883 return true;
884}
885
887 const VESubtarget &STI)
888 : TargetLowering(TM), Subtarget(&STI) {
889 // Instructions which use registers as conditionals examine all the
890 // bits (as does the pseudo SELECT_CC expansion). I don't think it
891 // matters much whether it's ZeroOrOneBooleanContent, or
892 // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the
893 // former.
896
897 initRegisterClasses();
898 initSPUActions();
899 initVPUActions();
900
902
903 // We have target-specific dag combine patterns for the following nodes:
907
908 // Set function alignment to 16 bytes
910
911 // VE stores all argument by 8 bytes alignment
913
914 computeRegisterProperties(Subtarget->getRegisterInfo());
915}
916
917const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
918#define TARGET_NODE_CASE(NAME) \
919 case VEISD::NAME: \
920 return "VEISD::" #NAME;
921 switch ((VEISD::NodeType)Opcode) {
923 break;
924 TARGET_NODE_CASE(CMPI)
925 TARGET_NODE_CASE(CMPU)
926 TARGET_NODE_CASE(CMPF)
927 TARGET_NODE_CASE(CMPQ)
928 TARGET_NODE_CASE(CMOV)
929 TARGET_NODE_CASE(CALL)
930 TARGET_NODE_CASE(EH_SJLJ_LONGJMP)
931 TARGET_NODE_CASE(EH_SJLJ_SETJMP)
932 TARGET_NODE_CASE(EH_SJLJ_SETUP_DISPATCH)
933 TARGET_NODE_CASE(GETFUNPLT)
934 TARGET_NODE_CASE(GETSTACKTOP)
935 TARGET_NODE_CASE(GETTLSADDR)
936 TARGET_NODE_CASE(GLOBAL_BASE_REG)
939 TARGET_NODE_CASE(RET_GLUE)
940 TARGET_NODE_CASE(TS1AM)
941 TARGET_NODE_CASE(VEC_UNPACK_LO)
942 TARGET_NODE_CASE(VEC_UNPACK_HI)
943 TARGET_NODE_CASE(VEC_PACK)
944 TARGET_NODE_CASE(VEC_BROADCAST)
945 TARGET_NODE_CASE(REPL_I32)
946 TARGET_NODE_CASE(REPL_F32)
947
948 TARGET_NODE_CASE(LEGALAVL)
949
950 // Register the VVP_* SDNodes.
951#define ADD_VVP_OP(VVP_NAME, ...) TARGET_NODE_CASE(VVP_NAME)
952#include "VVPNodes.def"
953 }
954#undef TARGET_NODE_CASE
955 return nullptr;
956}
957
959 EVT VT) const {
960 if (VT.isVector())
961 return VT.changeVectorElementType(MVT::i1);
962 return MVT::i32;
963}
964
965// Convert to a target node and set target flags.
967 SelectionDAG &DAG) const {
969 return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA),
970 GA->getValueType(0), GA->getOffset(), TF);
971
973 return DAG.getTargetBlockAddress(BA->getBlockAddress(), Op.getValueType(),
974 0, TF);
975
977 return DAG.getTargetConstantPool(CP->getConstVal(), CP->getValueType(0),
978 CP->getAlign(), CP->getOffset(), TF);
979
981 return DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0),
982 TF);
983
985 return DAG.getTargetJumpTable(JT->getIndex(), JT->getValueType(0), TF);
986
987 llvm_unreachable("Unhandled address SDNode");
988}
989
990// Split Op into high and low parts according to HiTF and LoTF.
991// Return an ADD node combining the parts.
992SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
993 SelectionDAG &DAG) const {
994 SDLoc DL(Op);
995 EVT VT = Op.getValueType();
996 SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
997 SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
998 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
999}
1000
1001// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
1002// or ExternalSymbol SDNode.
1004 SDLoc DL(Op);
1005 EVT PtrVT = Op.getValueType();
1006
1007 // Handle PIC mode first. VE needs a got load for every variable!
1008 if (isPositionIndependent()) {
1009 auto GlobalN = dyn_cast<GlobalAddressSDNode>(Op);
1010
1012 (GlobalN && GlobalN->getGlobal()->hasLocalLinkage())) {
1013 // Create following instructions for local linkage PIC code.
1014 // lea %reg, label@gotoff_lo
1015 // and %reg, %reg, (32)0
1016 // lea.sl %reg, label@gotoff_hi(%reg, %got)
1017 SDValue HiLo =
1019 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT);
1020 return DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo);
1021 }
1022 // Create following instructions for not local linkage PIC code.
1023 // lea %reg, label@got_lo
1024 // and %reg, %reg, (32)0
1025 // lea.sl %reg, label@got_hi(%reg)
1026 // ld %reg, (%reg, %got)
1028 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT);
1029 SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo);
1030 return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), AbsAddr,
1032 }
1033
1034 // This is one of the absolute code models.
1035 switch (getTargetMachine().getCodeModel()) {
1036 default:
1037 llvm_unreachable("Unsupported absolute code model");
1038 case CodeModel::Small:
1039 case CodeModel::Medium:
1040 case CodeModel::Large:
1041 // abs64.
1042 return makeHiLoPair(Op, VE::S_HI32, VE::S_LO32, DAG);
1043 }
1044}
1045
1046/// Custom Lower {
1047
1048// The mappings for emitLeading/TrailingFence for VE is designed by following
1049// http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
1051 Instruction *Inst,
1052 AtomicOrdering Ord) const {
1053 switch (Ord) {
1056 llvm_unreachable("Invalid fence: unordered/non-atomic");
1059 return nullptr; // Nothing to do
1062 return Builder.CreateFence(AtomicOrdering::Release);
1064 if (!Inst->hasAtomicStore())
1065 return nullptr; // Nothing to do
1066 return Builder.CreateFence(AtomicOrdering::SequentiallyConsistent);
1067 }
1068 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
1069}
1070
1072 Instruction *Inst,
1073 AtomicOrdering Ord) const {
1074 switch (Ord) {
1077 llvm_unreachable("Invalid fence: unordered/not-atomic");
1080 return nullptr; // Nothing to do
1083 return Builder.CreateFence(AtomicOrdering::Acquire);
1085 return Builder.CreateFence(AtomicOrdering::SequentiallyConsistent);
1086 }
1087 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
1088}
1089
1091 SelectionDAG &DAG) const {
1092 SDLoc DL(Op);
1093 AtomicOrdering FenceOrdering =
1094 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
1095 SyncScope::ID FenceSSID =
1096 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
1097
1098 // VE uses Release consistency, so need a fence instruction if it is a
1099 // cross-thread fence.
1100 if (FenceSSID == SyncScope::System) {
1101 switch (FenceOrdering) {
1105 // No need to generate fencem instruction here.
1106 break;
1108 // Generate "fencem 2" as acquire fence.
1109 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other,
1110 DAG.getTargetConstant(2, DL, MVT::i32),
1111 Op.getOperand(0)),
1112 0);
1114 // Generate "fencem 1" as release fence.
1115 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other,
1116 DAG.getTargetConstant(1, DL, MVT::i32),
1117 Op.getOperand(0)),
1118 0);
1121 // Generate "fencem 3" as acq_rel and seq_cst fence.
1122 // FIXME: "fencem 3" doesn't wait for PCIe deveices accesses,
1123 // so seq_cst may require more instruction for them.
1124 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other,
1125 DAG.getTargetConstant(3, DL, MVT::i32),
1126 Op.getOperand(0)),
1127 0);
1128 }
1129 }
1130
1131 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
1132 return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
1133}
1134
1137 // We have TS1AM implementation for i8/i16/i32/i64, so use it.
1138 if (AI->getOperation() == AtomicRMWInst::Xchg) {
1140 }
1141 // FIXME: Support "ATMAM" instruction for LOAD_ADD/SUB/AND/OR.
1142
1143 // Otherwise, expand it using compare and exchange instruction to not call
1144 // __sync_fetch_and_* functions.
1146}
1147
1149 SDValue &Bits) {
1150 SDLoc DL(Op);
1152 SDValue Ptr = N->getOperand(1);
1153 SDValue Val = N->getOperand(2);
1154 EVT PtrVT = Ptr.getValueType();
1155 bool Byte = N->getMemoryVT() == MVT::i8;
1156 // Remainder = AND Ptr, 3
1157 // Flag = 1 << Remainder ; If Byte is true (1 byte swap flag)
1158 // Flag = 3 << Remainder ; If Byte is false (2 bytes swap flag)
1159 // Bits = Remainder << 3
1160 // NewVal = Val << Bits
1161 SDValue Const3 = DAG.getConstant(3, DL, PtrVT);
1162 SDValue Remainder = DAG.getNode(ISD::AND, DL, PtrVT, {Ptr, Const3});
1163 SDValue Mask = Byte ? DAG.getConstant(1, DL, MVT::i32)
1164 : DAG.getConstant(3, DL, MVT::i32);
1165 Flag = DAG.getNode(ISD::SHL, DL, MVT::i32, {Mask, Remainder});
1166 Bits = DAG.getNode(ISD::SHL, DL, PtrVT, {Remainder, Const3});
1167 return DAG.getNode(ISD::SHL, DL, Val.getValueType(), {Val, Bits});
1168}
1169
1171 SDValue Bits) {
1172 SDLoc DL(Op);
1173 EVT VT = Data.getValueType();
1174 bool Byte = cast<AtomicSDNode>(Op)->getMemoryVT() == MVT::i8;
1175 // NewData = Data >> Bits
1176 // Result = NewData & 0xff ; If Byte is true (1 byte)
1177 // Result = NewData & 0xffff ; If Byte is false (2 bytes)
1178
1179 SDValue NewData = DAG.getNode(ISD::SRL, DL, VT, Data, Bits);
1180 return DAG.getNode(ISD::AND, DL, VT,
1181 {NewData, DAG.getConstant(Byte ? 0xff : 0xffff, DL, VT)});
1182}
1183
1185 SelectionDAG &DAG) const {
1186 SDLoc DL(Op);
1188
1189 if (N->getMemoryVT() == MVT::i8) {
1190 // For i8, use "ts1am"
1191 // Input:
1192 // ATOMIC_SWAP Ptr, Val, Order
1193 //
1194 // Output:
1195 // Remainder = AND Ptr, 3
1196 // Flag = 1 << Remainder ; 1 byte swap flag for TS1AM inst.
1197 // Bits = Remainder << 3
1198 // NewVal = Val << Bits
1199 //
1200 // Aligned = AND Ptr, -4
1201 // Data = TS1AM Aligned, Flag, NewVal
1202 //
1203 // NewData = Data >> Bits
1204 // Result = NewData & 0xff ; 1 byte result
1205 SDValue Flag;
1206 SDValue Bits;
1207 SDValue NewVal = prepareTS1AM(Op, DAG, Flag, Bits);
1208
1209 SDValue Ptr = N->getOperand(1);
1211 DAG.getNode(ISD::AND, DL, Ptr.getValueType(),
1212 {Ptr, DAG.getSignedConstant(-4, DL, MVT::i64)});
1213 SDValue TS1AM = DAG.getAtomic(VEISD::TS1AM, DL, N->getMemoryVT(),
1214 DAG.getVTList(Op.getNode()->getValueType(0),
1215 Op.getNode()->getValueType(1)),
1216 {N->getChain(), Aligned, Flag, NewVal},
1217 N->getMemOperand());
1218
1219 SDValue Result = finalizeTS1AM(Op, DAG, TS1AM, Bits);
1220 SDValue Chain = TS1AM.getValue(1);
1221 return DAG.getMergeValues({Result, Chain}, DL);
1222 }
1223 if (N->getMemoryVT() == MVT::i16) {
1224 // For i16, use "ts1am"
1225 SDValue Flag;
1226 SDValue Bits;
1227 SDValue NewVal = prepareTS1AM(Op, DAG, Flag, Bits);
1228
1229 SDValue Ptr = N->getOperand(1);
1231 DAG.getNode(ISD::AND, DL, Ptr.getValueType(),
1232 {Ptr, DAG.getSignedConstant(-4, DL, MVT::i64)});
1233 SDValue TS1AM = DAG.getAtomic(VEISD::TS1AM, DL, N->getMemoryVT(),
1234 DAG.getVTList(Op.getNode()->getValueType(0),
1235 Op.getNode()->getValueType(1)),
1236 {N->getChain(), Aligned, Flag, NewVal},
1237 N->getMemOperand());
1238
1239 SDValue Result = finalizeTS1AM(Op, DAG, TS1AM, Bits);
1240 SDValue Chain = TS1AM.getValue(1);
1241 return DAG.getMergeValues({Result, Chain}, DL);
1242 }
1243 // Otherwise, let llvm legalize it.
1244 return Op;
1245}
1246
1251
1256
1261
1262SDValue
1264 SelectionDAG &DAG) const {
1265 SDLoc DL(Op);
1266
1267 // Generate the following code:
1268 // t1: ch,glue = callseq_start t0, 0, 0
1269 // t2: i64,ch,glue = VEISD::GETTLSADDR t1, label, t1:1
1270 // t3: ch,glue = callseq_end t2, 0, 0, t2:2
1271 // t4: i64,ch,glue = CopyFromReg t3, Register:i64 $sx0, t3:1
1272 SDValue Label = withTargetFlags(Op, 0, DAG);
1273 EVT PtrVT = Op.getValueType();
1274
1275 // Lowering the machine isd will make sure everything is in the right
1276 // location.
1277 SDValue Chain = DAG.getEntryNode();
1278 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1279 const uint32_t *Mask = Subtarget->getRegisterInfo()->getCallPreservedMask(
1281 Chain = DAG.getCALLSEQ_START(Chain, 64, 0, DL);
1282 SDValue Args[] = {Chain, Label, DAG.getRegisterMask(Mask), Chain.getValue(1)};
1283 Chain = DAG.getNode(VEISD::GETTLSADDR, DL, NodeTys, Args);
1284 Chain = DAG.getCALLSEQ_END(Chain, 64, 0, Chain.getValue(1), DL);
1285 Chain = DAG.getCopyFromReg(Chain, DL, VE::SX0, PtrVT, Chain.getValue(1));
1286
1287 // GETTLSADDR will be codegen'ed as call. Inform MFI that function has calls.
1289 MFI.setHasCalls(true);
1290
1291 // Also generate code to prepare a GOT register if it is PIC.
1292 if (isPositionIndependent()) {
1294 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF);
1295 }
1296
1297 return Chain;
1298}
1299
1301 SelectionDAG &DAG) const {
1302 // The current implementation of nld (2.26) doesn't allow local exec model
1303 // code described in VE-tls_v1.1.pdf (*1) as its input. Instead, we always
1304 // generate the general dynamic model code sequence.
1305 //
1306 // *1: https://www.nec.com/en/global/prod/hpc/aurora/document/VE-tls_v1.1.pdf
1307 return lowerToTLSGeneralDynamicModel(Op, DAG);
1308}
1309
1313
1314// Lower a f128 load into two f64 loads.
1316 SDLoc DL(Op);
1317 LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode());
1318 assert(LdNode && LdNode->getOffset().isUndef() && "Unexpected node type");
1319 Align Alignment = LdNode->getAlign();
1320 if (Alignment > 8)
1321 Alignment = Align(8);
1322
1323 SDValue Lo64 =
1324 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), LdNode->getBasePtr(),
1325 LdNode->getPointerInfo(), Alignment,
1328 EVT AddrVT = LdNode->getBasePtr().getValueType();
1329 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, LdNode->getBasePtr(),
1330 DAG.getConstant(8, DL, AddrVT));
1331 SDValue Hi64 =
1332 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), HiPtr,
1333 LdNode->getPointerInfo(), Alignment,
1336
1337 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32);
1338 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32);
1339
1340 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr)
1341 SDNode *InFP128 =
1342 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f128);
1343 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128,
1344 SDValue(InFP128, 0), Hi64, SubRegEven);
1345 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128,
1346 SDValue(InFP128, 0), Lo64, SubRegOdd);
1347 SDValue OutChains[2] = {SDValue(Lo64.getNode(), 1),
1348 SDValue(Hi64.getNode(), 1)};
1349 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1350 SDValue Ops[2] = {SDValue(InFP128, 0), OutChain};
1351 return DAG.getMergeValues(Ops, DL);
1352}
1353
1354// Lower a vXi1 load into following instructions
1355// LDrii %1, (,%addr)
1356// LVMxir %vm, 0, %1
1357// LDrii %2, 8(,%addr)
1358// LVMxir %vm, 0, %2
1359// ...
1361 SDLoc DL(Op);
1362 LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode());
1363 assert(LdNode && LdNode->getOffset().isUndef() && "Unexpected node type");
1364
1365 SDValue BasePtr = LdNode->getBasePtr();
1366 Align Alignment = LdNode->getAlign();
1367 if (Alignment > 8)
1368 Alignment = Align(8);
1369
1370 EVT AddrVT = BasePtr.getValueType();
1371 EVT MemVT = LdNode->getMemoryVT();
1372 if (MemVT == MVT::v256i1 || MemVT == MVT::v4i64) {
1373 SDValue OutChains[4];
1374 SDNode *VM = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MemVT);
1375 for (int i = 0; i < 4; ++i) {
1376 // Generate load dag and prepare chains.
1377 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1378 DAG.getConstant(8 * i, DL, AddrVT));
1379 SDValue Val =
1380 DAG.getLoad(MVT::i64, DL, LdNode->getChain(), Addr,
1381 LdNode->getPointerInfo(), Alignment,
1384 OutChains[i] = SDValue(Val.getNode(), 1);
1385
1386 VM = DAG.getMachineNode(VE::LVMir_m, DL, MVT::i64,
1387 DAG.getTargetConstant(i, DL, MVT::i64), Val,
1388 SDValue(VM, 0));
1389 }
1390 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1391 SDValue Ops[2] = {SDValue(VM, 0), OutChain};
1392 return DAG.getMergeValues(Ops, DL);
1393 } else if (MemVT == MVT::v512i1 || MemVT == MVT::v8i64) {
1394 SDValue OutChains[8];
1395 SDNode *VM = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MemVT);
1396 for (int i = 0; i < 8; ++i) {
1397 // Generate load dag and prepare chains.
1398 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1399 DAG.getConstant(8 * i, DL, AddrVT));
1400 SDValue Val =
1401 DAG.getLoad(MVT::i64, DL, LdNode->getChain(), Addr,
1402 LdNode->getPointerInfo(), Alignment,
1405 OutChains[i] = SDValue(Val.getNode(), 1);
1406
1407 VM = DAG.getMachineNode(VE::LVMyir_y, DL, MVT::i64,
1408 DAG.getTargetConstant(i, DL, MVT::i64), Val,
1409 SDValue(VM, 0));
1410 }
1411 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1412 SDValue Ops[2] = {SDValue(VM, 0), OutChain};
1413 return DAG.getMergeValues(Ops, DL);
1414 } else {
1415 // Otherwise, ask llvm to expand it.
1416 return SDValue();
1417 }
1418}
1419
1421 LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
1422 EVT MemVT = LdNode->getMemoryVT();
1423
1424 // If VPU is enabled, always expand non-mask vector loads to VVP
1425 if (Subtarget->enableVPU() && MemVT.isVector() && !isMaskType(MemVT))
1426 return lowerToVVP(Op, DAG);
1427
1428 SDValue BasePtr = LdNode->getBasePtr();
1429 if (isa<FrameIndexSDNode>(BasePtr.getNode())) {
1430 // Do not expand store instruction with frame index here because of
1431 // dependency problems. We expand it later in eliminateFrameIndex().
1432 return Op;
1433 }
1434
1435 if (MemVT == MVT::f128)
1436 return lowerLoadF128(Op, DAG);
1437 if (isMaskType(MemVT))
1438 return lowerLoadI1(Op, DAG);
1439
1440 return Op;
1441}
1442
1443// Lower a f128 store into two f64 stores.
1445 SDLoc DL(Op);
1446 StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode());
1447 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type");
1448
1449 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32);
1450 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32);
1451
1452 SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64,
1453 StNode->getValue(), SubRegEven);
1454 SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64,
1455 StNode->getValue(), SubRegOdd);
1456
1457 Align Alignment = StNode->getAlign();
1458 if (Alignment > 8)
1459 Alignment = Align(8);
1460
1461 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr)
1462 SDValue OutChains[2];
1463 OutChains[0] =
1464 DAG.getStore(StNode->getChain(), DL, SDValue(Lo64, 0),
1465 StNode->getBasePtr(), MachinePointerInfo(), Alignment,
1468 EVT AddrVT = StNode->getBasePtr().getValueType();
1469 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, StNode->getBasePtr(),
1470 DAG.getConstant(8, DL, AddrVT));
1471 OutChains[1] =
1472 DAG.getStore(StNode->getChain(), DL, SDValue(Hi64, 0), HiPtr,
1473 MachinePointerInfo(), Alignment,
1476 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1477}
1478
1479// Lower a vXi1 store into following instructions
1480// SVMi %1, %vm, 0
1481// STrii %1, (,%addr)
1482// SVMi %2, %vm, 1
1483// STrii %2, 8(,%addr)
1484// ...
1486 SDLoc DL(Op);
1487 StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode());
1488 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type");
1489
1490 SDValue BasePtr = StNode->getBasePtr();
1491 Align Alignment = StNode->getAlign();
1492 if (Alignment > 8)
1493 Alignment = Align(8);
1494 EVT AddrVT = BasePtr.getValueType();
1495 EVT MemVT = StNode->getMemoryVT();
1496 if (MemVT == MVT::v256i1 || MemVT == MVT::v4i64) {
1497 SDValue OutChains[4];
1498 for (int i = 0; i < 4; ++i) {
1499 SDNode *V =
1500 DAG.getMachineNode(VE::SVMmi, DL, MVT::i64, StNode->getValue(),
1501 DAG.getTargetConstant(i, DL, MVT::i64));
1502 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1503 DAG.getConstant(8 * i, DL, AddrVT));
1504 OutChains[i] =
1505 DAG.getStore(StNode->getChain(), DL, SDValue(V, 0), Addr,
1506 MachinePointerInfo(), Alignment,
1509 }
1510 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1511 } else if (MemVT == MVT::v512i1 || MemVT == MVT::v8i64) {
1512 SDValue OutChains[8];
1513 for (int i = 0; i < 8; ++i) {
1514 SDNode *V =
1515 DAG.getMachineNode(VE::SVMyi, DL, MVT::i64, StNode->getValue(),
1516 DAG.getTargetConstant(i, DL, MVT::i64));
1517 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1518 DAG.getConstant(8 * i, DL, AddrVT));
1519 OutChains[i] =
1520 DAG.getStore(StNode->getChain(), DL, SDValue(V, 0), Addr,
1521 MachinePointerInfo(), Alignment,
1524 }
1525 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1526 } else {
1527 // Otherwise, ask llvm to expand it.
1528 return SDValue();
1529 }
1530}
1531
1533 StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode());
1534 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type");
1535 EVT MemVT = StNode->getMemoryVT();
1536
1537 // If VPU is enabled, always expand non-mask vector stores to VVP
1538 if (Subtarget->enableVPU() && MemVT.isVector() && !isMaskType(MemVT))
1539 return lowerToVVP(Op, DAG);
1540
1541 SDValue BasePtr = StNode->getBasePtr();
1542 if (isa<FrameIndexSDNode>(BasePtr.getNode())) {
1543 // Do not expand store instruction with frame index here because of
1544 // dependency problems. We expand it later in eliminateFrameIndex().
1545 return Op;
1546 }
1547
1548 if (MemVT == MVT::f128)
1549 return lowerStoreF128(Op, DAG);
1550 if (isMaskType(MemVT))
1551 return lowerStoreI1(Op, DAG);
1552
1553 // Otherwise, ask llvm to expand it.
1554 return SDValue();
1555}
1556
1560 auto PtrVT = getPointerTy(DAG.getDataLayout());
1561
1562 // Need frame address to find the address of VarArgsFrameIndex.
1564
1565 // vastart just stores the address of the VarArgsFrameIndex slot into the
1566 // memory location argument.
1567 SDLoc DL(Op);
1568 SDValue Offset =
1569 DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(VE::SX9, PtrVT),
1570 DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL));
1571 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1572 return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1),
1573 MachinePointerInfo(SV));
1574}
1575
1577 SDNode *Node = Op.getNode();
1578 EVT VT = Node->getValueType(0);
1579 SDValue InChain = Node->getOperand(0);
1580 SDValue VAListPtr = Node->getOperand(1);
1581 EVT PtrVT = VAListPtr.getValueType();
1582 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1583 SDLoc DL(Node);
1584 SDValue VAList =
1585 DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV));
1586 SDValue Chain = VAList.getValue(1);
1587 SDValue NextPtr;
1588
1589 if (VT == MVT::f128) {
1590 // VE f128 values must be stored with 16 bytes alignment. We don't
1591 // know the actual alignment of VAList, so we take alignment of it
1592 // dynamically.
1593 int Align = 16;
1594 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
1595 DAG.getConstant(Align - 1, DL, PtrVT));
1596 VAList = DAG.getNode(ISD::AND, DL, PtrVT, VAList,
1597 DAG.getSignedConstant(-Align, DL, PtrVT));
1598 // Increment the pointer, VAList, by 16 to the next vaarg.
1599 NextPtr =
1600 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(16, DL));
1601 } else if (VT == MVT::f32) {
1602 // float --> need special handling like below.
1603 // 0 4
1604 // +------+------+
1605 // | empty| float|
1606 // +------+------+
1607 // Increment the pointer, VAList, by 8 to the next vaarg.
1608 NextPtr =
1609 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL));
1610 // Then, adjust VAList.
1611 unsigned InternalOffset = 4;
1612 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
1613 DAG.getConstant(InternalOffset, DL, PtrVT));
1614 } else {
1615 // Increment the pointer, VAList, by 8 to the next vaarg.
1616 NextPtr =
1617 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL));
1618 }
1619
1620 // Store the incremented VAList to the legalized pointer.
1621 InChain = DAG.getStore(Chain, DL, NextPtr, VAListPtr, MachinePointerInfo(SV));
1622
1623 // Load the actual argument out of the pointer VAList.
1624 // We can't count on greater alignment than the word size.
1625 return DAG.getLoad(
1626 VT, DL, InChain, VAList, MachinePointerInfo(),
1627 Align(std::min(PtrVT.getSizeInBits(), VT.getSizeInBits()) / 8));
1628}
1629
1631 SelectionDAG &DAG) const {
1632 // Generate following code.
1633 // (void)__llvm_grow_stack(size);
1634 // ret = GETSTACKTOP; // pseudo instruction
1635 SDLoc DL(Op);
1636
1637 // Get the inputs.
1638 SDNode *Node = Op.getNode();
1639 SDValue Chain = Op.getOperand(0);
1640 SDValue Size = Op.getOperand(1);
1641 MaybeAlign Alignment(Op.getConstantOperandVal(2));
1642 EVT VT = Node->getValueType(0);
1643
1644 // Chain the dynamic stack allocation so that it doesn't modify the stack
1645 // pointer when other instructions are using the stack.
1646 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
1647
1648 const TargetFrameLowering &TFI = *Subtarget->getFrameLowering();
1649 Align StackAlign = TFI.getStackAlign();
1650 bool NeedsAlign = Alignment.valueOrOne() > StackAlign;
1651
1652 // Prepare arguments
1654 Args.emplace_back(Size, Size.getValueType().getTypeForEVT(*DAG.getContext()));
1655 if (NeedsAlign) {
1656 SDValue Align = DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT);
1657 Args.emplace_back(Align,
1658 Align.getValueType().getTypeForEVT(*DAG.getContext()));
1659 }
1660 Type *RetTy = Type::getVoidTy(*DAG.getContext());
1661
1662 EVT PtrVT = Op.getValueType();
1663 SDValue Callee;
1664 if (NeedsAlign) {
1665 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack_align", PtrVT, 0);
1666 } else {
1667 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack", PtrVT, 0);
1668 }
1669
1671 CLI.setDebugLoc(DL)
1672 .setChain(Chain)
1673 .setCallee(CallingConv::PreserveAll, RetTy, Callee, std::move(Args))
1674 .setDiscardResult(true);
1675 std::pair<SDValue, SDValue> pair = LowerCallTo(CLI);
1676 Chain = pair.second;
1677 SDValue Result = DAG.getNode(VEISD::GETSTACKTOP, DL, VT, Chain);
1678 if (NeedsAlign) {
1679 Result = DAG.getNode(ISD::ADD, DL, VT, Result,
1680 DAG.getConstant((Alignment->value() - 1ULL), DL, VT));
1681 Result = DAG.getNode(ISD::AND, DL, VT, Result,
1682 DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT));
1683 }
1684 // Chain = Result.getValue(1);
1685 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, SDValue(), DL);
1686
1687 SDValue Ops[2] = {Result, Chain};
1688 return DAG.getMergeValues(Ops, DL);
1689}
1690
1692 SelectionDAG &DAG) const {
1693 SDLoc DL(Op);
1694 return DAG.getNode(VEISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0),
1695 Op.getOperand(1));
1696}
1697
1699 SelectionDAG &DAG) const {
1700 SDLoc DL(Op);
1701 return DAG.getNode(VEISD::EH_SJLJ_SETJMP, DL,
1702 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
1703 Op.getOperand(1));
1704}
1705
1707 SelectionDAG &DAG) const {
1708 SDLoc DL(Op);
1709 return DAG.getNode(VEISD::EH_SJLJ_SETUP_DISPATCH, DL, MVT::Other,
1710 Op.getOperand(0));
1711}
1712
1714 const VETargetLowering &TLI,
1715 const VESubtarget *Subtarget) {
1716 SDLoc DL(Op);
1718 EVT PtrVT = TLI.getPointerTy(MF.getDataLayout());
1719
1720 MachineFrameInfo &MFI = MF.getFrameInfo();
1721 MFI.setFrameAddressIsTaken(true);
1722
1723 unsigned Depth = Op.getConstantOperandVal(0);
1724 const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
1725 Register FrameReg = RegInfo->getFrameRegister(MF);
1726 SDValue FrameAddr =
1727 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, PtrVT);
1728 while (Depth--)
1729 FrameAddr = DAG.getLoad(Op.getValueType(), DL, DAG.getEntryNode(),
1730 FrameAddr, MachinePointerInfo());
1731 return FrameAddr;
1732}
1733
1735 const VETargetLowering &TLI,
1736 const VESubtarget *Subtarget) {
1738 MachineFrameInfo &MFI = MF.getFrameInfo();
1739 MFI.setReturnAddressIsTaken(true);
1740
1741 SDValue FrameAddr = lowerFRAMEADDR(Op, DAG, TLI, Subtarget);
1742
1743 SDLoc DL(Op);
1744 EVT VT = Op.getValueType();
1745 SDValue Offset = DAG.getConstant(8, DL, VT);
1746 return DAG.getLoad(VT, DL, DAG.getEntryNode(),
1747 DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset),
1749}
1750
1752 SelectionDAG &DAG) const {
1753 SDLoc DL(Op);
1754 unsigned IntNo = Op.getConstantOperandVal(0);
1755 switch (IntNo) {
1756 default: // Don't custom lower most intrinsics.
1757 return SDValue();
1758 case Intrinsic::eh_sjlj_lsda: {
1760 MVT VT = Op.getSimpleValueType();
1761 const VETargetMachine *TM =
1762 static_cast<const VETargetMachine *>(&DAG.getTarget());
1763
1764 // Create GCC_except_tableXX string. The real symbol for that will be
1765 // generated in EHStreamer::emitExceptionTable() later. So, we just
1766 // borrow it's name here.
1767 TM->getStrList()->push_back(std::string(
1768 (Twine("GCC_except_table") + Twine(MF.getFunctionNumber())).str()));
1769 SDValue Addr =
1770 DAG.getTargetExternalSymbol(TM->getStrList()->back().c_str(), VT, 0);
1771 if (isPositionIndependent()) {
1773 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, VT);
1774 return DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Addr);
1775 }
1776 return makeHiLoPair(Addr, VE::S_HI32, VE::S_LO32, DAG);
1777 }
1778 }
1779}
1780
1781static bool getUniqueInsertion(SDNode *N, unsigned &UniqueIdx) {
1783 return false;
1784 const auto *BVN = cast<BuildVectorSDNode>(N);
1785
1786 // Find first non-undef insertion.
1787 unsigned Idx;
1788 for (Idx = 0; Idx < BVN->getNumOperands(); ++Idx) {
1789 auto ElemV = BVN->getOperand(Idx);
1790 if (!ElemV->isUndef())
1791 break;
1792 }
1793 // Catch the (hypothetical) all-undef case.
1794 if (Idx == BVN->getNumOperands())
1795 return false;
1796 // Remember insertion.
1797 UniqueIdx = Idx++;
1798 // Verify that all other insertions are undef.
1799 for (; Idx < BVN->getNumOperands(); ++Idx) {
1800 auto ElemV = BVN->getOperand(Idx);
1801 if (!ElemV->isUndef())
1802 return false;
1803 }
1804 return true;
1805}
1806
1808 if (auto *BuildVec = dyn_cast<BuildVectorSDNode>(N)) {
1809 return BuildVec->getSplatValue();
1810 }
1811 return SDValue();
1812}
1813
1815 SelectionDAG &DAG) const {
1816 VECustomDAG CDAG(DAG, Op);
1817 MVT ResultVT = Op.getSimpleValueType();
1818
1819 // If there is just one element, expand to INSERT_VECTOR_ELT.
1820 unsigned UniqueIdx;
1821 if (getUniqueInsertion(Op.getNode(), UniqueIdx)) {
1822 SDValue AccuV = CDAG.getUNDEF(Op.getValueType());
1823 auto ElemV = Op->getOperand(UniqueIdx);
1824 SDValue IdxV = CDAG.getConstant(UniqueIdx, MVT::i64);
1825 return CDAG.getNode(ISD::INSERT_VECTOR_ELT, ResultVT, {AccuV, ElemV, IdxV});
1826 }
1827
1828 // Else emit a broadcast.
1829 if (SDValue ScalarV = getSplatValue(Op.getNode())) {
1830 unsigned NumEls = ResultVT.getVectorNumElements();
1831 auto AVL = CDAG.getConstant(NumEls, MVT::i32);
1832 return CDAG.getBroadcast(ResultVT, ScalarV, AVL);
1833 }
1834
1835 // Expand
1836 return SDValue();
1837}
1838
1841 // Custom legalization on VVP_* and VEC_* opcodes is required to pack-legalize
1842 // these operations (transform nodes such that their AVL parameter refers to
1843 // packs of 64bit, instead of number of elements.
1844
1845 // Packing opcodes are created with a pack-legal AVL (LEGALAVL). No need to
1846 // re-visit them.
1847 if (isPackingSupportOpcode(Op.getOpcode()))
1848 return Legal;
1849
1850 // Custom lower to legalize AVL for packed mode.
1851 if (isVVPOrVEC(Op.getOpcode()))
1852 return Custom;
1853 return Legal;
1854}
1855
1857 LLVM_DEBUG(dbgs() << "::LowerOperation "; Op.dump(&DAG));
1858 unsigned Opcode = Op.getOpcode();
1859
1860 /// Scalar isel.
1861 switch (Opcode) {
1862 case ISD::ATOMIC_FENCE:
1863 return lowerATOMIC_FENCE(Op, DAG);
1864 case ISD::ATOMIC_SWAP:
1865 return lowerATOMIC_SWAP(Op, DAG);
1866 case ISD::BlockAddress:
1867 return lowerBlockAddress(Op, DAG);
1868 case ISD::ConstantPool:
1869 return lowerConstantPool(Op, DAG);
1870 case ISD::DYNAMIC_STACKALLOC:
1871 return lowerDYNAMIC_STACKALLOC(Op, DAG);
1873 return lowerEH_SJLJ_LONGJMP(Op, DAG);
1875 return lowerEH_SJLJ_SETJMP(Op, DAG);
1877 return lowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
1878 case ISD::FRAMEADDR:
1879 return lowerFRAMEADDR(Op, DAG, *this, Subtarget);
1880 case ISD::GlobalAddress:
1881 return lowerGlobalAddress(Op, DAG);
1883 return lowerGlobalTLSAddress(Op, DAG);
1885 return lowerINTRINSIC_WO_CHAIN(Op, DAG);
1886 case ISD::JumpTable:
1887 return lowerJumpTable(Op, DAG);
1888 case ISD::LOAD:
1889 return lowerLOAD(Op, DAG);
1890 case ISD::RETURNADDR:
1891 return lowerRETURNADDR(Op, DAG, *this, Subtarget);
1892 case ISD::BUILD_VECTOR:
1893 return lowerBUILD_VECTOR(Op, DAG);
1894 case ISD::STORE:
1895 return lowerSTORE(Op, DAG);
1896 case ISD::VASTART:
1897 return lowerVASTART(Op, DAG);
1898 case ISD::VAARG:
1899 return lowerVAARG(Op, DAG);
1900
1902 return lowerINSERT_VECTOR_ELT(Op, DAG);
1904 return lowerEXTRACT_VECTOR_ELT(Op, DAG);
1905 }
1906
1907 /// Vector isel.
1908 if (ISD::isVPOpcode(Opcode))
1909 return lowerToVVP(Op, DAG);
1910
1911 switch (Opcode) {
1912 default:
1913 llvm_unreachable("Should not custom lower this!");
1914
1915 // Legalize the AVL of this internal node.
1917#define ADD_VVP_OP(VVP_NAME, ...) case VEISD::VVP_NAME:
1918#include "VVPNodes.def"
1919 // AVL already legalized.
1920 if (getAnnotatedNodeAVL(Op).second)
1921 return Op;
1922 return legalizeInternalVectorOp(Op, DAG);
1923
1924 // Translate into a VEC_*/VVP_* layer operation.
1925 case ISD::MLOAD:
1926 case ISD::MSTORE:
1927#define ADD_VVP_OP(VVP_NAME, ISD_NAME) case ISD::ISD_NAME:
1928#include "VVPNodes.def"
1929 if (isMaskArithmetic(Op) && isPackedVectorType(Op.getValueType()))
1930 return splitMaskArithmetic(Op, DAG);
1931 return lowerToVVP(Op, DAG);
1932 }
1933}
1934/// } Custom Lower
1935
1938 SelectionDAG &DAG) const {
1939 switch (N->getOpcode()) {
1940 case ISD::ATOMIC_SWAP:
1941 // Let LLVM expand atomic swap instruction through LowerOperation.
1942 return;
1943 default:
1944 LLVM_DEBUG(N->dumpr(&DAG));
1945 llvm_unreachable("Do not know how to custom type legalize this operation!");
1946 }
1947}
1948
1949/// JumpTable for VE.
1950///
1951/// VE cannot generate relocatable symbol in jump table. VE cannot
1952/// generate expressions using symbols in both text segment and data
1953/// segment like below.
1954/// .4byte .LBB0_2-.LJTI0_0
1955/// So, we generate offset from the top of function like below as
1956/// a custom label.
1957/// .4byte .LBB0_2-<function name>
1958
1960 // Use custom label for PIC.
1963
1964 // Otherwise, use the normal jump table encoding heuristics.
1966}
1967
1969 const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB,
1970 unsigned Uid, MCContext &Ctx) const {
1972
1973 // Generate custom label for PIC like below.
1974 // .4bytes .LBB0_2-<function name>
1975 const auto *Value = MCSymbolRefExpr::create(MBB->getSymbol(), Ctx);
1976 MCSymbol *Sym = Ctx.getOrCreateSymbol(MBB->getParent()->getName().data());
1977 const auto *Base = MCSymbolRefExpr::create(Sym, Ctx);
1978 return MCBinaryExpr::createSub(Value, Base, Ctx);
1979}
1980
1982 SelectionDAG &DAG) const {
1984 SDLoc DL(Table);
1986 assert(Function != nullptr);
1987 auto PtrTy = getPointerTy(DAG.getDataLayout(), Function->getAddressSpace());
1988
1989 // In the jump table, we have following values in PIC mode.
1990 // .4bytes .LBB0_2-<function name>
1991 // We need to add this value and the address of this function to generate
1992 // .LBB0_2 label correctly under PIC mode. So, we want to generate following
1993 // instructions:
1994 // lea %reg, fun@gotoff_lo
1995 // and %reg, %reg, (32)0
1996 // lea.sl %reg, fun@gotoff_hi(%reg, %got)
1997 // In order to do so, we need to genarate correctly marked DAG node using
1998 // makeHiLoPair.
1999 SDValue Op = DAG.getGlobalAddress(Function, DL, PtrTy);
2001 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrTy);
2002 return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo);
2003}
2004
2007 MachineBasicBlock *TargetBB,
2008 const DebugLoc &DL) const {
2009 MachineFunction *MF = MBB.getParent();
2011 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2012
2013 const TargetRegisterClass *RC = &VE::I64RegClass;
2014 Register Tmp1 = MRI.createVirtualRegister(RC);
2015 Register Tmp2 = MRI.createVirtualRegister(RC);
2016 Register Result = MRI.createVirtualRegister(RC);
2017
2018 if (isPositionIndependent()) {
2019 // Create following instructions for local linkage PIC code.
2020 // lea %Tmp1, TargetBB@gotoff_lo
2021 // and %Tmp2, %Tmp1, (32)0
2022 // lea.sl %Result, TargetBB@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2023 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2024 .addImm(0)
2025 .addImm(0)
2026 .addMBB(TargetBB, VE::S_GOTOFF_LO32);
2027 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2028 .addReg(Tmp1, getKillRegState(true))
2029 .addImm(M0(32));
2030 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
2031 .addReg(VE::SX15)
2032 .addReg(Tmp2, getKillRegState(true))
2033 .addMBB(TargetBB, VE::S_GOTOFF_HI32);
2034 } else {
2035 // Create following instructions for non-PIC code.
2036 // lea %Tmp1, TargetBB@lo
2037 // and %Tmp2, %Tmp1, (32)0
2038 // lea.sl %Result, TargetBB@hi(%Tmp2)
2039 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2040 .addImm(0)
2041 .addImm(0)
2042 .addMBB(TargetBB, VE::S_LO32);
2043 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2044 .addReg(Tmp1, getKillRegState(true))
2045 .addImm(M0(32));
2046 BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
2047 .addReg(Tmp2, getKillRegState(true))
2048 .addImm(0)
2049 .addMBB(TargetBB, VE::S_HI32);
2050 }
2051 return Result;
2052}
2053
2056 StringRef Symbol, const DebugLoc &DL,
2057 bool IsLocal = false,
2058 bool IsCall = false) const {
2059 MachineFunction *MF = MBB.getParent();
2061 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2062
2063 const TargetRegisterClass *RC = &VE::I64RegClass;
2064 Register Result = MRI.createVirtualRegister(RC);
2065
2066 if (isPositionIndependent()) {
2067 if (IsCall && !IsLocal) {
2068 // Create following instructions for non-local linkage PIC code function
2069 // calls. These instructions uses IC and magic number -24, so we expand
2070 // them in VEAsmPrinter.cpp from GETFUNPLT pseudo instruction.
2071 // lea %Reg, Symbol@plt_lo(-24)
2072 // and %Reg, %Reg, (32)0
2073 // sic %s16
2074 // lea.sl %Result, Symbol@plt_hi(%Reg, %s16) ; %s16 is PLT
2075 BuildMI(MBB, I, DL, TII->get(VE::GETFUNPLT), Result)
2076 .addExternalSymbol("abort");
2077 } else if (IsLocal) {
2078 Register Tmp1 = MRI.createVirtualRegister(RC);
2079 Register Tmp2 = MRI.createVirtualRegister(RC);
2080 // Create following instructions for local linkage PIC code.
2081 // lea %Tmp1, Symbol@gotoff_lo
2082 // and %Tmp2, %Tmp1, (32)0
2083 // lea.sl %Result, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2084 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2085 .addImm(0)
2086 .addImm(0)
2087 .addExternalSymbol(Symbol.data(), VE::S_GOTOFF_LO32);
2088 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2089 .addReg(Tmp1, getKillRegState(true))
2090 .addImm(M0(32));
2091 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
2092 .addReg(VE::SX15)
2093 .addReg(Tmp2, getKillRegState(true))
2094 .addExternalSymbol(Symbol.data(), VE::S_GOTOFF_HI32);
2095 } else {
2096 Register Tmp1 = MRI.createVirtualRegister(RC);
2097 Register Tmp2 = MRI.createVirtualRegister(RC);
2098 // Create following instructions for not local linkage PIC code.
2099 // lea %Tmp1, Symbol@got_lo
2100 // and %Tmp2, %Tmp1, (32)0
2101 // lea.sl %Tmp3, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2102 // ld %Result, 0(%Tmp3)
2103 Register Tmp3 = MRI.createVirtualRegister(RC);
2104 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2105 .addImm(0)
2106 .addImm(0)
2107 .addExternalSymbol(Symbol.data(), VE::S_GOT_LO32);
2108 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2109 .addReg(Tmp1, getKillRegState(true))
2110 .addImm(M0(32));
2111 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Tmp3)
2112 .addReg(VE::SX15)
2113 .addReg(Tmp2, getKillRegState(true))
2114 .addExternalSymbol(Symbol.data(), VE::S_GOT_HI32);
2115 BuildMI(MBB, I, DL, TII->get(VE::LDrii), Result)
2116 .addReg(Tmp3, getKillRegState(true))
2117 .addImm(0)
2118 .addImm(0);
2119 }
2120 } else {
2121 Register Tmp1 = MRI.createVirtualRegister(RC);
2122 Register Tmp2 = MRI.createVirtualRegister(RC);
2123 // Create following instructions for non-PIC code.
2124 // lea %Tmp1, Symbol@lo
2125 // and %Tmp2, %Tmp1, (32)0
2126 // lea.sl %Result, Symbol@hi(%Tmp2)
2127 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2128 .addImm(0)
2129 .addImm(0)
2130 .addExternalSymbol(Symbol.data(), VE::S_LO32);
2131 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2132 .addReg(Tmp1, getKillRegState(true))
2133 .addImm(M0(32));
2134 BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
2135 .addReg(Tmp2, getKillRegState(true))
2136 .addImm(0)
2137 .addExternalSymbol(Symbol.data(), VE::S_HI32);
2138 }
2139 return Result;
2140}
2141
2144 MachineBasicBlock *DispatchBB,
2145 int FI, int Offset) const {
2146 DebugLoc DL = MI.getDebugLoc();
2147 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2148
2149 Register LabelReg =
2151
2152 // Store an address of DispatchBB to a given jmpbuf[1] where has next IC
2153 // referenced by longjmp (throw) later.
2154 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2155 addFrameReference(MIB, FI, Offset); // jmpbuf[1]
2156 MIB.addReg(LabelReg, getKillRegState(true));
2157}
2158
2161 MachineBasicBlock *MBB) const {
2162 DebugLoc DL = MI.getDebugLoc();
2163 MachineFunction *MF = MBB->getParent();
2164 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
2165 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
2167
2168 const BasicBlock *BB = MBB->getBasicBlock();
2169 MachineFunction::iterator I = ++MBB->getIterator();
2170
2171 // Memory Reference.
2172 SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands());
2173 Register BufReg = MI.getOperand(1).getReg();
2174
2175 Register DstReg;
2176
2177 DstReg = MI.getOperand(0).getReg();
2178 const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
2179 assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
2180 (void)TRI;
2181 Register MainDestReg = MRI.createVirtualRegister(RC);
2182 Register RestoreDestReg = MRI.createVirtualRegister(RC);
2183
2184 // For `v = call @llvm.eh.sjlj.setjmp(buf)`, we generate following
2185 // instructions. SP/FP must be saved in jmpbuf before `llvm.eh.sjlj.setjmp`.
2186 //
2187 // ThisMBB:
2188 // buf[3] = %s17 iff %s17 is used as BP
2189 // buf[1] = RestoreMBB as IC after longjmp
2190 // # SjLjSetup RestoreMBB
2191 //
2192 // MainMBB:
2193 // v_main = 0
2194 //
2195 // SinkMBB:
2196 // v = phi(v_main, MainMBB, v_restore, RestoreMBB)
2197 // ...
2198 //
2199 // RestoreMBB:
2200 // %s17 = buf[3] = iff %s17 is used as BP
2201 // v_restore = 1
2202 // goto SinkMBB
2203
2204 MachineBasicBlock *ThisMBB = MBB;
2205 MachineBasicBlock *MainMBB = MF->CreateMachineBasicBlock(BB);
2206 MachineBasicBlock *SinkMBB = MF->CreateMachineBasicBlock(BB);
2207 MachineBasicBlock *RestoreMBB = MF->CreateMachineBasicBlock(BB);
2208 MF->insert(I, MainMBB);
2209 MF->insert(I, SinkMBB);
2210 MF->push_back(RestoreMBB);
2211 RestoreMBB->setMachineBlockAddressTaken();
2212
2213 // Transfer the remainder of BB and its successor edges to SinkMBB.
2214 SinkMBB->splice(SinkMBB->begin(), MBB,
2215 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
2217
2218 // ThisMBB:
2219 Register LabelReg =
2221
2222 // Store BP in buf[3] iff this function is using BP.
2223 const VEFrameLowering *TFI = Subtarget->getFrameLowering();
2224 if (TFI->hasBP(*MF)) {
2225 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2226 MIB.addReg(BufReg);
2227 MIB.addImm(0);
2228 MIB.addImm(24);
2229 MIB.addReg(VE::SX17);
2230 MIB.setMemRefs(MMOs);
2231 }
2232
2233 // Store IP in buf[1].
2234 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2235 MIB.add(MI.getOperand(1)); // we can preserve the kill flags here.
2236 MIB.addImm(0);
2237 MIB.addImm(8);
2238 MIB.addReg(LabelReg, getKillRegState(true));
2239 MIB.setMemRefs(MMOs);
2240
2241 // SP/FP are already stored in jmpbuf before `llvm.eh.sjlj.setjmp`.
2242
2243 // Insert setup.
2244 MIB =
2245 BuildMI(*ThisMBB, MI, DL, TII->get(VE::EH_SjLj_Setup)).addMBB(RestoreMBB);
2246
2247 const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2248 MIB.addRegMask(RegInfo->getNoPreservedMask());
2249 ThisMBB->addSuccessor(MainMBB);
2250 ThisMBB->addSuccessor(RestoreMBB);
2251
2252 // MainMBB:
2253 BuildMI(MainMBB, DL, TII->get(VE::LEAzii), MainDestReg)
2254 .addImm(0)
2255 .addImm(0)
2256 .addImm(0);
2257 MainMBB->addSuccessor(SinkMBB);
2258
2259 // SinkMBB:
2260 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII->get(VE::PHI), DstReg)
2261 .addReg(MainDestReg)
2262 .addMBB(MainMBB)
2263 .addReg(RestoreDestReg)
2264 .addMBB(RestoreMBB);
2265
2266 // RestoreMBB:
2267 // Restore BP from buf[3] iff this function is using BP. The address of
2268 // buf is in SX10.
2269 // FIXME: Better to not use SX10 here
2270 if (TFI->hasBP(*MF)) {
2272 BuildMI(RestoreMBB, DL, TII->get(VE::LDrii), VE::SX17);
2273 MIB.addReg(VE::SX10);
2274 MIB.addImm(0);
2275 MIB.addImm(24);
2276 MIB.setMemRefs(MMOs);
2277 }
2278 BuildMI(RestoreMBB, DL, TII->get(VE::LEAzii), RestoreDestReg)
2279 .addImm(0)
2280 .addImm(0)
2281 .addImm(1);
2282 BuildMI(RestoreMBB, DL, TII->get(VE::BRCFLa_t)).addMBB(SinkMBB);
2283 RestoreMBB->addSuccessor(SinkMBB);
2284
2285 MI.eraseFromParent();
2286 return SinkMBB;
2287}
2288
2291 MachineBasicBlock *MBB) const {
2292 DebugLoc DL = MI.getDebugLoc();
2293 MachineFunction *MF = MBB->getParent();
2294 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
2296
2297 // Memory Reference.
2298 SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands());
2299 Register BufReg = MI.getOperand(0).getReg();
2300
2301 Register Tmp = MRI.createVirtualRegister(&VE::I64RegClass);
2302 // Since FP is only updated here but NOT referenced, it's treated as GPR.
2303 Register FP = VE::SX9;
2304 Register SP = VE::SX11;
2305
2307
2308 MachineBasicBlock *ThisMBB = MBB;
2309
2310 // For `call @llvm.eh.sjlj.longjmp(buf)`, we generate following instructions.
2311 //
2312 // ThisMBB:
2313 // %fp = load buf[0]
2314 // %jmp = load buf[1]
2315 // %s10 = buf ; Store an address of buf to SX10 for RestoreMBB
2316 // %sp = load buf[2] ; generated by llvm.eh.sjlj.setjmp.
2317 // jmp %jmp
2318
2319 // Reload FP.
2320 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), FP);
2321 MIB.addReg(BufReg);
2322 MIB.addImm(0);
2323 MIB.addImm(0);
2324 MIB.setMemRefs(MMOs);
2325
2326 // Reload IP.
2327 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), Tmp);
2328 MIB.addReg(BufReg);
2329 MIB.addImm(0);
2330 MIB.addImm(8);
2331 MIB.setMemRefs(MMOs);
2332
2333 // Copy BufReg to SX10 for later use in setjmp.
2334 // FIXME: Better to not use SX10 here
2335 BuildMI(*ThisMBB, MI, DL, TII->get(VE::ORri), VE::SX10)
2336 .addReg(BufReg)
2337 .addImm(0);
2338
2339 // Reload SP.
2340 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), SP);
2341 MIB.add(MI.getOperand(0)); // we can preserve the kill flags here.
2342 MIB.addImm(0);
2343 MIB.addImm(16);
2344 MIB.setMemRefs(MMOs);
2345
2346 // Jump.
2347 BuildMI(*ThisMBB, MI, DL, TII->get(VE::BCFLari_t))
2348 .addReg(Tmp, getKillRegState(true))
2349 .addImm(0);
2350
2351 MI.eraseFromParent();
2352 return ThisMBB;
2353}
2354
2357 MachineBasicBlock *BB) const {
2358 DebugLoc DL = MI.getDebugLoc();
2359 MachineFunction *MF = BB->getParent();
2360 MachineFrameInfo &MFI = MF->getFrameInfo();
2362 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2363 int FI = MFI.getFunctionContextIndex();
2364
2365 // Get a mapping of the call site numbers to all of the landing pads they're
2366 // associated with.
2368 unsigned MaxCSNum = 0;
2369 for (auto &MBB : *MF) {
2370 if (!MBB.isEHPad())
2371 continue;
2372
2373 MCSymbol *Sym = nullptr;
2374 for (const auto &MI : MBB) {
2375 if (MI.isDebugInstr())
2376 continue;
2377
2378 assert(MI.isEHLabel() && "expected EH_LABEL");
2379 Sym = MI.getOperand(0).getMCSymbol();
2380 break;
2381 }
2382
2383 if (!MF->hasCallSiteLandingPad(Sym))
2384 continue;
2385
2386 for (unsigned CSI : MF->getCallSiteLandingPad(Sym)) {
2387 CallSiteNumToLPad[CSI].push_back(&MBB);
2388 MaxCSNum = std::max(MaxCSNum, CSI);
2389 }
2390 }
2391
2392 // Get an ordered list of the machine basic blocks for the jump table.
2393 std::vector<MachineBasicBlock *> LPadList;
2395 LPadList.reserve(CallSiteNumToLPad.size());
2396
2397 for (unsigned CSI = 1; CSI <= MaxCSNum; ++CSI) {
2398 for (auto &LP : CallSiteNumToLPad[CSI]) {
2399 LPadList.push_back(LP);
2400 InvokeBBs.insert_range(LP->predecessors());
2401 }
2402 }
2403
2404 assert(!LPadList.empty() &&
2405 "No landing pad destinations for the dispatch jump table!");
2406
2407 // The %fn_context is allocated like below (from --print-after=sjljehprepare):
2408 // %fn_context = alloca { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }
2409 //
2410 // This `[5 x i8*]` is jmpbuf, so jmpbuf[1] is FI+72.
2411 // First `i64` is callsite, so callsite is FI+8.
2412 static const int OffsetIC = 72;
2413 static const int OffsetCS = 8;
2414
2415 // Create the MBBs for the dispatch code like following:
2416 //
2417 // ThisMBB:
2418 // Prepare DispatchBB address and store it to buf[1].
2419 // ...
2420 //
2421 // DispatchBB:
2422 // %s15 = GETGOT iff isPositionIndependent
2423 // %callsite = load callsite
2424 // brgt.l.t #size of callsites, %callsite, DispContBB
2425 //
2426 // TrapBB:
2427 // Call abort.
2428 //
2429 // DispContBB:
2430 // %breg = address of jump table
2431 // %pc = load and calculate next pc from %breg and %callsite
2432 // jmp %pc
2433
2434 // Shove the dispatch's address into the return slot in the function context.
2435 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
2436 DispatchBB->setIsEHPad(true);
2437
2438 // Trap BB will causes trap like `assert(0)`.
2440 DispatchBB->addSuccessor(TrapBB);
2441
2442 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
2443 DispatchBB->addSuccessor(DispContBB);
2444
2445 // Insert MBBs.
2446 MF->push_back(DispatchBB);
2447 MF->push_back(DispContBB);
2448 MF->push_back(TrapBB);
2449
2450 // Insert code to call abort in the TrapBB.
2451 Register Abort = prepareSymbol(*TrapBB, TrapBB->end(), "abort", DL,
2452 /* Local */ false, /* Call */ true);
2453 BuildMI(TrapBB, DL, TII->get(VE::BSICrii), VE::SX10)
2454 .addReg(Abort, getKillRegState(true))
2455 .addImm(0)
2456 .addImm(0);
2457
2458 // Insert code into the entry block that creates and registers the function
2459 // context.
2460 setupEntryBlockForSjLj(MI, BB, DispatchBB, FI, OffsetIC);
2461
2462 // Create the jump table and associated information
2463 unsigned JTE = getJumpTableEncoding();
2465 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
2466
2467 const VERegisterInfo &RI = TII->getRegisterInfo();
2468 // Add a register mask with no preserved registers. This results in all
2469 // registers being marked as clobbered.
2470 BuildMI(DispatchBB, DL, TII->get(VE::NOP))
2472
2473 if (isPositionIndependent()) {
2474 // Force to generate GETGOT, since current implementation doesn't store GOT
2475 // register.
2476 BuildMI(DispatchBB, DL, TII->get(VE::GETGOT), VE::SX15);
2477 }
2478
2479 // IReg is used as an index in a memory operand and therefore can't be SP
2480 const TargetRegisterClass *RC = &VE::I64RegClass;
2481 Register IReg = MRI.createVirtualRegister(RC);
2482 addFrameReference(BuildMI(DispatchBB, DL, TII->get(VE::LDLZXrii), IReg), FI,
2483 OffsetCS);
2484 if (LPadList.size() < 64) {
2485 BuildMI(DispatchBB, DL, TII->get(VE::BRCFLir_t))
2487 .addImm(LPadList.size())
2488 .addReg(IReg)
2489 .addMBB(TrapBB);
2490 } else {
2491 assert(LPadList.size() <= 0x7FFFFFFF && "Too large Landing Pad!");
2492 Register TmpReg = MRI.createVirtualRegister(RC);
2493 BuildMI(DispatchBB, DL, TII->get(VE::LEAzii), TmpReg)
2494 .addImm(0)
2495 .addImm(0)
2496 .addImm(LPadList.size());
2497 BuildMI(DispatchBB, DL, TII->get(VE::BRCFLrr_t))
2499 .addReg(TmpReg, getKillRegState(true))
2500 .addReg(IReg)
2501 .addMBB(TrapBB);
2502 }
2503
2504 Register BReg = MRI.createVirtualRegister(RC);
2505 Register Tmp1 = MRI.createVirtualRegister(RC);
2506 Register Tmp2 = MRI.createVirtualRegister(RC);
2507
2508 if (isPositionIndependent()) {
2509 // Create following instructions for local linkage PIC code.
2510 // lea %Tmp1, .LJTI0_0@gotoff_lo
2511 // and %Tmp2, %Tmp1, (32)0
2512 // lea.sl %BReg, .LJTI0_0@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2513 BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
2514 .addImm(0)
2515 .addImm(0)
2517 BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
2518 .addReg(Tmp1, getKillRegState(true))
2519 .addImm(M0(32));
2520 BuildMI(DispContBB, DL, TII->get(VE::LEASLrri), BReg)
2521 .addReg(VE::SX15)
2522 .addReg(Tmp2, getKillRegState(true))
2524 } else {
2525 // Create following instructions for non-PIC code.
2526 // lea %Tmp1, .LJTI0_0@lo
2527 // and %Tmp2, %Tmp1, (32)0
2528 // lea.sl %BReg, .LJTI0_0@hi(%Tmp2)
2529 BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
2530 .addImm(0)
2531 .addImm(0)
2533 BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
2534 .addReg(Tmp1, getKillRegState(true))
2535 .addImm(M0(32));
2536 BuildMI(DispContBB, DL, TII->get(VE::LEASLrii), BReg)
2537 .addReg(Tmp2, getKillRegState(true))
2538 .addImm(0)
2540 }
2541
2542 switch (JTE) {
2544 // Generate simple block address code for no-PIC model.
2545 // sll %Tmp1, %IReg, 3
2546 // lds %TReg, 0(%Tmp1, %BReg)
2547 // bcfla %TReg
2548
2549 Register TReg = MRI.createVirtualRegister(RC);
2550 Register Tmp1 = MRI.createVirtualRegister(RC);
2551
2552 BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
2553 .addReg(IReg, getKillRegState(true))
2554 .addImm(3);
2555 BuildMI(DispContBB, DL, TII->get(VE::LDrri), TReg)
2556 .addReg(BReg, getKillRegState(true))
2557 .addReg(Tmp1, getKillRegState(true))
2558 .addImm(0);
2559 BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
2560 .addReg(TReg, getKillRegState(true))
2561 .addImm(0);
2562 break;
2563 }
2565 // Generate block address code using differences from the function pointer
2566 // for PIC model.
2567 // sll %Tmp1, %IReg, 2
2568 // ldl.zx %OReg, 0(%Tmp1, %BReg)
2569 // Prepare function address in BReg2.
2570 // adds.l %TReg, %BReg2, %OReg
2571 // bcfla %TReg
2572
2574 Register OReg = MRI.createVirtualRegister(RC);
2575 Register TReg = MRI.createVirtualRegister(RC);
2576 Register Tmp1 = MRI.createVirtualRegister(RC);
2577
2578 BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
2579 .addReg(IReg, getKillRegState(true))
2580 .addImm(2);
2581 BuildMI(DispContBB, DL, TII->get(VE::LDLZXrri), OReg)
2582 .addReg(BReg, getKillRegState(true))
2583 .addReg(Tmp1, getKillRegState(true))
2584 .addImm(0);
2585 Register BReg2 =
2586 prepareSymbol(*DispContBB, DispContBB->end(),
2587 DispContBB->getParent()->getName(), DL, /* Local */ true);
2588 BuildMI(DispContBB, DL, TII->get(VE::ADDSLrr), TReg)
2589 .addReg(OReg, getKillRegState(true))
2590 .addReg(BReg2, getKillRegState(true));
2591 BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
2592 .addReg(TReg, getKillRegState(true))
2593 .addImm(0);
2594 break;
2595 }
2596 default:
2597 llvm_unreachable("Unexpected jump table encoding");
2598 }
2599
2600 // Add the jump table entries as successors to the MBB.
2602 for (auto &LP : LPadList)
2603 if (SeenMBBs.insert(LP).second)
2604 DispContBB->addSuccessor(LP);
2605
2606 // N.B. the order the invoke BBs are processed in doesn't matter here.
2608 const MCPhysReg *SavedRegs = MF->getRegInfo().getCalleeSavedRegs();
2609 for (MachineBasicBlock *MBB : InvokeBBs) {
2610 // Remove the landing pad successor from the invoke block and replace it
2611 // with the new dispatch block.
2612 // Keep a copy of Successors since it's modified inside the loop.
2613 SmallVector<MachineBasicBlock *, 8> Successors(MBB->succ_rbegin(),
2614 MBB->succ_rend());
2615 // FIXME: Avoid quadratic complexity.
2616 for (auto *MBBS : Successors) {
2617 if (MBBS->isEHPad()) {
2618 MBB->removeSuccessor(MBBS);
2619 MBBLPads.push_back(MBBS);
2620 }
2621 }
2622
2623 MBB->addSuccessor(DispatchBB);
2624
2625 // Find the invoke call and mark all of the callee-saved registers as
2626 // 'implicit defined' so that they're spilled. This prevents code from
2627 // moving instructions to before the EH block, where they will never be
2628 // executed.
2629 for (auto &II : reverse(*MBB)) {
2630 if (!II.isCall())
2631 continue;
2632
2633 DenseSet<Register> DefRegs;
2634 for (auto &MOp : II.operands())
2635 if (MOp.isReg())
2636 DefRegs.insert(MOp.getReg());
2637
2638 MachineInstrBuilder MIB(*MF, &II);
2639 for (unsigned RI = 0; SavedRegs[RI]; ++RI) {
2640 Register Reg = SavedRegs[RI];
2641 if (!DefRegs.contains(Reg))
2643 }
2644
2645 break;
2646 }
2647 }
2648
2649 // Mark all former landing pads as non-landing pads. The dispatch is the only
2650 // landing pad now.
2651 for (auto &LP : MBBLPads)
2652 LP->setIsEHPad(false);
2653
2654 // The instruction is gone now.
2655 MI.eraseFromParent();
2656 return BB;
2657}
2658
2661 MachineBasicBlock *BB) const {
2662 switch (MI.getOpcode()) {
2663 default:
2664 llvm_unreachable("Unknown Custom Instruction!");
2665 case VE::EH_SjLj_LongJmp:
2666 return emitEHSjLjLongJmp(MI, BB);
2667 case VE::EH_SjLj_SetJmp:
2668 return emitEHSjLjSetJmp(MI, BB);
2669 case VE::EH_SjLj_Setup_Dispatch:
2670 return emitSjLjDispatchBlock(MI, BB);
2671 }
2672}
2673
2674static bool isSimm7(SDValue V) {
2675 EVT VT = V.getValueType();
2676 if (VT.isVector())
2677 return false;
2678
2679 if (VT.isInteger()) {
2681 return isInt<7>(C->getSExtValue());
2682 } else if (VT.isFloatingPoint()) {
2684 if (VT == MVT::f32 || VT == MVT::f64) {
2685 const APInt &Imm = C->getValueAPF().bitcastToAPInt();
2686 uint64_t Val = Imm.getSExtValue();
2687 if (Imm.getBitWidth() == 32)
2688 Val <<= 32; // Immediate value of float place at higher bits on VE.
2689 return isInt<7>(Val);
2690 }
2691 }
2692 }
2693 return false;
2694}
2695
2696static bool isMImm(SDValue V) {
2697 EVT VT = V.getValueType();
2698 if (VT.isVector())
2699 return false;
2700
2701 if (VT.isInteger()) {
2703 return isMImmVal(getImmVal(C));
2704 } else if (VT.isFloatingPoint()) {
2706 if (VT == MVT::f32) {
2707 // Float value places at higher bits, so ignore lower 32 bits.
2708 return isMImm32Val(getFpImmVal(C) >> 32);
2709 } else if (VT == MVT::f64) {
2710 return isMImmVal(getFpImmVal(C));
2711 }
2712 }
2713 }
2714 return false;
2715}
2716
2717static unsigned decideComp(EVT SrcVT, ISD::CondCode CC) {
2718 if (SrcVT.isFloatingPoint()) {
2719 if (SrcVT == MVT::f128)
2720 return VEISD::CMPQ;
2721 return VEISD::CMPF;
2722 }
2723 return isSignedIntSetCC(CC) ? VEISD::CMPI : VEISD::CMPU;
2724}
2725
2726static EVT decideCompType(EVT SrcVT) {
2727 if (SrcVT == MVT::f128)
2728 return MVT::f64;
2729 return SrcVT;
2730}
2731
2733 bool WithCMov) {
2734 if (SrcVT.isFloatingPoint()) {
2735 // For the case of floating point setcc, only unordered comparison
2736 // or general comparison with -enable-no-nans-fp-math option reach
2737 // here, so it is safe even if values are NaN. Only f128 doesn't
2738 // safe since VE uses f64 result of f128 comparison.
2739 return SrcVT != MVT::f128;
2740 }
2741 if (isIntEqualitySetCC(CC)) {
2742 // For the case of equal or not equal, it is safe without comparison with 0.
2743 return true;
2744 }
2745 if (WithCMov) {
2746 // For the case of integer setcc with cmov, all signed comparison with 0
2747 // are safe.
2748 return isSignedIntSetCC(CC);
2749 }
2750 // For the case of integer setcc, only signed 64 bits comparison is safe.
2751 // For unsigned, "CMPU 0x80000000, 0" has to be greater than 0, but it becomes
2752 // less than 0 witout CMPU. For 32 bits, other half of 32 bits are
2753 // uncoditional, so it is not safe too without CMPI..
2754 return isSignedIntSetCC(CC) && SrcVT == MVT::i64;
2755}
2756
2758 ISD::CondCode CC, bool WithCMov,
2759 const SDLoc &DL, SelectionDAG &DAG) {
2760 // Compare values. If RHS is 0 and it is safe to calculate without
2761 // comparison, we don't generate an instruction for comparison.
2762 EVT CompVT = decideCompType(VT);
2763 if (CompVT == VT && safeWithoutCompWithNull(VT, CC, WithCMov) &&
2765 return LHS;
2766 }
2767 return DAG.getNode(decideComp(VT, CC), DL, CompVT, LHS, RHS);
2768}
2769
2771 DAGCombinerInfo &DCI) const {
2772 assert(N->getOpcode() == ISD::SELECT &&
2773 "Should be called with a SELECT node");
2775 SDValue Cond = N->getOperand(0);
2776 SDValue True = N->getOperand(1);
2777 SDValue False = N->getOperand(2);
2778
2779 // We handle only scalar SELECT.
2780 EVT VT = N->getValueType(0);
2781 if (VT.isVector())
2782 return SDValue();
2783
2784 // Peform combineSelect after leagalize DAG.
2785 if (!DCI.isAfterLegalizeDAG())
2786 return SDValue();
2787
2788 EVT VT0 = Cond.getValueType();
2789 if (isMImm(True)) {
2790 // VE's condition move can handle MImm in True clause, so nothing to do.
2791 } else if (isMImm(False)) {
2792 // VE's condition move can handle MImm in True clause, so swap True and
2793 // False clauses if False has MImm value. And, update condition code.
2794 std::swap(True, False);
2795 CC = getSetCCInverse(CC, VT0);
2796 }
2797
2798 SDLoc DL(N);
2799 SelectionDAG &DAG = DCI.DAG;
2800 VECC::CondCode VECCVal;
2801 if (VT0.isFloatingPoint()) {
2802 VECCVal = fpCondCode2Fcc(CC);
2803 } else {
2804 VECCVal = intCondCode2Icc(CC);
2805 }
2806 SDValue Ops[] = {Cond, True, False,
2807 DAG.getConstant(VECCVal, DL, MVT::i32)};
2808 return DAG.getNode(VEISD::CMOV, DL, VT, Ops);
2809}
2810
2812 DAGCombinerInfo &DCI) const {
2813 assert(N->getOpcode() == ISD::SELECT_CC &&
2814 "Should be called with a SELECT_CC node");
2815 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
2816 SDValue LHS = N->getOperand(0);
2817 SDValue RHS = N->getOperand(1);
2818 SDValue True = N->getOperand(2);
2819 SDValue False = N->getOperand(3);
2820
2821 // We handle only scalar SELECT_CC.
2822 EVT VT = N->getValueType(0);
2823 if (VT.isVector())
2824 return SDValue();
2825
2826 // Peform combineSelectCC after leagalize DAG.
2827 if (!DCI.isAfterLegalizeDAG())
2828 return SDValue();
2829
2830 // We handle only i32/i64/f32/f64/f128 comparisons.
2831 EVT LHSVT = LHS.getValueType();
2832 assert(LHSVT == RHS.getValueType());
2833 switch (LHSVT.getSimpleVT().SimpleTy) {
2834 case MVT::i32:
2835 case MVT::i64:
2836 case MVT::f32:
2837 case MVT::f64:
2838 case MVT::f128:
2839 break;
2840 default:
2841 // Return SDValue to let llvm handle other types.
2842 return SDValue();
2843 }
2844
2845 if (isMImm(RHS)) {
2846 // VE's comparison can handle MImm in RHS, so nothing to do.
2847 } else if (isSimm7(RHS)) {
2848 // VE's comparison can handle Simm7 in LHS, so swap LHS and RHS, and
2849 // update condition code.
2850 std::swap(LHS, RHS);
2851 CC = getSetCCSwappedOperands(CC);
2852 }
2853 if (isMImm(True)) {
2854 // VE's condition move can handle MImm in True clause, so nothing to do.
2855 } else if (isMImm(False)) {
2856 // VE's condition move can handle MImm in True clause, so swap True and
2857 // False clauses if False has MImm value. And, update condition code.
2858 std::swap(True, False);
2859 CC = getSetCCInverse(CC, LHSVT);
2860 }
2861
2862 SDLoc DL(N);
2863 SelectionDAG &DAG = DCI.DAG;
2864
2865 bool WithCMov = true;
2866 SDValue CompNode = generateComparison(LHSVT, LHS, RHS, CC, WithCMov, DL, DAG);
2867
2868 VECC::CondCode VECCVal;
2869 if (LHSVT.isFloatingPoint()) {
2870 VECCVal = fpCondCode2Fcc(CC);
2871 } else {
2872 VECCVal = intCondCode2Icc(CC);
2873 }
2874 SDValue Ops[] = {CompNode, True, False,
2875 DAG.getConstant(VECCVal, DL, MVT::i32)};
2876 return DAG.getNode(VEISD::CMOV, DL, VT, Ops);
2877}
2878
2879static bool isI32InsnAllUses(const SDNode *User, const SDNode *N);
2880static bool isI32Insn(const SDNode *User, const SDNode *N) {
2881 switch (User->getOpcode()) {
2882 default:
2883 return false;
2884 case ISD::ADD:
2885 case ISD::SUB:
2886 case ISD::MUL:
2887 case ISD::SDIV:
2888 case ISD::UDIV:
2889 case ISD::SETCC:
2890 case ISD::SMIN:
2891 case ISD::SMAX:
2892 case ISD::SHL:
2893 case ISD::SRA:
2894 case ISD::BSWAP:
2895 case ISD::SINT_TO_FP:
2896 case ISD::UINT_TO_FP:
2897 case ISD::BR_CC:
2898 case ISD::BITCAST:
2899 case ISD::ATOMIC_CMP_SWAP:
2900 case ISD::ATOMIC_SWAP:
2901 case VEISD::CMPU:
2902 case VEISD::CMPI:
2903 return true;
2904 case ISD::SRL:
2905 if (N->getOperand(0).getOpcode() != ISD::SRL)
2906 return true;
2907 // (srl (trunc (srl ...))) may be optimized by combining srl, so
2908 // doesn't optimize trunc now.
2909 return false;
2910 case ISD::SELECT_CC:
2911 if (User->getOperand(2).getNode() != N &&
2912 User->getOperand(3).getNode() != N)
2913 return true;
2914 return isI32InsnAllUses(User, N);
2915 case VEISD::CMOV:
2916 // CMOV in (cmov (trunc ...), true, false, int-comparison) is safe.
2917 // However, trunc in true or false clauses is not safe.
2918 if (User->getOperand(1).getNode() != N &&
2919 User->getOperand(2).getNode() != N &&
2921 VECC::CondCode VECCVal =
2922 static_cast<VECC::CondCode>(User->getConstantOperandVal(3));
2923 return isIntVECondCode(VECCVal);
2924 }
2925 [[fallthrough]];
2926 case ISD::AND:
2927 case ISD::OR:
2928 case ISD::XOR:
2929 case ISD::SELECT:
2930 case ISD::CopyToReg:
2931 // Check all use of selections, bit operations, and copies. If all of them
2932 // are safe, optimize truncate to extract_subreg.
2933 return isI32InsnAllUses(User, N);
2934 }
2935}
2936
2937static bool isI32InsnAllUses(const SDNode *User, const SDNode *N) {
2938 // Check all use of User node. If all of them are safe, optimize
2939 // truncate to extract_subreg.
2940 for (const SDNode *U : User->users()) {
2941 switch (U->getOpcode()) {
2942 default:
2943 // If the use is an instruction which treats the source operand as i32,
2944 // it is safe to avoid truncate here.
2945 if (isI32Insn(U, N))
2946 continue;
2947 break;
2948 case ISD::ANY_EXTEND:
2949 case ISD::SIGN_EXTEND:
2950 case ISD::ZERO_EXTEND: {
2951 // Special optimizations to the combination of ext and trunc.
2952 // (ext ... (select ... (trunc ...))) is safe to avoid truncate here
2953 // since this truncate instruction clears higher 32 bits which is filled
2954 // by one of ext instructions later.
2955 assert(N->getValueType(0) == MVT::i32 &&
2956 "find truncate to not i32 integer");
2957 if (User->getOpcode() == ISD::SELECT_CC ||
2958 User->getOpcode() == ISD::SELECT || User->getOpcode() == VEISD::CMOV)
2959 continue;
2960 break;
2961 }
2962 }
2963 return false;
2964 }
2965 return true;
2966}
2967
2968// Optimize TRUNCATE in DAG combining. Optimizing it in CUSTOM lower is
2969// sometime too early. Optimizing it in DAG pattern matching in VEInstrInfo.td
2970// is sometime too late. So, doing it at here.
2972 DAGCombinerInfo &DCI) const {
2973 assert(N->getOpcode() == ISD::TRUNCATE &&
2974 "Should be called with a TRUNCATE node");
2975
2976 SelectionDAG &DAG = DCI.DAG;
2977 SDLoc DL(N);
2978 EVT VT = N->getValueType(0);
2979
2980 // We prefer to do this when all types are legal.
2981 if (!DCI.isAfterLegalizeDAG())
2982 return SDValue();
2983
2984 // Skip combine TRUNCATE atm if the operand of TRUNCATE might be a constant.
2985 if (N->getOperand(0)->getOpcode() == ISD::SELECT_CC &&
2986 isa<ConstantSDNode>(N->getOperand(0)->getOperand(0)) &&
2987 isa<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
2988 return SDValue();
2989
2990 // Check all use of this TRUNCATE.
2991 for (const SDNode *User : N->users()) {
2992 // Make sure that we're not going to replace TRUNCATE for non i32
2993 // instructions.
2994 //
2995 // FIXME: Although we could sometimes handle this, and it does occur in
2996 // practice that one of the condition inputs to the select is also one of
2997 // the outputs, we currently can't deal with this.
2998 if (isI32Insn(User, N))
2999 continue;
3000
3001 return SDValue();
3002 }
3003
3004 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32);
3005 return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT,
3006 N->getOperand(0), SubI32),
3007 0);
3008}
3009
3011 DAGCombinerInfo &DCI) const {
3012 switch (N->getOpcode()) {
3013 default:
3014 break;
3015 case ISD::SELECT:
3016 return combineSelect(N, DCI);
3017 case ISD::SELECT_CC:
3018 return combineSelectCC(N, DCI);
3019 case ISD::TRUNCATE:
3020 return combineTRUNCATE(N, DCI);
3021 }
3022
3023 return SDValue();
3024}
3025
3026//===----------------------------------------------------------------------===//
3027// VE Inline Assembly Support
3028//===----------------------------------------------------------------------===//
3029
3032 if (Constraint.size() == 1) {
3033 switch (Constraint[0]) {
3034 default:
3035 break;
3036 case 'v': // vector registers
3037 return C_RegisterClass;
3038 }
3039 }
3040 return TargetLowering::getConstraintType(Constraint);
3041}
3042
3043std::pair<unsigned, const TargetRegisterClass *>
3045 StringRef Constraint,
3046 MVT VT) const {
3047 const TargetRegisterClass *RC = nullptr;
3048 if (Constraint.size() == 1) {
3049 switch (Constraint[0]) {
3050 default:
3051 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3052 case 'r':
3053 RC = &VE::I64RegClass;
3054 break;
3055 case 'v':
3056 RC = &VE::V64RegClass;
3057 break;
3058 }
3059 return std::make_pair(0U, RC);
3060 }
3061
3062 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3063}
3064
3065//===----------------------------------------------------------------------===//
3066// VE Target Optimization Support
3067//===----------------------------------------------------------------------===//
3068
3070 // Specify 8 for PIC model to relieve the impact of PIC load instructions.
3071 if (isJumpTableRelative())
3072 return 8;
3073
3075}
3076
3078 EVT VT = Y.getValueType();
3079
3080 // VE doesn't have vector and not instruction.
3081 if (VT.isVector())
3082 return false;
3083
3084 // VE allows different immediate values for X and Y where ~X & Y.
3085 // Only simm7 works for X, and only mimm works for Y on VE. However, this
3086 // function is used to check whether an immediate value is OK for and-not
3087 // instruction as both X and Y. Generating additional instruction to
3088 // retrieve an immediate value is no good since the purpose of this
3089 // function is to convert a series of 3 instructions to another series of
3090 // 3 instructions with better parallelism. Therefore, we return false
3091 // for all immediate values now.
3092 // FIXME: Change hasAndNot function to have two operands to make it work
3093 // correctly with Aurora VE.
3095 return false;
3096
3097 // It's ok for generic registers.
3098 return true;
3099}
3100
3102 SelectionDAG &DAG) const {
3103 assert(Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Unknown opcode!");
3104 MVT VT = Op.getOperand(0).getSimpleValueType();
3105
3106 // Special treatment for packed V64 types.
3107 assert(VT == MVT::v512i32 || VT == MVT::v512f32);
3108 (void)VT;
3109 // Example of codes:
3110 // %packed_v = extractelt %vr, %idx / 2
3111 // %v = %packed_v >> (%idx % 2 * 32)
3112 // %res = %v & 0xffffffff
3113
3114 SDValue Vec = Op.getOperand(0);
3115 SDValue Idx = Op.getOperand(1);
3116 SDLoc DL(Op);
3117 SDValue Result = Op;
3118 if (false /* Idx->isConstant() */) {
3119 // TODO: optimized implementation using constant values
3120 } else {
3121 SDValue Const1 = DAG.getConstant(1, DL, MVT::i64);
3122 SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1});
3123 SDValue PackedElt =
3124 SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0);
3125 SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1});
3126 SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1});
3127 SDValue Const5 = DAG.getConstant(5, DL, MVT::i64);
3128 Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5});
3129 PackedElt = DAG.getNode(ISD::SRL, DL, MVT::i64, {PackedElt, Shift});
3130 SDValue Mask = DAG.getConstant(0xFFFFFFFFL, DL, MVT::i64);
3131 PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask});
3132 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32);
3133 Result = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
3134 MVT::i32, PackedElt, SubI32),
3135 0);
3136
3137 if (Op.getSimpleValueType() == MVT::f32) {
3138 Result = DAG.getBitcast(MVT::f32, Result);
3139 } else {
3140 assert(Op.getSimpleValueType() == MVT::i32);
3141 }
3142 }
3143 return Result;
3144}
3145
3147 SelectionDAG &DAG) const {
3148 assert(Op.getOpcode() == ISD::INSERT_VECTOR_ELT && "Unknown opcode!");
3149 MVT VT = Op.getOperand(0).getSimpleValueType();
3150
3151 // Special treatment for packed V64 types.
3152 assert(VT == MVT::v512i32 || VT == MVT::v512f32);
3153 (void)VT;
3154 // The v512i32 and v512f32 starts from upper bits (0..31). This "upper
3155 // bits" required `val << 32` from C implementation's point of view.
3156 //
3157 // Example of codes:
3158 // %packed_elt = extractelt %vr, (%idx >> 1)
3159 // %shift = ((%idx & 1) ^ 1) << 5
3160 // %packed_elt &= 0xffffffff00000000 >> shift
3161 // %packed_elt |= (zext %val) << shift
3162 // %vr = insertelt %vr, %packed_elt, (%idx >> 1)
3163
3164 SDLoc DL(Op);
3165 SDValue Vec = Op.getOperand(0);
3166 SDValue Val = Op.getOperand(1);
3167 SDValue Idx = Op.getOperand(2);
3168 if (Idx.getSimpleValueType() == MVT::i32)
3169 Idx = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Idx);
3170 if (Val.getSimpleValueType() == MVT::f32)
3171 Val = DAG.getBitcast(MVT::i32, Val);
3172 assert(Val.getSimpleValueType() == MVT::i32);
3173 Val = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Val);
3174
3175 SDValue Result = Op;
3176 if (false /* Idx->isConstant()*/) {
3177 // TODO: optimized implementation using constant values
3178 } else {
3179 SDValue Const1 = DAG.getConstant(1, DL, MVT::i64);
3180 SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1});
3181 SDValue PackedElt =
3182 SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0);
3183 SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1});
3184 SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1});
3185 SDValue Const5 = DAG.getConstant(5, DL, MVT::i64);
3186 Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5});
3187 SDValue Mask = DAG.getConstant(0xFFFFFFFF00000000L, DL, MVT::i64);
3188 Mask = DAG.getNode(ISD::SRL, DL, MVT::i64, {Mask, Shift});
3189 PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask});
3190 Val = DAG.getNode(ISD::SHL, DL, MVT::i64, {Val, Shift});
3191 PackedElt = DAG.getNode(ISD::OR, DL, MVT::i64, {PackedElt, Val});
3192 Result =
3193 SDValue(DAG.getMachineNode(VE::LSVrr_v, DL, Vec.getSimpleValueType(),
3194 {HalfIdx, PackedElt, Vec}),
3195 0);
3196 }
3197 return Result;
3198}
unsigned const MachineRegisterInfo * MRI
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
#define I(x, y, z)
Definition MD5.cpp:58
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
const SmallVectorImpl< MachineOperand > & Cond
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:114
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static unsigned decideComp(EVT SrcVT, ISD::CondCode CC)
static bool isSimm7(SDValue V)
CCAssignFn * getParamCC(CallingConv::ID CallConv, bool IsVarArg)
static SDValue lowerLoadF128(SDValue Op, SelectionDAG &DAG)
static bool isMImm(SDValue V)
static SDValue prepareTS1AM(SDValue Op, SelectionDAG &DAG, SDValue &Flag, SDValue &Bits)
CCAssignFn * getReturnCC(CallingConv::ID CallConv)
static bool safeWithoutCompWithNull(EVT SrcVT, ISD::CondCode CC, bool WithCMov)
static bool isI32InsnAllUses(const SDNode *User, const SDNode *N)
static SDValue lowerLoadI1(SDValue Op, SelectionDAG &DAG)
static SDValue generateComparison(EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode CC, bool WithCMov, const SDLoc &DL, SelectionDAG &DAG)
static EVT decideCompType(EVT SrcVT)
static bool isI32Insn(const SDNode *User, const SDNode *N)
static SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const VETargetLowering &TLI, const VESubtarget *Subtarget)
static const MVT AllMaskVTs[]
static bool getUniqueInsertion(SDNode *N, unsigned &UniqueIdx)
static SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG, const VETargetLowering &TLI, const VESubtarget *Subtarget)
static const MVT AllVectorVTs[]
static const MVT AllPackedVTs[]
static SDValue finalizeTS1AM(SDValue Op, SelectionDAG &DAG, SDValue Data, SDValue Bits)
static SDValue lowerStoreF128(SDValue Op, SelectionDAG &DAG)
static SDValue lowerStoreI1(SDValue Op, SelectionDAG &DAG)
#define TARGET_NODE_CASE(NAME)
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
This is an SDNode representing atomic operations.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
bool isExtInLoc() const
int64_t getLocMemOffset() const
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
A debug info location.
Definition DebugLoc.h:124
unsigned size() const
Definition DenseMap.h:110
Implements a dense probed hash-table based set.
Definition DenseSet.h:279
unsigned getAddressSpace() const
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
LLVM_ABI bool hasAtomicStore() const LLVM_READONLY
Return true if this atomic instruction stores to memory.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:428
Context object for machine code objects.
Definition MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
Machine Value Type.
SimpleValueType SimpleTy
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
static auto integer_valuetypes()
static auto vector_valuetypes()
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
int getFunctionContextIndex() const
Return the index for the function context object.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
MachineJumpTableInfo * getOrCreateJumpTableInfo(unsigned JTEntryKind)
getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it does already exist,...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool hasCallSiteLandingPad(MCSymbol *Sym)
Return true if the landing pad Eh symbol has an associated call site.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
SmallVectorImpl< unsigned > & getCallSiteLandingPad(MCSymbol *Sym)
Get the call site indexes for a landing pad EH symbol.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
LLVM_ABI unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
Align getAlign() const
bool isVolatile() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class representing virtual and physical registers.
Definition Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, bool isTargetGA=false, unsigned TargetFlags=0)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
const TargetMachine & getTarget() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:146
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Information about stack frame layout on the target.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual unsigned getMinimumJumpTableEntries() const
Return lower limit for number of blocks in a jump table.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
std::vector< ArgListEntry > ArgListTy
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:281
Value * getOperand(unsigned i) const
Definition User.h:232
SDValue getBroadcast(EVT ResultVT, SDValue Scalar, SDValue AVL) const
SDValue getNode(unsigned OC, SDVTList VTL, ArrayRef< SDValue > OpV, std::optional< SDNodeFlags > Flags=std::nullopt) const
getNode {
SDValue getUNDEF(EVT VT) const
SDValue getConstant(uint64_t Val, EVT VT, bool IsTarget=false, bool IsOpaque=false) const
bool hasBP(const MachineFunction &MF) const
const VERegisterInfo * getRegisterInfo() const override
Definition VESubtarget.h:55
SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const
} Custom Inserter
SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const
SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
VETargetLowering(const TargetMachine &TM, const VESubtarget &STI)
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Custom Lower {.
SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
} VVPLowering
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const
unsigned getMinimumJumpTableEntries() const override
} Inline Assembly
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &dl, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MachineBasicBlock * emitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *BB) const
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TargetBB, const DebugLoc &DL) const
void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, MachineBasicBlock *DispatchBB, int FI, int Offset) const
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
Custom Inserter {.
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Returns true if the target allows unaligned memory accesses of the specified type.
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
TargetLoweringBase::LegalizeAction getCustomOperationAction(SDNode &) const override
Custom Lower {.
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const
SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const
Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, StringRef Symbol, const DebugLoc &DL, bool IsLocal, bool IsCall) const
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
} Custom Lower
SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const
} Custom DAGCombine
SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const
const MCExpr * LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned Uid, MCContext &Ctx) const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &ArgsFlags, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const
unsigned getJumpTableEncoding() const override
JumpTable for VE.
SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, SelectionDAG &DAG) const
ConstraintType getConstraintType(StringRef Constraint) const override
Inline Assembly {.
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const
std::list< std::string > * getStrList() const
LLVM Value Representation.
Definition Value.h:75
iterator_range< user_iterator > users()
Definition Value.h:426
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:175
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:801
@ CTLZ_ZERO_UNDEF
Definition ISDOpcodes.h:774
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
Definition ISDOpcodes.h:163
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:270
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:765
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:259
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:835
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:511
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
Definition ISDOpcodes.h:167
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:862
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:275
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:826
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:778
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition ISDOpcodes.h:225
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:695
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:756
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:563
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:219
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:832
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:793
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:718
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:730
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:200
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:552
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
Definition ISDOpcodes.h:157
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:838
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:815
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:521
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:543
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
@ Dead
Unused definition.
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:58
CondCode
Definition VE.h:43
@ CC_ILE
Definition VE.h:50
@ S_GOTOFF_LO32
Definition VEMCAsmInfo.h:47
@ S_GOTOFF_HI32
Definition VEMCAsmInfo.h:46
This is an optimization pass for GlobalISel generic memory operations.
static uint64_t getFpImmVal(const ConstantFPSDNode *N)
getFpImmVal - get immediate representation of floating point value
bool isPackedVectorType(EVT SomeVT)
@ Offset
Definition DWP.cpp:477
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
static bool isIntVECondCode(VECC::CondCode CC)
Definition VE.h:151
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:644
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
static uint64_t getImmVal(const ConstantSDNode *N)
getImmVal - get immediate representation of integer value
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
bool isMaskArithmetic(SDValue Op)
static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC)
Convert a DAG floating point condition code to a VE FCC condition.
bool isMaskType(EVT SomeVT)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
AtomicOrdering
Atomic ordering for LLVM's memory model.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
bool isVVPOrVEC(unsigned Opcode)
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
bool isPackingSupportOpcode(unsigned Opc)
std::pair< SDValue, bool > getAnnotatedNodeAVL(SDValue Op)
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
Definition VE.h:376
static VECC::CondCode intCondCode2Icc(ISD::CondCode CC)
Convert a DAG integer condition code to a VE ICC condition.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:560
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
static bool isMImmVal(uint64_t Val)
Definition VE.h:332
static bool isMImm32Val(uint32_t Val)
Definition VE.h:345
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:869
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:147
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:373
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:316
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:168
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
Definition ValueTypes.h:102
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:152
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
SmallVector< ISD::OutputArg, 32 > Outs
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
const uint32_t * getNoPreservedMask() const override