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