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"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/IRBuilder.h"
35#include "llvm/IR/Module.h"
37using namespace llvm;
38
39#define DEBUG_TYPE "ve-lower"
40
41//===----------------------------------------------------------------------===//
42// Calling Convention Implementation
43//===----------------------------------------------------------------------===//
44
45#define GET_CALLING_CONV_IMPL
46#include "VEGenCallingConv.inc"
47
49 switch (CallConv) {
50 default:
51 return RetCC_VE_C;
53 return RetCC_VE_Fast;
54 }
55}
56
57CCAssignFn *getParamCC(CallingConv::ID CallConv, bool IsVarArg) {
58 if (IsVarArg)
59 return CC_VE2;
60 switch (CallConv) {
61 default:
62 return CC_VE_C;
64 return CC_VE_Fast;
65 }
66}
67
69 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
70 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
71 const Type *RetTy) const {
72 CCAssignFn *RetCC = getReturnCC(CallConv);
74 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
75 return CCInfo.CheckReturn(Outs, RetCC);
76}
77
78static const MVT AllVectorVTs[] = {MVT::v256i32, MVT::v512i32, MVT::v256i64,
79 MVT::v256f32, MVT::v512f32, MVT::v256f64};
80
81static const MVT AllMaskVTs[] = {MVT::v256i1, MVT::v512i1};
82
83static const MVT AllPackedVTs[] = {MVT::v512i32, MVT::v512f32};
84
85void VETargetLowering::initRegisterClasses() {
86 // Set up the register classes.
87 addRegisterClass(MVT::i32, &VE::I32RegClass);
88 addRegisterClass(MVT::i64, &VE::I64RegClass);
89 addRegisterClass(MVT::f32, &VE::F32RegClass);
90 addRegisterClass(MVT::f64, &VE::I64RegClass);
91 addRegisterClass(MVT::f128, &VE::F128RegClass);
92
93 if (Subtarget->enableVPU()) {
94 for (MVT VecVT : AllVectorVTs)
95 addRegisterClass(VecVT, &VE::V64RegClass);
96 addRegisterClass(MVT::v256i1, &VE::VMRegClass);
97 addRegisterClass(MVT::v512i1, &VE::VM512RegClass);
98 }
99}
100
101void VETargetLowering::initSPUActions() {
102 const auto &TM = getTargetMachine();
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::getIntegerVT(TM.getPointerSizeInBits(0));
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/// isFPImmLegal - Returns true if the target can instruction select the
860/// specified FP immediate natively. If false, the legalizer will
861/// materialize the FP immediate as a load from a constant pool.
863 bool ForCodeSize) const {
864 return VT == MVT::f32 || VT == MVT::f64;
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 // Chain the dynamic stack allocation so that it doesn't modify the stack
1608 // pointer when other instructions are using the stack.
1609 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
1610
1611 const TargetFrameLowering &TFI = *Subtarget->getFrameLowering();
1612 Align StackAlign = TFI.getStackAlign();
1613 bool NeedsAlign = Alignment.valueOrOne() > StackAlign;
1614
1615 // Prepare arguments
1617 Args.emplace_back(Size, Size.getValueType().getTypeForEVT(*DAG.getContext()));
1618 if (NeedsAlign) {
1619 SDValue Align = DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT);
1620 Args.emplace_back(Align,
1621 Align.getValueType().getTypeForEVT(*DAG.getContext()));
1622 }
1623 Type *RetTy = Type::getVoidTy(*DAG.getContext());
1624
1625 EVT PtrVT = Op.getValueType();
1626 SDValue Callee;
1627 if (NeedsAlign) {
1628 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack_align", PtrVT, 0);
1629 } else {
1630 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack", PtrVT, 0);
1631 }
1632
1634 CLI.setDebugLoc(DL)
1635 .setChain(Chain)
1636 .setCallee(CallingConv::PreserveAll, RetTy, Callee, std::move(Args))
1637 .setDiscardResult(true);
1638 std::pair<SDValue, SDValue> pair = LowerCallTo(CLI);
1639 Chain = pair.second;
1640 SDValue Result = DAG.getNode(VEISD::GETSTACKTOP, DL, VT, Chain);
1641 if (NeedsAlign) {
1642 Result = DAG.getNode(ISD::ADD, DL, VT, Result,
1643 DAG.getConstant((Alignment->value() - 1ULL), DL, VT));
1644 Result = DAG.getNode(ISD::AND, DL, VT, Result,
1645 DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT));
1646 }
1647 // Chain = Result.getValue(1);
1648 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, SDValue(), DL);
1649
1650 SDValue Ops[2] = {Result, Chain};
1651 return DAG.getMergeValues(Ops, DL);
1652}
1653
1655 SelectionDAG &DAG) const {
1656 SDLoc DL(Op);
1657 return DAG.getNode(VEISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0),
1658 Op.getOperand(1));
1659}
1660
1662 SelectionDAG &DAG) const {
1663 SDLoc DL(Op);
1664 return DAG.getNode(VEISD::EH_SJLJ_SETJMP, DL,
1665 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
1666 Op.getOperand(1));
1667}
1668
1670 SelectionDAG &DAG) const {
1671 SDLoc DL(Op);
1672 return DAG.getNode(VEISD::EH_SJLJ_SETUP_DISPATCH, DL, MVT::Other,
1673 Op.getOperand(0));
1674}
1675
1677 const VETargetLowering &TLI,
1678 const VESubtarget *Subtarget) {
1679 SDLoc DL(Op);
1681 EVT PtrVT = TLI.getPointerTy(MF.getDataLayout());
1682
1683 MachineFrameInfo &MFI = MF.getFrameInfo();
1684 MFI.setFrameAddressIsTaken(true);
1685
1686 unsigned Depth = Op.getConstantOperandVal(0);
1687 const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
1688 Register FrameReg = RegInfo->getFrameRegister(MF);
1689 SDValue FrameAddr =
1690 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, PtrVT);
1691 while (Depth--)
1692 FrameAddr = DAG.getLoad(Op.getValueType(), DL, DAG.getEntryNode(),
1693 FrameAddr, MachinePointerInfo());
1694 return FrameAddr;
1695}
1696
1698 const VETargetLowering &TLI,
1699 const VESubtarget *Subtarget) {
1701 MachineFrameInfo &MFI = MF.getFrameInfo();
1702 MFI.setReturnAddressIsTaken(true);
1703
1704 SDValue FrameAddr = lowerFRAMEADDR(Op, DAG, TLI, Subtarget);
1705
1706 SDLoc DL(Op);
1707 EVT VT = Op.getValueType();
1708 SDValue Offset = DAG.getConstant(8, DL, VT);
1709 return DAG.getLoad(VT, DL, DAG.getEntryNode(),
1710 DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset),
1712}
1713
1715 SelectionDAG &DAG) const {
1716 SDLoc DL(Op);
1717 unsigned IntNo = Op.getConstantOperandVal(0);
1718 switch (IntNo) {
1719 default: // Don't custom lower most intrinsics.
1720 return SDValue();
1721 case Intrinsic::eh_sjlj_lsda: {
1723 MVT VT = Op.getSimpleValueType();
1724 const VETargetMachine *TM =
1725 static_cast<const VETargetMachine *>(&DAG.getTarget());
1726
1727 // Create GCC_except_tableXX string. The real symbol for that will be
1728 // generated in EHStreamer::emitExceptionTable() later. So, we just
1729 // borrow it's name here.
1730 TM->getStrList()->push_back(std::string(
1731 (Twine("GCC_except_table") + Twine(MF.getFunctionNumber())).str()));
1732 SDValue Addr =
1733 DAG.getTargetExternalSymbol(TM->getStrList()->back().c_str(), VT, 0);
1734 if (isPositionIndependent()) {
1736 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, VT);
1737 return DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Addr);
1738 }
1739 return makeHiLoPair(Addr, VE::S_HI32, VE::S_LO32, DAG);
1740 }
1741 }
1742}
1743
1744static bool getUniqueInsertion(SDNode *N, unsigned &UniqueIdx) {
1746 return false;
1747 const auto *BVN = cast<BuildVectorSDNode>(N);
1748
1749 // Find first non-undef insertion.
1750 unsigned Idx;
1751 for (Idx = 0; Idx < BVN->getNumOperands(); ++Idx) {
1752 auto ElemV = BVN->getOperand(Idx);
1753 if (!ElemV->isUndef())
1754 break;
1755 }
1756 // Catch the (hypothetical) all-undef case.
1757 if (Idx == BVN->getNumOperands())
1758 return false;
1759 // Remember insertion.
1760 UniqueIdx = Idx++;
1761 // Verify that all other insertions are undef.
1762 for (; Idx < BVN->getNumOperands(); ++Idx) {
1763 auto ElemV = BVN->getOperand(Idx);
1764 if (!ElemV->isUndef())
1765 return false;
1766 }
1767 return true;
1768}
1769
1771 if (auto *BuildVec = dyn_cast<BuildVectorSDNode>(N)) {
1772 return BuildVec->getSplatValue();
1773 }
1774 return SDValue();
1775}
1776
1778 SelectionDAG &DAG) const {
1779 VECustomDAG CDAG(DAG, Op);
1780 MVT ResultVT = Op.getSimpleValueType();
1781
1782 // If there is just one element, expand to INSERT_VECTOR_ELT.
1783 unsigned UniqueIdx;
1784 if (getUniqueInsertion(Op.getNode(), UniqueIdx)) {
1785 SDValue AccuV = CDAG.getUNDEF(Op.getValueType());
1786 auto ElemV = Op->getOperand(UniqueIdx);
1787 SDValue IdxV = CDAG.getConstant(UniqueIdx, MVT::i64);
1788 return CDAG.getNode(ISD::INSERT_VECTOR_ELT, ResultVT, {AccuV, ElemV, IdxV});
1789 }
1790
1791 // Else emit a broadcast.
1792 if (SDValue ScalarV = getSplatValue(Op.getNode())) {
1793 unsigned NumEls = ResultVT.getVectorNumElements();
1794 auto AVL = CDAG.getConstant(NumEls, MVT::i32);
1795 return CDAG.getBroadcast(ResultVT, ScalarV, AVL);
1796 }
1797
1798 // Expand
1799 return SDValue();
1800}
1801
1804 // Custom legalization on VVP_* and VEC_* opcodes is required to pack-legalize
1805 // these operations (transform nodes such that their AVL parameter refers to
1806 // packs of 64bit, instead of number of elements.
1807
1808 // Packing opcodes are created with a pack-legal AVL (LEGALAVL). No need to
1809 // re-visit them.
1810 if (isPackingSupportOpcode(Op.getOpcode()))
1811 return Legal;
1812
1813 // Custom lower to legalize AVL for packed mode.
1814 if (isVVPOrVEC(Op.getOpcode()))
1815 return Custom;
1816 return Legal;
1817}
1818
1820 LLVM_DEBUG(dbgs() << "::LowerOperation "; Op.dump(&DAG));
1821 unsigned Opcode = Op.getOpcode();
1822
1823 /// Scalar isel.
1824 switch (Opcode) {
1825 case ISD::ATOMIC_FENCE:
1826 return lowerATOMIC_FENCE(Op, DAG);
1827 case ISD::ATOMIC_SWAP:
1828 return lowerATOMIC_SWAP(Op, DAG);
1829 case ISD::BlockAddress:
1830 return lowerBlockAddress(Op, DAG);
1831 case ISD::ConstantPool:
1832 return lowerConstantPool(Op, DAG);
1834 return lowerDYNAMIC_STACKALLOC(Op, DAG);
1836 return lowerEH_SJLJ_LONGJMP(Op, DAG);
1838 return lowerEH_SJLJ_SETJMP(Op, DAG);
1840 return lowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
1841 case ISD::FRAMEADDR:
1842 return lowerFRAMEADDR(Op, DAG, *this, Subtarget);
1843 case ISD::GlobalAddress:
1844 return lowerGlobalAddress(Op, DAG);
1846 return lowerGlobalTLSAddress(Op, DAG);
1848 return lowerINTRINSIC_WO_CHAIN(Op, DAG);
1849 case ISD::JumpTable:
1850 return lowerJumpTable(Op, DAG);
1851 case ISD::LOAD:
1852 return lowerLOAD(Op, DAG);
1853 case ISD::RETURNADDR:
1854 return lowerRETURNADDR(Op, DAG, *this, Subtarget);
1855 case ISD::BUILD_VECTOR:
1856 return lowerBUILD_VECTOR(Op, DAG);
1857 case ISD::STORE:
1858 return lowerSTORE(Op, DAG);
1859 case ISD::VASTART:
1860 return lowerVASTART(Op, DAG);
1861 case ISD::VAARG:
1862 return lowerVAARG(Op, DAG);
1863
1865 return lowerINSERT_VECTOR_ELT(Op, DAG);
1867 return lowerEXTRACT_VECTOR_ELT(Op, DAG);
1868 }
1869
1870 /// Vector isel.
1871 if (ISD::isVPOpcode(Opcode))
1872 return lowerToVVP(Op, DAG);
1873
1874 switch (Opcode) {
1875 default:
1876 llvm_unreachable("Should not custom lower this!");
1877
1878 // Legalize the AVL of this internal node.
1879 case VEISD::VEC_BROADCAST:
1880#define ADD_VVP_OP(VVP_NAME, ...) case VEISD::VVP_NAME:
1881#include "VVPNodes.def"
1882 // AVL already legalized.
1883 if (getAnnotatedNodeAVL(Op).second)
1884 return Op;
1885 return legalizeInternalVectorOp(Op, DAG);
1886
1887 // Translate into a VEC_*/VVP_* layer operation.
1888 case ISD::MLOAD:
1889 case ISD::MSTORE:
1890#define ADD_VVP_OP(VVP_NAME, ISD_NAME) case ISD::ISD_NAME:
1891#include "VVPNodes.def"
1892 if (isMaskArithmetic(Op) && isPackedVectorType(Op.getValueType()))
1893 return splitMaskArithmetic(Op, DAG);
1894 return lowerToVVP(Op, DAG);
1895 }
1896}
1897/// } Custom Lower
1898
1901 SelectionDAG &DAG) const {
1902 switch (N->getOpcode()) {
1903 case ISD::ATOMIC_SWAP:
1904 // Let LLVM expand atomic swap instruction through LowerOperation.
1905 return;
1906 default:
1907 LLVM_DEBUG(N->dumpr(&DAG));
1908 llvm_unreachable("Do not know how to custom type legalize this operation!");
1909 }
1910}
1911
1912/// JumpTable for VE.
1913///
1914/// VE cannot generate relocatable symbol in jump table. VE cannot
1915/// generate expressions using symbols in both text segment and data
1916/// segment like below.
1917/// .4byte .LBB0_2-.LJTI0_0
1918/// So, we generate offset from the top of function like below as
1919/// a custom label.
1920/// .4byte .LBB0_2-<function name>
1921
1923 // Use custom label for PIC.
1926
1927 // Otherwise, use the normal jump table encoding heuristics.
1929}
1930
1932 const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB,
1933 unsigned Uid, MCContext &Ctx) const {
1935
1936 // Generate custom label for PIC like below.
1937 // .4bytes .LBB0_2-<function name>
1938 const auto *Value = MCSymbolRefExpr::create(MBB->getSymbol(), Ctx);
1939 MCSymbol *Sym = Ctx.getOrCreateSymbol(MBB->getParent()->getName().data());
1940 const auto *Base = MCSymbolRefExpr::create(Sym, Ctx);
1941 return MCBinaryExpr::createSub(Value, Base, Ctx);
1942}
1943
1945 SelectionDAG &DAG) const {
1947 SDLoc DL(Table);
1949 assert(Function != nullptr);
1950 auto PtrTy = getPointerTy(DAG.getDataLayout(), Function->getAddressSpace());
1951
1952 // In the jump table, we have following values in PIC mode.
1953 // .4bytes .LBB0_2-<function name>
1954 // We need to add this value and the address of this function to generate
1955 // .LBB0_2 label correctly under PIC mode. So, we want to generate following
1956 // instructions:
1957 // lea %reg, fun@gotoff_lo
1958 // and %reg, %reg, (32)0
1959 // lea.sl %reg, fun@gotoff_hi(%reg, %got)
1960 // In order to do so, we need to genarate correctly marked DAG node using
1961 // makeHiLoPair.
1962 SDValue Op = DAG.getGlobalAddress(Function, DL, PtrTy);
1964 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrTy);
1965 return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo);
1966}
1967
1970 MachineBasicBlock *TargetBB,
1971 const DebugLoc &DL) const {
1972 MachineFunction *MF = MBB.getParent();
1973 MachineRegisterInfo &MRI = MF->getRegInfo();
1974 const VEInstrInfo *TII = Subtarget->getInstrInfo();
1975
1976 const TargetRegisterClass *RC = &VE::I64RegClass;
1977 Register Tmp1 = MRI.createVirtualRegister(RC);
1978 Register Tmp2 = MRI.createVirtualRegister(RC);
1979 Register Result = MRI.createVirtualRegister(RC);
1980
1981 if (isPositionIndependent()) {
1982 // Create following instructions for local linkage PIC code.
1983 // lea %Tmp1, TargetBB@gotoff_lo
1984 // and %Tmp2, %Tmp1, (32)0
1985 // lea.sl %Result, TargetBB@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
1986 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
1987 .addImm(0)
1988 .addImm(0)
1989 .addMBB(TargetBB, VE::S_GOTOFF_LO32);
1990 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
1991 .addReg(Tmp1, getKillRegState(true))
1992 .addImm(M0(32));
1993 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
1994 .addReg(VE::SX15)
1995 .addReg(Tmp2, getKillRegState(true))
1996 .addMBB(TargetBB, VE::S_GOTOFF_HI32);
1997 } else {
1998 // Create following instructions for non-PIC code.
1999 // lea %Tmp1, TargetBB@lo
2000 // and %Tmp2, %Tmp1, (32)0
2001 // lea.sl %Result, TargetBB@hi(%Tmp2)
2002 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2003 .addImm(0)
2004 .addImm(0)
2005 .addMBB(TargetBB, VE::S_LO32);
2006 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2007 .addReg(Tmp1, getKillRegState(true))
2008 .addImm(M0(32));
2009 BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
2010 .addReg(Tmp2, getKillRegState(true))
2011 .addImm(0)
2012 .addMBB(TargetBB, VE::S_HI32);
2013 }
2014 return Result;
2015}
2016
2019 StringRef Symbol, const DebugLoc &DL,
2020 bool IsLocal = false,
2021 bool IsCall = false) const {
2022 MachineFunction *MF = MBB.getParent();
2023 MachineRegisterInfo &MRI = MF->getRegInfo();
2024 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2025
2026 const TargetRegisterClass *RC = &VE::I64RegClass;
2027 Register Result = MRI.createVirtualRegister(RC);
2028
2029 if (isPositionIndependent()) {
2030 if (IsCall && !IsLocal) {
2031 // Create following instructions for non-local linkage PIC code function
2032 // calls. These instructions uses IC and magic number -24, so we expand
2033 // them in VEAsmPrinter.cpp from GETFUNPLT pseudo instruction.
2034 // lea %Reg, Symbol@plt_lo(-24)
2035 // and %Reg, %Reg, (32)0
2036 // sic %s16
2037 // lea.sl %Result, Symbol@plt_hi(%Reg, %s16) ; %s16 is PLT
2038 BuildMI(MBB, I, DL, TII->get(VE::GETFUNPLT), Result)
2039 .addExternalSymbol("abort");
2040 } else if (IsLocal) {
2041 Register Tmp1 = MRI.createVirtualRegister(RC);
2042 Register Tmp2 = MRI.createVirtualRegister(RC);
2043 // Create following instructions for local linkage PIC code.
2044 // lea %Tmp1, Symbol@gotoff_lo
2045 // and %Tmp2, %Tmp1, (32)0
2046 // lea.sl %Result, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2047 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2048 .addImm(0)
2049 .addImm(0)
2050 .addExternalSymbol(Symbol.data(), VE::S_GOTOFF_LO32);
2051 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2052 .addReg(Tmp1, getKillRegState(true))
2053 .addImm(M0(32));
2054 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
2055 .addReg(VE::SX15)
2056 .addReg(Tmp2, getKillRegState(true))
2057 .addExternalSymbol(Symbol.data(), VE::S_GOTOFF_HI32);
2058 } else {
2059 Register Tmp1 = MRI.createVirtualRegister(RC);
2060 Register Tmp2 = MRI.createVirtualRegister(RC);
2061 // Create following instructions for not local linkage PIC code.
2062 // lea %Tmp1, Symbol@got_lo
2063 // and %Tmp2, %Tmp1, (32)0
2064 // lea.sl %Tmp3, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2065 // ld %Result, 0(%Tmp3)
2066 Register Tmp3 = MRI.createVirtualRegister(RC);
2067 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2068 .addImm(0)
2069 .addImm(0)
2070 .addExternalSymbol(Symbol.data(), VE::S_GOT_LO32);
2071 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2072 .addReg(Tmp1, getKillRegState(true))
2073 .addImm(M0(32));
2074 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Tmp3)
2075 .addReg(VE::SX15)
2076 .addReg(Tmp2, getKillRegState(true))
2077 .addExternalSymbol(Symbol.data(), VE::S_GOT_HI32);
2078 BuildMI(MBB, I, DL, TII->get(VE::LDrii), Result)
2079 .addReg(Tmp3, getKillRegState(true))
2080 .addImm(0)
2081 .addImm(0);
2082 }
2083 } else {
2084 Register Tmp1 = MRI.createVirtualRegister(RC);
2085 Register Tmp2 = MRI.createVirtualRegister(RC);
2086 // Create following instructions for non-PIC code.
2087 // lea %Tmp1, Symbol@lo
2088 // and %Tmp2, %Tmp1, (32)0
2089 // lea.sl %Result, Symbol@hi(%Tmp2)
2090 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2091 .addImm(0)
2092 .addImm(0)
2093 .addExternalSymbol(Symbol.data(), VE::S_LO32);
2094 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2095 .addReg(Tmp1, getKillRegState(true))
2096 .addImm(M0(32));
2097 BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
2098 .addReg(Tmp2, getKillRegState(true))
2099 .addImm(0)
2100 .addExternalSymbol(Symbol.data(), VE::S_HI32);
2101 }
2102 return Result;
2103}
2104
2107 MachineBasicBlock *DispatchBB,
2108 int FI, int Offset) const {
2109 DebugLoc DL = MI.getDebugLoc();
2110 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2111
2112 Register LabelReg =
2114
2115 // Store an address of DispatchBB to a given jmpbuf[1] where has next IC
2116 // referenced by longjmp (throw) later.
2117 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2118 addFrameReference(MIB, FI, Offset); // jmpbuf[1]
2119 MIB.addReg(LabelReg, getKillRegState(true));
2120}
2121
2124 MachineBasicBlock *MBB) const {
2125 DebugLoc DL = MI.getDebugLoc();
2126 MachineFunction *MF = MBB->getParent();
2127 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
2128 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
2129 MachineRegisterInfo &MRI = MF->getRegInfo();
2130
2131 const BasicBlock *BB = MBB->getBasicBlock();
2132 MachineFunction::iterator I = ++MBB->getIterator();
2133
2134 // Memory Reference.
2135 SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands());
2136 Register BufReg = MI.getOperand(1).getReg();
2137
2138 Register DstReg;
2139
2140 DstReg = MI.getOperand(0).getReg();
2141 const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
2142 assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
2143 (void)TRI;
2144 Register MainDestReg = MRI.createVirtualRegister(RC);
2145 Register RestoreDestReg = MRI.createVirtualRegister(RC);
2146
2147 // For `v = call @llvm.eh.sjlj.setjmp(buf)`, we generate following
2148 // instructions. SP/FP must be saved in jmpbuf before `llvm.eh.sjlj.setjmp`.
2149 //
2150 // ThisMBB:
2151 // buf[3] = %s17 iff %s17 is used as BP
2152 // buf[1] = RestoreMBB as IC after longjmp
2153 // # SjLjSetup RestoreMBB
2154 //
2155 // MainMBB:
2156 // v_main = 0
2157 //
2158 // SinkMBB:
2159 // v = phi(v_main, MainMBB, v_restore, RestoreMBB)
2160 // ...
2161 //
2162 // RestoreMBB:
2163 // %s17 = buf[3] = iff %s17 is used as BP
2164 // v_restore = 1
2165 // goto SinkMBB
2166
2167 MachineBasicBlock *ThisMBB = MBB;
2168 MachineBasicBlock *MainMBB = MF->CreateMachineBasicBlock(BB);
2169 MachineBasicBlock *SinkMBB = MF->CreateMachineBasicBlock(BB);
2170 MachineBasicBlock *RestoreMBB = MF->CreateMachineBasicBlock(BB);
2171 MF->insert(I, MainMBB);
2172 MF->insert(I, SinkMBB);
2173 MF->push_back(RestoreMBB);
2174 RestoreMBB->setMachineBlockAddressTaken();
2175
2176 // Transfer the remainder of BB and its successor edges to SinkMBB.
2177 SinkMBB->splice(SinkMBB->begin(), MBB,
2178 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
2180
2181 // ThisMBB:
2182 Register LabelReg =
2184
2185 // Store BP in buf[3] iff this function is using BP.
2186 const VEFrameLowering *TFI = Subtarget->getFrameLowering();
2187 if (TFI->hasBP(*MF)) {
2188 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2189 MIB.addReg(BufReg);
2190 MIB.addImm(0);
2191 MIB.addImm(24);
2192 MIB.addReg(VE::SX17);
2193 MIB.setMemRefs(MMOs);
2194 }
2195
2196 // Store IP in buf[1].
2197 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2198 MIB.add(MI.getOperand(1)); // we can preserve the kill flags here.
2199 MIB.addImm(0);
2200 MIB.addImm(8);
2201 MIB.addReg(LabelReg, getKillRegState(true));
2202 MIB.setMemRefs(MMOs);
2203
2204 // SP/FP are already stored in jmpbuf before `llvm.eh.sjlj.setjmp`.
2205
2206 // Insert setup.
2207 MIB =
2208 BuildMI(*ThisMBB, MI, DL, TII->get(VE::EH_SjLj_Setup)).addMBB(RestoreMBB);
2209
2210 const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2211 MIB.addRegMask(RegInfo->getNoPreservedMask());
2212 ThisMBB->addSuccessor(MainMBB);
2213 ThisMBB->addSuccessor(RestoreMBB);
2214
2215 // MainMBB:
2216 BuildMI(MainMBB, DL, TII->get(VE::LEAzii), MainDestReg)
2217 .addImm(0)
2218 .addImm(0)
2219 .addImm(0);
2220 MainMBB->addSuccessor(SinkMBB);
2221
2222 // SinkMBB:
2223 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII->get(VE::PHI), DstReg)
2224 .addReg(MainDestReg)
2225 .addMBB(MainMBB)
2226 .addReg(RestoreDestReg)
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(VE::BRCFLa_t)).addMBB(SinkMBB);
2246 RestoreMBB->addSuccessor(SinkMBB);
2247
2248 MI.eraseFromParent();
2249 return SinkMBB;
2250}
2251
2254 MachineBasicBlock *MBB) const {
2255 DebugLoc DL = MI.getDebugLoc();
2256 MachineFunction *MF = MBB->getParent();
2257 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
2258 MachineRegisterInfo &MRI = MF->getRegInfo();
2259
2260 // Memory Reference.
2261 SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands());
2262 Register BufReg = MI.getOperand(0).getReg();
2263
2264 Register Tmp = MRI.createVirtualRegister(&VE::I64RegClass);
2265 // Since FP is only updated here but NOT referenced, it's treated as GPR.
2266 Register FP = VE::SX9;
2267 Register SP = VE::SX11;
2268
2270
2271 MachineBasicBlock *ThisMBB = MBB;
2272
2273 // For `call @llvm.eh.sjlj.longjmp(buf)`, we generate following instructions.
2274 //
2275 // ThisMBB:
2276 // %fp = load buf[0]
2277 // %jmp = load buf[1]
2278 // %s10 = buf ; Store an address of buf to SX10 for RestoreMBB
2279 // %sp = load buf[2] ; generated by llvm.eh.sjlj.setjmp.
2280 // jmp %jmp
2281
2282 // Reload FP.
2283 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), FP);
2284 MIB.addReg(BufReg);
2285 MIB.addImm(0);
2286 MIB.addImm(0);
2287 MIB.setMemRefs(MMOs);
2288
2289 // Reload IP.
2290 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), Tmp);
2291 MIB.addReg(BufReg);
2292 MIB.addImm(0);
2293 MIB.addImm(8);
2294 MIB.setMemRefs(MMOs);
2295
2296 // Copy BufReg to SX10 for later use in setjmp.
2297 // FIXME: Better to not use SX10 here
2298 BuildMI(*ThisMBB, MI, DL, TII->get(VE::ORri), VE::SX10)
2299 .addReg(BufReg)
2300 .addImm(0);
2301
2302 // Reload SP.
2303 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), SP);
2304 MIB.add(MI.getOperand(0)); // we can preserve the kill flags here.
2305 MIB.addImm(0);
2306 MIB.addImm(16);
2307 MIB.setMemRefs(MMOs);
2308
2309 // Jump.
2310 BuildMI(*ThisMBB, MI, DL, TII->get(VE::BCFLari_t))
2311 .addReg(Tmp, getKillRegState(true))
2312 .addImm(0);
2313
2314 MI.eraseFromParent();
2315 return ThisMBB;
2316}
2317
2320 MachineBasicBlock *BB) const {
2321 DebugLoc DL = MI.getDebugLoc();
2322 MachineFunction *MF = BB->getParent();
2323 MachineFrameInfo &MFI = MF->getFrameInfo();
2324 MachineRegisterInfo &MRI = MF->getRegInfo();
2325 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2326 int FI = MFI.getFunctionContextIndex();
2327
2328 // Get a mapping of the call site numbers to all of the landing pads they're
2329 // associated with.
2331 unsigned MaxCSNum = 0;
2332 for (auto &MBB : *MF) {
2333 if (!MBB.isEHPad())
2334 continue;
2335
2336 MCSymbol *Sym = nullptr;
2337 for (const auto &MI : MBB) {
2338 if (MI.isDebugInstr())
2339 continue;
2340
2341 assert(MI.isEHLabel() && "expected EH_LABEL");
2342 Sym = MI.getOperand(0).getMCSymbol();
2343 break;
2344 }
2345
2346 if (!MF->hasCallSiteLandingPad(Sym))
2347 continue;
2348
2349 for (unsigned CSI : MF->getCallSiteLandingPad(Sym)) {
2350 CallSiteNumToLPad[CSI].push_back(&MBB);
2351 MaxCSNum = std::max(MaxCSNum, CSI);
2352 }
2353 }
2354
2355 // Get an ordered list of the machine basic blocks for the jump table.
2356 std::vector<MachineBasicBlock *> LPadList;
2358 LPadList.reserve(CallSiteNumToLPad.size());
2359
2360 for (unsigned CSI = 1; CSI <= MaxCSNum; ++CSI) {
2361 for (auto &LP : CallSiteNumToLPad[CSI]) {
2362 LPadList.push_back(LP);
2363 InvokeBBs.insert_range(LP->predecessors());
2364 }
2365 }
2366
2367 assert(!LPadList.empty() &&
2368 "No landing pad destinations for the dispatch jump table!");
2369
2370 // The %fn_context is allocated like below (from --print-after=sjljehprepare):
2371 // %fn_context = alloca { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }
2372 //
2373 // This `[5 x i8*]` is jmpbuf, so jmpbuf[1] is FI+72.
2374 // First `i64` is callsite, so callsite is FI+8.
2375 static const int OffsetIC = 72;
2376 static const int OffsetCS = 8;
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, getKillRegState(true))
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 Register IReg = MRI.createVirtualRegister(RC);
2445 addFrameReference(BuildMI(DispatchBB, DL, TII->get(VE::LDLZXrii), IReg), FI,
2446 OffsetCS);
2447 if (LPadList.size() < 64) {
2448 BuildMI(DispatchBB, DL, TII->get(VE::BRCFLir_t))
2450 .addImm(LPadList.size())
2451 .addReg(IReg)
2452 .addMBB(TrapBB);
2453 } else {
2454 assert(LPadList.size() <= 0x7FFFFFFF && "Too large Landing Pad!");
2455 Register TmpReg = MRI.createVirtualRegister(RC);
2456 BuildMI(DispatchBB, DL, TII->get(VE::LEAzii), TmpReg)
2457 .addImm(0)
2458 .addImm(0)
2459 .addImm(LPadList.size());
2460 BuildMI(DispatchBB, DL, TII->get(VE::BRCFLrr_t))
2462 .addReg(TmpReg, getKillRegState(true))
2463 .addReg(IReg)
2464 .addMBB(TrapBB);
2465 }
2466
2467 Register BReg = MRI.createVirtualRegister(RC);
2468 Register Tmp1 = MRI.createVirtualRegister(RC);
2469 Register Tmp2 = MRI.createVirtualRegister(RC);
2470
2471 if (isPositionIndependent()) {
2472 // Create following instructions for local linkage PIC code.
2473 // lea %Tmp1, .LJTI0_0@gotoff_lo
2474 // and %Tmp2, %Tmp1, (32)0
2475 // lea.sl %BReg, .LJTI0_0@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2476 BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
2477 .addImm(0)
2478 .addImm(0)
2480 BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
2481 .addReg(Tmp1, getKillRegState(true))
2482 .addImm(M0(32));
2483 BuildMI(DispContBB, DL, TII->get(VE::LEASLrri), BReg)
2484 .addReg(VE::SX15)
2485 .addReg(Tmp2, getKillRegState(true))
2487 } else {
2488 // Create following instructions for non-PIC code.
2489 // lea %Tmp1, .LJTI0_0@lo
2490 // and %Tmp2, %Tmp1, (32)0
2491 // lea.sl %BReg, .LJTI0_0@hi(%Tmp2)
2492 BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
2493 .addImm(0)
2494 .addImm(0)
2496 BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
2497 .addReg(Tmp1, getKillRegState(true))
2498 .addImm(M0(32));
2499 BuildMI(DispContBB, DL, TII->get(VE::LEASLrii), BReg)
2500 .addReg(Tmp2, getKillRegState(true))
2501 .addImm(0)
2503 }
2504
2505 switch (JTE) {
2507 // Generate simple block address code for no-PIC model.
2508 // sll %Tmp1, %IReg, 3
2509 // lds %TReg, 0(%Tmp1, %BReg)
2510 // bcfla %TReg
2511
2512 Register TReg = MRI.createVirtualRegister(RC);
2513 Register Tmp1 = MRI.createVirtualRegister(RC);
2514
2515 BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
2516 .addReg(IReg, getKillRegState(true))
2517 .addImm(3);
2518 BuildMI(DispContBB, DL, TII->get(VE::LDrri), TReg)
2519 .addReg(BReg, getKillRegState(true))
2520 .addReg(Tmp1, getKillRegState(true))
2521 .addImm(0);
2522 BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
2523 .addReg(TReg, getKillRegState(true))
2524 .addImm(0);
2525 break;
2526 }
2528 // Generate block address code using differences from the function pointer
2529 // for PIC model.
2530 // sll %Tmp1, %IReg, 2
2531 // ldl.zx %OReg, 0(%Tmp1, %BReg)
2532 // Prepare function address in BReg2.
2533 // adds.l %TReg, %BReg2, %OReg
2534 // bcfla %TReg
2535
2537 Register OReg = MRI.createVirtualRegister(RC);
2538 Register TReg = MRI.createVirtualRegister(RC);
2539 Register Tmp1 = MRI.createVirtualRegister(RC);
2540
2541 BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
2542 .addReg(IReg, getKillRegState(true))
2543 .addImm(2);
2544 BuildMI(DispContBB, DL, TII->get(VE::LDLZXrri), OReg)
2545 .addReg(BReg, getKillRegState(true))
2546 .addReg(Tmp1, getKillRegState(true))
2547 .addImm(0);
2548 Register BReg2 =
2549 prepareSymbol(*DispContBB, DispContBB->end(),
2550 DispContBB->getParent()->getName(), DL, /* Local */ true);
2551 BuildMI(DispContBB, DL, TII->get(VE::ADDSLrr), TReg)
2552 .addReg(OReg, getKillRegState(true))
2553 .addReg(BReg2, getKillRegState(true));
2554 BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
2555 .addReg(TReg, getKillRegState(true))
2556 .addImm(0);
2557 break;
2558 }
2559 default:
2560 llvm_unreachable("Unexpected jump table encoding");
2561 }
2562
2563 // Add the jump table entries as successors to the MBB.
2565 for (auto &LP : LPadList)
2566 if (SeenMBBs.insert(LP).second)
2567 DispContBB->addSuccessor(LP);
2568
2569 // N.B. the order the invoke BBs are processed in doesn't matter here.
2571 const MCPhysReg *SavedRegs = MF->getRegInfo().getCalleeSavedRegs();
2572 for (MachineBasicBlock *MBB : InvokeBBs) {
2573 // Remove the landing pad successor from the invoke block and replace it
2574 // with the new dispatch block.
2575 // Keep a copy of Successors since it's modified inside the loop.
2576 SmallVector<MachineBasicBlock *, 8> Successors(MBB->succ_rbegin(),
2577 MBB->succ_rend());
2578 // FIXME: Avoid quadratic complexity.
2579 for (auto *MBBS : Successors) {
2580 if (MBBS->isEHPad()) {
2581 MBB->removeSuccessor(MBBS);
2582 MBBLPads.push_back(MBBS);
2583 }
2584 }
2585
2586 MBB->addSuccessor(DispatchBB);
2587
2588 // Find the invoke call and mark all of the callee-saved registers as
2589 // 'implicit defined' so that they're spilled. This prevents code from
2590 // moving instructions to before the EH block, where they will never be
2591 // executed.
2592 for (auto &II : reverse(*MBB)) {
2593 if (!II.isCall())
2594 continue;
2595
2596 DenseSet<Register> DefRegs;
2597 for (auto &MOp : II.operands())
2598 if (MOp.isReg())
2599 DefRegs.insert(MOp.getReg());
2600
2601 MachineInstrBuilder MIB(*MF, &II);
2602 for (unsigned RI = 0; SavedRegs[RI]; ++RI) {
2603 Register Reg = SavedRegs[RI];
2604 if (!DefRegs.contains(Reg))
2606 }
2607
2608 break;
2609 }
2610 }
2611
2612 // Mark all former landing pads as non-landing pads. The dispatch is the only
2613 // landing pad now.
2614 for (auto &LP : MBBLPads)
2615 LP->setIsEHPad(false);
2616
2617 // The instruction is gone now.
2618 MI.eraseFromParent();
2619 return BB;
2620}
2621
2624 MachineBasicBlock *BB) const {
2625 switch (MI.getOpcode()) {
2626 default:
2627 llvm_unreachable("Unknown Custom Instruction!");
2628 case VE::EH_SjLj_LongJmp:
2629 return emitEHSjLjLongJmp(MI, BB);
2630 case VE::EH_SjLj_SetJmp:
2631 return emitEHSjLjSetJmp(MI, BB);
2632 case VE::EH_SjLj_Setup_Dispatch:
2633 return emitSjLjDispatchBlock(MI, BB);
2634 }
2635}
2636
2637static bool isSimm7(SDValue V) {
2638 EVT VT = V.getValueType();
2639 if (VT.isVector())
2640 return false;
2641
2642 if (VT.isInteger()) {
2644 return isInt<7>(C->getSExtValue());
2645 } else if (VT.isFloatingPoint()) {
2647 if (VT == MVT::f32 || VT == MVT::f64) {
2648 const APInt &Imm = C->getValueAPF().bitcastToAPInt();
2649 uint64_t Val = Imm.getSExtValue();
2650 if (Imm.getBitWidth() == 32)
2651 Val <<= 32; // Immediate value of float place at higher bits on VE.
2652 return isInt<7>(Val);
2653 }
2654 }
2655 }
2656 return false;
2657}
2658
2659static bool isMImm(SDValue V) {
2660 EVT VT = V.getValueType();
2661 if (VT.isVector())
2662 return false;
2663
2664 if (VT.isInteger()) {
2666 return isMImmVal(getImmVal(C));
2667 } else if (VT.isFloatingPoint()) {
2669 if (VT == MVT::f32) {
2670 // Float value places at higher bits, so ignore lower 32 bits.
2671 return isMImm32Val(getFpImmVal(C) >> 32);
2672 } else if (VT == MVT::f64) {
2673 return isMImmVal(getFpImmVal(C));
2674 }
2675 }
2676 }
2677 return false;
2678}
2679
2680static unsigned decideComp(EVT SrcVT, ISD::CondCode CC) {
2681 if (SrcVT.isFloatingPoint()) {
2682 if (SrcVT == MVT::f128)
2683 return VEISD::CMPQ;
2684 return VEISD::CMPF;
2685 }
2686 return isSignedIntSetCC(CC) ? VEISD::CMPI : VEISD::CMPU;
2687}
2688
2689static EVT decideCompType(EVT SrcVT) {
2690 if (SrcVT == MVT::f128)
2691 return MVT::f64;
2692 return SrcVT;
2693}
2694
2696 bool WithCMov) {
2697 if (SrcVT.isFloatingPoint()) {
2698 // For the case of floating point setcc, only unordered comparison
2699 // or general comparison with -enable-no-nans-fp-math option reach
2700 // here, so it is safe even if values are NaN. Only f128 doesn't
2701 // safe since VE uses f64 result of f128 comparison.
2702 return SrcVT != MVT::f128;
2703 }
2704 if (isIntEqualitySetCC(CC)) {
2705 // For the case of equal or not equal, it is safe without comparison with 0.
2706 return true;
2707 }
2708 if (WithCMov) {
2709 // For the case of integer setcc with cmov, all signed comparison with 0
2710 // are safe.
2711 return isSignedIntSetCC(CC);
2712 }
2713 // For the case of integer setcc, only signed 64 bits comparison is safe.
2714 // For unsigned, "CMPU 0x80000000, 0" has to be greater than 0, but it becomes
2715 // less than 0 witout CMPU. For 32 bits, other half of 32 bits are
2716 // uncoditional, so it is not safe too without CMPI..
2717 return isSignedIntSetCC(CC) && SrcVT == MVT::i64;
2718}
2719
2721 ISD::CondCode CC, bool WithCMov,
2722 const SDLoc &DL, SelectionDAG &DAG) {
2723 // Compare values. If RHS is 0 and it is safe to calculate without
2724 // comparison, we don't generate an instruction for comparison.
2725 EVT CompVT = decideCompType(VT);
2726 if (CompVT == VT && safeWithoutCompWithNull(VT, CC, WithCMov) &&
2728 return LHS;
2729 }
2730 return DAG.getNode(decideComp(VT, CC), DL, CompVT, LHS, RHS);
2731}
2732
2734 DAGCombinerInfo &DCI) const {
2735 assert(N->getOpcode() == ISD::SELECT &&
2736 "Should be called with a SELECT node");
2738 SDValue Cond = N->getOperand(0);
2739 SDValue True = N->getOperand(1);
2740 SDValue False = N->getOperand(2);
2741
2742 // We handle only scalar SELECT.
2743 EVT VT = N->getValueType(0);
2744 if (VT.isVector())
2745 return SDValue();
2746
2747 // Peform combineSelect after leagalize DAG.
2748 if (!DCI.isAfterLegalizeDAG())
2749 return SDValue();
2750
2751 EVT VT0 = Cond.getValueType();
2752 if (isMImm(True)) {
2753 // VE's condition move can handle MImm in True clause, so nothing to do.
2754 } else if (isMImm(False)) {
2755 // VE's condition move can handle MImm in True clause, so swap True and
2756 // False clauses if False has MImm value. And, update condition code.
2757 std::swap(True, False);
2758 CC = getSetCCInverse(CC, VT0);
2759 }
2760
2761 SDLoc DL(N);
2762 SelectionDAG &DAG = DCI.DAG;
2763 VECC::CondCode VECCVal;
2764 if (VT0.isFloatingPoint()) {
2765 VECCVal = fpCondCode2Fcc(CC);
2766 } else {
2767 VECCVal = intCondCode2Icc(CC);
2768 }
2769 SDValue Ops[] = {Cond, True, False,
2770 DAG.getConstant(VECCVal, DL, MVT::i32)};
2771 return DAG.getNode(VEISD::CMOV, DL, VT, Ops);
2772}
2773
2775 DAGCombinerInfo &DCI) const {
2776 assert(N->getOpcode() == ISD::SELECT_CC &&
2777 "Should be called with a SELECT_CC node");
2778 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
2779 SDValue LHS = N->getOperand(0);
2780 SDValue RHS = N->getOperand(1);
2781 SDValue True = N->getOperand(2);
2782 SDValue False = N->getOperand(3);
2783
2784 // We handle only scalar SELECT_CC.
2785 EVT VT = N->getValueType(0);
2786 if (VT.isVector())
2787 return SDValue();
2788
2789 // Peform combineSelectCC after leagalize DAG.
2790 if (!DCI.isAfterLegalizeDAG())
2791 return SDValue();
2792
2793 // We handle only i32/i64/f32/f64/f128 comparisons.
2794 EVT LHSVT = LHS.getValueType();
2795 assert(LHSVT == RHS.getValueType());
2796 switch (LHSVT.getSimpleVT().SimpleTy) {
2797 case MVT::i32:
2798 case MVT::i64:
2799 case MVT::f32:
2800 case MVT::f64:
2801 case MVT::f128:
2802 break;
2803 default:
2804 // Return SDValue to let llvm handle other types.
2805 return SDValue();
2806 }
2807
2808 if (isMImm(RHS)) {
2809 // VE's comparison can handle MImm in RHS, so nothing to do.
2810 } else if (isSimm7(RHS)) {
2811 // VE's comparison can handle Simm7 in LHS, so swap LHS and RHS, and
2812 // update condition code.
2813 std::swap(LHS, RHS);
2814 CC = getSetCCSwappedOperands(CC);
2815 }
2816 if (isMImm(True)) {
2817 // VE's condition move can handle MImm in True clause, so nothing to do.
2818 } else if (isMImm(False)) {
2819 // VE's condition move can handle MImm in True clause, so swap True and
2820 // False clauses if False has MImm value. And, update condition code.
2821 std::swap(True, False);
2822 CC = getSetCCInverse(CC, LHSVT);
2823 }
2824
2825 SDLoc DL(N);
2826 SelectionDAG &DAG = DCI.DAG;
2827
2828 bool WithCMov = true;
2829 SDValue CompNode = generateComparison(LHSVT, LHS, RHS, CC, WithCMov, DL, DAG);
2830
2831 VECC::CondCode VECCVal;
2832 if (LHSVT.isFloatingPoint()) {
2833 VECCVal = fpCondCode2Fcc(CC);
2834 } else {
2835 VECCVal = intCondCode2Icc(CC);
2836 }
2837 SDValue Ops[] = {CompNode, True, False,
2838 DAG.getConstant(VECCVal, DL, MVT::i32)};
2839 return DAG.getNode(VEISD::CMOV, DL, VT, Ops);
2840}
2841
2842static bool isI32InsnAllUses(const SDNode *User, const SDNode *N);
2843static bool isI32Insn(const SDNode *User, const SDNode *N) {
2844 switch (User->getOpcode()) {
2845 default:
2846 return false;
2847 case ISD::ADD:
2848 case ISD::SUB:
2849 case ISD::MUL:
2850 case ISD::SDIV:
2851 case ISD::UDIV:
2852 case ISD::SETCC:
2853 case ISD::SMIN:
2854 case ISD::SMAX:
2855 case ISD::SHL:
2856 case ISD::SRA:
2857 case ISD::BSWAP:
2858 case ISD::SINT_TO_FP:
2859 case ISD::UINT_TO_FP:
2860 case ISD::BR_CC:
2861 case ISD::BITCAST:
2863 case ISD::ATOMIC_SWAP:
2864 case VEISD::CMPU:
2865 case VEISD::CMPI:
2866 return true;
2867 case ISD::SRL:
2868 if (N->getOperand(0).getOpcode() != ISD::SRL)
2869 return true;
2870 // (srl (trunc (srl ...))) may be optimized by combining srl, so
2871 // doesn't optimize trunc now.
2872 return false;
2873 case ISD::SELECT_CC:
2874 if (User->getOperand(2).getNode() != N &&
2875 User->getOperand(3).getNode() != N)
2876 return true;
2877 return isI32InsnAllUses(User, N);
2878 case VEISD::CMOV:
2879 // CMOV in (cmov (trunc ...), true, false, int-comparison) is safe.
2880 // However, trunc in true or false clauses is not safe.
2881 if (User->getOperand(1).getNode() != N &&
2882 User->getOperand(2).getNode() != N &&
2884 VECC::CondCode VECCVal =
2885 static_cast<VECC::CondCode>(User->getConstantOperandVal(3));
2886 return isIntVECondCode(VECCVal);
2887 }
2888 [[fallthrough]];
2889 case ISD::AND:
2890 case ISD::OR:
2891 case ISD::XOR:
2892 case ISD::SELECT:
2893 case ISD::CopyToReg:
2894 // Check all use of selections, bit operations, and copies. If all of them
2895 // are safe, optimize truncate to extract_subreg.
2896 return isI32InsnAllUses(User, N);
2897 }
2898}
2899
2900static bool isI32InsnAllUses(const SDNode *User, const SDNode *N) {
2901 // Check all use of User node. If all of them are safe, optimize
2902 // truncate to extract_subreg.
2903 for (const SDNode *U : User->users()) {
2904 switch (U->getOpcode()) {
2905 default:
2906 // If the use is an instruction which treats the source operand as i32,
2907 // it is safe to avoid truncate here.
2908 if (isI32Insn(U, N))
2909 continue;
2910 break;
2911 case ISD::ANY_EXTEND:
2912 case ISD::SIGN_EXTEND:
2913 case ISD::ZERO_EXTEND: {
2914 // Special optimizations to the combination of ext and trunc.
2915 // (ext ... (select ... (trunc ...))) is safe to avoid truncate here
2916 // since this truncate instruction clears higher 32 bits which is filled
2917 // by one of ext instructions later.
2918 assert(N->getValueType(0) == MVT::i32 &&
2919 "find truncate to not i32 integer");
2920 if (User->getOpcode() == ISD::SELECT_CC ||
2921 User->getOpcode() == ISD::SELECT || User->getOpcode() == VEISD::CMOV)
2922 continue;
2923 break;
2924 }
2925 }
2926 return false;
2927 }
2928 return true;
2929}
2930
2931// Optimize TRUNCATE in DAG combining. Optimizing it in CUSTOM lower is
2932// sometime too early. Optimizing it in DAG pattern matching in VEInstrInfo.td
2933// is sometime too late. So, doing it at here.
2935 DAGCombinerInfo &DCI) const {
2936 assert(N->getOpcode() == ISD::TRUNCATE &&
2937 "Should be called with a TRUNCATE node");
2938
2939 SelectionDAG &DAG = DCI.DAG;
2940 SDLoc DL(N);
2941 EVT VT = N->getValueType(0);
2942
2943 // We prefer to do this when all types are legal.
2944 if (!DCI.isAfterLegalizeDAG())
2945 return SDValue();
2946
2947 // Skip combine TRUNCATE atm if the operand of TRUNCATE might be a constant.
2948 if (N->getOperand(0)->getOpcode() == ISD::SELECT_CC &&
2949 isa<ConstantSDNode>(N->getOperand(0)->getOperand(0)) &&
2950 isa<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
2951 return SDValue();
2952
2953 // Check all use of this TRUNCATE.
2954 for (const SDNode *User : N->users()) {
2955 // Make sure that we're not going to replace TRUNCATE for non i32
2956 // instructions.
2957 //
2958 // FIXME: Although we could sometimes handle this, and it does occur in
2959 // practice that one of the condition inputs to the select is also one of
2960 // the outputs, we currently can't deal with this.
2961 if (isI32Insn(User, N))
2962 continue;
2963
2964 return SDValue();
2965 }
2966
2967 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32);
2968 return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT,
2969 N->getOperand(0), SubI32),
2970 0);
2971}
2972
2974 DAGCombinerInfo &DCI) const {
2975 switch (N->getOpcode()) {
2976 default:
2977 break;
2978 case ISD::SELECT:
2979 return combineSelect(N, DCI);
2980 case ISD::SELECT_CC:
2981 return combineSelectCC(N, DCI);
2982 case ISD::TRUNCATE:
2983 return combineTRUNCATE(N, DCI);
2984 }
2985
2986 return SDValue();
2987}
2988
2989//===----------------------------------------------------------------------===//
2990// VE Inline Assembly Support
2991//===----------------------------------------------------------------------===//
2992
2995 if (Constraint.size() == 1) {
2996 switch (Constraint[0]) {
2997 default:
2998 break;
2999 case 'v': // vector registers
3000 return C_RegisterClass;
3001 }
3002 }
3003 return TargetLowering::getConstraintType(Constraint);
3004}
3005
3006std::pair<unsigned, const TargetRegisterClass *>
3008 StringRef Constraint,
3009 MVT VT) const {
3010 const TargetRegisterClass *RC = nullptr;
3011 if (Constraint.size() == 1) {
3012 switch (Constraint[0]) {
3013 default:
3014 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3015 case 'r':
3016 RC = &VE::I64RegClass;
3017 break;
3018 case 'v':
3019 RC = &VE::V64RegClass;
3020 break;
3021 }
3022 return std::make_pair(0U, RC);
3023 }
3024
3025 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3026}
3027
3028//===----------------------------------------------------------------------===//
3029// VE Target Optimization Support
3030//===----------------------------------------------------------------------===//
3031
3033 // Specify 8 for PIC model to relieve the impact of PIC load instructions.
3034 if (isJumpTableRelative())
3035 return 8;
3036
3038}
3039
3041 EVT VT = Y.getValueType();
3042
3043 // VE doesn't have vector and not instruction.
3044 if (VT.isVector())
3045 return false;
3046
3047 // VE allows different immediate values for X and Y where ~X & Y.
3048 // Only simm7 works for X, and only mimm works for Y on VE. However, this
3049 // function is used to check whether an immediate value is OK for and-not
3050 // instruction as both X and Y. Generating additional instruction to
3051 // retrieve an immediate value is no good since the purpose of this
3052 // function is to convert a series of 3 instructions to another series of
3053 // 3 instructions with better parallelism. Therefore, we return false
3054 // for all immediate values now.
3055 // FIXME: Change hasAndNot function to have two operands to make it work
3056 // correctly with Aurora VE.
3058 return false;
3059
3060 // It's ok for generic registers.
3061 return true;
3062}
3063
3065 SelectionDAG &DAG) const {
3066 assert(Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Unknown opcode!");
3067 MVT VT = Op.getOperand(0).getSimpleValueType();
3068
3069 // Special treatment for packed V64 types.
3070 assert(VT == MVT::v512i32 || VT == MVT::v512f32);
3071 (void)VT;
3072 // Example of codes:
3073 // %packed_v = extractelt %vr, %idx / 2
3074 // %v = %packed_v >> (%idx % 2 * 32)
3075 // %res = %v & 0xffffffff
3076
3077 SDValue Vec = Op.getOperand(0);
3078 SDValue Idx = Op.getOperand(1);
3079 SDLoc DL(Op);
3080 SDValue Result = Op;
3081 if (false /* Idx->isConstant() */) {
3082 // TODO: optimized implementation using constant values
3083 } else {
3084 SDValue Const1 = DAG.getConstant(1, DL, MVT::i64);
3085 SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1});
3086 SDValue PackedElt =
3087 SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0);
3088 SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1});
3089 SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1});
3090 SDValue Const5 = DAG.getConstant(5, DL, MVT::i64);
3091 Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5});
3092 PackedElt = DAG.getNode(ISD::SRL, DL, MVT::i64, {PackedElt, Shift});
3093 SDValue Mask = DAG.getConstant(0xFFFFFFFFL, DL, MVT::i64);
3094 PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask});
3095 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32);
3096 Result = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
3097 MVT::i32, PackedElt, SubI32),
3098 0);
3099
3100 if (Op.getSimpleValueType() == MVT::f32) {
3101 Result = DAG.getBitcast(MVT::f32, Result);
3102 } else {
3103 assert(Op.getSimpleValueType() == MVT::i32);
3104 }
3105 }
3106 return Result;
3107}
3108
3110 SelectionDAG &DAG) const {
3111 assert(Op.getOpcode() == ISD::INSERT_VECTOR_ELT && "Unknown opcode!");
3112 MVT VT = Op.getOperand(0).getSimpleValueType();
3113
3114 // Special treatment for packed V64 types.
3115 assert(VT == MVT::v512i32 || VT == MVT::v512f32);
3116 (void)VT;
3117 // The v512i32 and v512f32 starts from upper bits (0..31). This "upper
3118 // bits" required `val << 32` from C implementation's point of view.
3119 //
3120 // Example of codes:
3121 // %packed_elt = extractelt %vr, (%idx >> 1)
3122 // %shift = ((%idx & 1) ^ 1) << 5
3123 // %packed_elt &= 0xffffffff00000000 >> shift
3124 // %packed_elt |= (zext %val) << shift
3125 // %vr = insertelt %vr, %packed_elt, (%idx >> 1)
3126
3127 SDLoc DL(Op);
3128 SDValue Vec = Op.getOperand(0);
3129 SDValue Val = Op.getOperand(1);
3130 SDValue Idx = Op.getOperand(2);
3131 if (Idx.getSimpleValueType() == MVT::i32)
3132 Idx = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Idx);
3133 if (Val.getSimpleValueType() == MVT::f32)
3134 Val = DAG.getBitcast(MVT::i32, Val);
3135 assert(Val.getSimpleValueType() == MVT::i32);
3136 Val = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Val);
3137
3138 SDValue Result = Op;
3139 if (false /* Idx->isConstant()*/) {
3140 // TODO: optimized implementation using constant values
3141 } else {
3142 SDValue Const1 = DAG.getConstant(1, DL, MVT::i64);
3143 SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1});
3144 SDValue PackedElt =
3145 SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0);
3146 SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1});
3147 SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1});
3148 SDValue Const5 = DAG.getConstant(5, DL, MVT::i64);
3149 Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5});
3150 SDValue Mask = DAG.getConstant(0xFFFFFFFF00000000L, DL, MVT::i64);
3151 Mask = DAG.getNode(ISD::SRL, DL, MVT::i64, {Mask, Shift});
3152 PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask});
3153 Val = DAG.getNode(ISD::SHL, DL, MVT::i64, {Val, Shift});
3154 PackedElt = DAG.getNode(ISD::OR, DL, MVT::i64, {PackedElt, Val});
3155 Result =
3156 SDValue(DAG.getMachineNode(VE::LSVrr_v, DL, Vec.getSimpleValueType(),
3157 {HalfIdx, PackedElt, Vec}),
3158 0);
3159 }
3160 return Result;
3161}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
unsigned uint64_t
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)
const SmallVectorImpl< MachineOperand > & Cond
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h: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
A debug info location.
Definition DebugLoc.h:126
unsigned size() const
Definition DenseMap.h:172
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
unsigned getAddressSpace() const
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
LLVM_ABI bool hasAtomicStore() const LLVM_READONLY
Return true if this atomic instruction stores to memory.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h: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 MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
int getFunctionContextIndex() const
Return the index for the function context object.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
MachineJumpTableInfo * getOrCreateJumpTableInfo(unsigned JTEntryKind)
getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it does already exist,...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool hasCallSiteLandingPad(MCSymbol *Sym)
Return true if the landing pad Eh symbol has an associated call site.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
SmallVectorImpl< unsigned > & getCallSiteLandingPad(MCSymbol *Sym)
Get the call site indexes for a landing pad EH symbol.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & 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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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)
Information about stack frame layout on the target.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual unsigned getMinimumJumpTableEntries() const
Return lower limit for number of blocks in a jump table.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
std::vector< ArgListEntry > ArgListTy
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:282
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
const VERegisterInfo * getRegisterInfo() const override
Definition VESubtarget.h:56
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
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
VETargetLowering(const TargetMachine &TM, const VESubtarget &STI)
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Custom Lower {.
SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
} VVPLowering
SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const
unsigned getMinimumJumpTableEntries() const override
} Inline Assembly
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &dl, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MachineBasicBlock * emitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *BB) const
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TargetBB, const DebugLoc &DL) const
void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, MachineBasicBlock *DispatchBB, int FI, int Offset) const
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
Custom Inserter {.
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Returns true if the target allows unaligned memory accesses of the specified type.
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
TargetLoweringBase::LegalizeAction getCustomOperationAction(SDNode &) const override
Custom Lower {.
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const
SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const
Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, StringRef Symbol, const DebugLoc &DL, bool IsLocal, bool IsCall) const
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
} Custom Lower
SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const
} Custom DAGCombine
SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const
const MCExpr * LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned Uid, MCContext &Ctx) const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &ArgsFlags, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const
unsigned getJumpTableEncoding() const override
JumpTable for VE.
SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, SelectionDAG &DAG) const
ConstraintType getConstraintType(StringRef Constraint) const override
Inline Assembly {.
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const
std::list< std::string > * getStrList() const
LLVM Value Representation.
Definition Value.h:75
iterator_range< user_iterator > users()
Definition Value.h:426
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h: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:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ 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:168
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ 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:264
@ 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:863
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:520
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
Definition ISDOpcodes.h:172
@ GlobalAddress
Definition ISDOpcodes.h:88
@ 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:890
@ 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:280
@ 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:89
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ 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:806
@ 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:230
@ 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:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:224
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ 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:729
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:205
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:567
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ 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:162
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ 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:843
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:536
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:558
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:58
CondCode
Definition VE.h:43
@ CC_ILE
Definition VE.h:50
@ 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
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.
constexpr RegState getKillRegState(bool B)
static bool isIntVECondCode(VECC::CondCode CC)
Definition VE.h:151
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h: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:407
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:144
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:376
static VECC::CondCode intCondCode2Icc(ISD::CondCode CC)
Convert a DAG integer condition code to a VE ICC condition.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h: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:332
static bool isMImm32Val(uint32_t Val)
Definition VE.h:345
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:155
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
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:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
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