LLVM 22.0.0git
HexagonISelLowering.cpp
Go to the documentation of this file.
1//===-- HexagonISelLowering.cpp - Hexagon 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 Hexagon uses to lower LLVM code
10// into a selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "HexagonISelLowering.h"
15#include "Hexagon.h"
17#include "HexagonRegisterInfo.h"
18#include "HexagonSubtarget.h"
21#include "llvm/ADT/APInt.h"
22#include "llvm/ADT/ArrayRef.h"
33#include "llvm/IR/BasicBlock.h"
34#include "llvm/IR/CallingConv.h"
35#include "llvm/IR/DataLayout.h"
39#include "llvm/IR/Function.h"
40#include "llvm/IR/GlobalValue.h"
41#include "llvm/IR/IRBuilder.h"
42#include "llvm/IR/InlineAsm.h"
45#include "llvm/IR/Intrinsics.h"
46#include "llvm/IR/IntrinsicsHexagon.h"
47#include "llvm/IR/Module.h"
48#include "llvm/IR/Type.h"
49#include "llvm/IR/Value.h"
53#include "llvm/Support/Debug.h"
58#include <algorithm>
59#include <cassert>
60#include <cstdint>
61#include <limits>
62#include <utility>
63
64using namespace llvm;
65
66#define DEBUG_TYPE "hexagon-lowering"
67
68static cl::opt<bool> EmitJumpTables("hexagon-emit-jump-tables",
69 cl::init(true), cl::Hidden,
70 cl::desc("Control jump table emission on Hexagon target"));
71
72static cl::opt<bool>
73 EnableHexSDNodeSched("enable-hexagon-sdnode-sched", cl::Hidden,
74 cl::desc("Enable Hexagon SDNode scheduling"));
75
76static cl::opt<int> MinimumJumpTables("minimum-jump-tables", cl::Hidden,
77 cl::init(5),
78 cl::desc("Set minimum jump tables"));
79
80static cl::opt<int>
81 MaxStoresPerMemcpyCL("max-store-memcpy", cl::Hidden, cl::init(6),
82 cl::desc("Max #stores to inline memcpy"));
83
84static cl::opt<int>
86 cl::desc("Max #stores to inline memcpy"));
87
88static cl::opt<int>
89 MaxStoresPerMemmoveCL("max-store-memmove", cl::Hidden, cl::init(6),
90 cl::desc("Max #stores to inline memmove"));
91
92static cl::opt<int>
94 cl::init(4),
95 cl::desc("Max #stores to inline memmove"));
96
97static cl::opt<int>
98 MaxStoresPerMemsetCL("max-store-memset", cl::Hidden, cl::init(8),
99 cl::desc("Max #stores to inline memset"));
100
101static cl::opt<int>
103 cl::desc("Max #stores to inline memset"));
104
105static cl::opt<bool>
106 ConstantLoadsToImm("constant-loads-to-imm", cl::Hidden, cl::init(true),
107 cl::desc("Convert constant loads to immediate values."));
108
109static cl::opt<bool> AlignLoads("hexagon-align-loads",
110 cl::Hidden, cl::init(false),
111 cl::desc("Rewrite unaligned loads as a pair of aligned loads"));
112
113static cl::opt<bool>
114 DisableArgsMinAlignment("hexagon-disable-args-min-alignment", cl::Hidden,
115 cl::init(false),
116 cl::desc("Disable minimum alignment of 1 for "
117 "arguments passed by value on stack"));
118
119// Implement calling convention for Hexagon.
120
121static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
122 CCValAssign::LocInfo &LocInfo,
123 ISD::ArgFlagsTy &ArgFlags, CCState &State) {
124 static const MCPhysReg ArgRegs[] = {
125 Hexagon::R0, Hexagon::R1, Hexagon::R2,
126 Hexagon::R3, Hexagon::R4, Hexagon::R5
127 };
128 const unsigned NumArgRegs = std::size(ArgRegs);
129 unsigned RegNum = State.getFirstUnallocated(ArgRegs);
130
131 // RegNum is an index into ArgRegs: skip a register if RegNum is odd.
132 if (RegNum != NumArgRegs && RegNum % 2 == 1)
133 State.AllocateReg(ArgRegs[RegNum]);
134
135 // Always return false here, as this function only makes sure that the first
136 // unallocated register has an even register number and does not actually
137 // allocate a register for the current argument.
138 return false;
139}
140
141#include "HexagonGenCallingConv.inc"
142
144 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
145 unsigned &NumIntermediates, MVT &RegisterVT) const {
146
147 bool isBoolVector = VT.getVectorElementType() == MVT::i1;
148 bool isPowerOf2 = VT.isPow2VectorType();
149 unsigned NumElts = VT.getVectorNumElements();
150
151 // Split vectors of type vXi1 into (X/8) vectors of type v8i1,
152 // where X is divisible by 8.
153 if (isBoolVector && !Subtarget.useHVXOps() && isPowerOf2 && NumElts >= 8) {
154 RegisterVT = MVT::v8i8;
155 IntermediateVT = MVT::v8i1;
156 NumIntermediates = NumElts / 8;
157 return NumIntermediates;
158 }
159
160 // In HVX 64-byte mode, vectors of type vXi1 are split into (X / 64) vectors
161 // of type v64i1, provided that X is divisible by 64.
162 if (isBoolVector && Subtarget.useHVX64BOps() && isPowerOf2 && NumElts >= 64) {
163 RegisterVT = MVT::v64i8;
164 IntermediateVT = MVT::v64i1;
165 NumIntermediates = NumElts / 64;
166 return NumIntermediates;
167 }
168
169 // In HVX 128-byte mode, vectors of type vXi1 are split into (X / 128) vectors
170 // of type v128i1, provided that X is divisible by 128.
171 if (isBoolVector && Subtarget.useHVX128BOps() && isPowerOf2 &&
172 NumElts >= 128) {
173 RegisterVT = MVT::v128i8;
174 IntermediateVT = MVT::v128i1;
175 NumIntermediates = NumElts / 128;
176 return NumIntermediates;
177 }
178
180 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
181}
182
183std::pair<MVT, unsigned>
185 const HexagonSubtarget &Subtarget, EVT VT) const {
186 assert(VT.getVectorElementType() == MVT::i1);
187
188 const unsigned NumElems = VT.getVectorNumElements();
189
190 if (!VT.isPow2VectorType())
192
193 if (!Subtarget.useHVXOps() && NumElems >= 8)
194 return {MVT::v8i8, NumElems / 8};
195
196 if (Subtarget.useHVX64BOps() && NumElems >= 64)
197 return {MVT::v64i8, NumElems / 64};
198
199 if (Subtarget.useHVX128BOps() && NumElems >= 128)
200 return {MVT::v128i8, NumElems / 128};
201
203}
204
207 EVT VT) const {
208
209 if (VT.isVector() && VT.getVectorElementType() == MVT::i1) {
210 auto [RegisterVT, NumRegisters] =
212 if (RegisterVT != MVT::INVALID_SIMPLE_VALUE_TYPE)
213 return RegisterVT;
214 }
215
217}
218
221 const {
222 unsigned IntNo = Op.getConstantOperandVal(0);
223 SDLoc dl(Op);
224 switch (IntNo) {
225 default:
226 return SDValue(); // Don't custom lower most intrinsics.
227 case Intrinsic::thread_pointer: {
228 EVT PtrVT = getPointerTy(DAG.getDataLayout());
229 return DAG.getNode(HexagonISD::THREAD_POINTER, dl, PtrVT);
230 }
231 }
232}
233
234/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
235/// by "Src" to address "Dst" of size "Size". Alignment information is
236/// specified by the specific parameter attribute. The copy will be passed as
237/// a byval function parameter. Sometimes what we are copying is the end of a
238/// larger object, the part that does not fit in registers.
240 SDValue Chain, ISD::ArgFlagsTy Flags,
241 SelectionDAG &DAG, const SDLoc &dl) {
242 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
243 return DAG.getMemcpy(
244 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
245 /*isVolatile=*/false, /*AlwaysInline=*/false,
246 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());
247}
248
249bool
251 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
253 LLVMContext &Context, const Type *RetTy) const {
255 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
256
258 return CCInfo.CheckReturn(Outs, RetCC_Hexagon_HVX);
259 return CCInfo.CheckReturn(Outs, RetCC_Hexagon);
260}
261
262// LowerReturn - Lower ISD::RET. If a struct is larger than 8 bytes and is
263// passed by value, the function prototype is modified to return void and
264// the value is stored in memory pointed by a pointer passed by caller.
267 bool IsVarArg,
269 const SmallVectorImpl<SDValue> &OutVals,
270 const SDLoc &dl, SelectionDAG &DAG) const {
271 // CCValAssign - represent the assignment of the return value to locations.
273
274 // CCState - Info about the registers and stack slot.
275 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
276 *DAG.getContext());
277
278 // Analyze return values of ISD::RET
279 if (Subtarget.useHVXOps())
280 CCInfo.AnalyzeReturn(Outs, RetCC_Hexagon_HVX);
281 else
282 CCInfo.AnalyzeReturn(Outs, RetCC_Hexagon);
283
284 SDValue Glue;
285 SmallVector<SDValue, 4> RetOps(1, Chain);
286
287 // Copy the result values into the output registers.
288 for (unsigned i = 0; i != RVLocs.size(); ++i) {
289 CCValAssign &VA = RVLocs[i];
290 SDValue Val = OutVals[i];
291
292 switch (VA.getLocInfo()) {
293 default:
294 // Loc info must be one of Full, BCvt, SExt, ZExt, or AExt.
295 llvm_unreachable("Unknown loc info!");
297 break;
299 Val = DAG.getBitcast(VA.getLocVT(), Val);
300 break;
302 Val = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Val);
303 break;
305 Val = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Val);
306 break;
308 Val = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Val);
309 break;
310 }
311
312 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Val, Glue);
313
314 // Guarantee that all emitted copies are stuck together with flags.
315 Glue = Chain.getValue(1);
316 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
317 }
318
319 RetOps[0] = Chain; // Update chain.
320
321 // Add the glue if we have it.
322 if (Glue.getNode())
323 RetOps.push_back(Glue);
324
325 return DAG.getNode(HexagonISD::RET_GLUE, dl, MVT::Other, RetOps);
326}
327
329 // If either no tail call or told not to tail call at all, don't.
330 return CI->isTailCall();
331}
332
334 const char* RegName, LLT VT, const MachineFunction &) const {
335 // Just support r19, the linux kernel uses it.
337 .Case("r0", Hexagon::R0)
338 .Case("r1", Hexagon::R1)
339 .Case("r2", Hexagon::R2)
340 .Case("r3", Hexagon::R3)
341 .Case("r4", Hexagon::R4)
342 .Case("r5", Hexagon::R5)
343 .Case("r6", Hexagon::R6)
344 .Case("r7", Hexagon::R7)
345 .Case("r8", Hexagon::R8)
346 .Case("r9", Hexagon::R9)
347 .Case("r10", Hexagon::R10)
348 .Case("r11", Hexagon::R11)
349 .Case("r12", Hexagon::R12)
350 .Case("r13", Hexagon::R13)
351 .Case("r14", Hexagon::R14)
352 .Case("r15", Hexagon::R15)
353 .Case("r16", Hexagon::R16)
354 .Case("r17", Hexagon::R17)
355 .Case("r18", Hexagon::R18)
356 .Case("r19", Hexagon::R19)
357 .Case("r20", Hexagon::R20)
358 .Case("r21", Hexagon::R21)
359 .Case("r22", Hexagon::R22)
360 .Case("r23", Hexagon::R23)
361 .Case("r24", Hexagon::R24)
362 .Case("r25", Hexagon::R25)
363 .Case("r26", Hexagon::R26)
364 .Case("r27", Hexagon::R27)
365 .Case("r28", Hexagon::R28)
366 .Case("r29", Hexagon::R29)
367 .Case("r30", Hexagon::R30)
368 .Case("r31", Hexagon::R31)
369 .Case("r1:0", Hexagon::D0)
370 .Case("r3:2", Hexagon::D1)
371 .Case("r5:4", Hexagon::D2)
372 .Case("r7:6", Hexagon::D3)
373 .Case("r9:8", Hexagon::D4)
374 .Case("r11:10", Hexagon::D5)
375 .Case("r13:12", Hexagon::D6)
376 .Case("r15:14", Hexagon::D7)
377 .Case("r17:16", Hexagon::D8)
378 .Case("r19:18", Hexagon::D9)
379 .Case("r21:20", Hexagon::D10)
380 .Case("r23:22", Hexagon::D11)
381 .Case("r25:24", Hexagon::D12)
382 .Case("r27:26", Hexagon::D13)
383 .Case("r29:28", Hexagon::D14)
384 .Case("r31:30", Hexagon::D15)
385 .Case("sp", Hexagon::R29)
386 .Case("fp", Hexagon::R30)
387 .Case("lr", Hexagon::R31)
388 .Case("p0", Hexagon::P0)
389 .Case("p1", Hexagon::P1)
390 .Case("p2", Hexagon::P2)
391 .Case("p3", Hexagon::P3)
392 .Case("sa0", Hexagon::SA0)
393 .Case("lc0", Hexagon::LC0)
394 .Case("sa1", Hexagon::SA1)
395 .Case("lc1", Hexagon::LC1)
396 .Case("m0", Hexagon::M0)
397 .Case("m1", Hexagon::M1)
398 .Case("usr", Hexagon::USR)
399 .Case("ugp", Hexagon::UGP)
400 .Case("cs0", Hexagon::CS0)
401 .Case("cs1", Hexagon::CS1)
402 .Default(Register());
403 return Reg;
404}
405
406/// LowerCallResult - Lower the result values of an ISD::CALL into the
407/// appropriate copies out of appropriate physical registers. This assumes that
408/// Chain/Glue are the input chain/glue to use, and that TheCall is the call
409/// being lowered. Returns a SDNode with the same number of values as the
410/// ISD::CALL.
412 SDValue Chain, SDValue Glue, CallingConv::ID CallConv, bool IsVarArg,
413 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
415 const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const {
416 // Assign locations to each value returned by this call.
418
419 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
420 *DAG.getContext());
421
422 if (Subtarget.useHVXOps())
423 CCInfo.AnalyzeCallResult(Ins, RetCC_Hexagon_HVX);
424 else
425 CCInfo.AnalyzeCallResult(Ins, RetCC_Hexagon);
426
427 // Copy all of the result registers out of their specified physreg.
428 for (unsigned i = 0; i != RVLocs.size(); ++i) {
429 SDValue RetVal;
430 if (RVLocs[i].getValVT() == MVT::i1) {
431 // Return values of type MVT::i1 require special handling. The reason
432 // is that MVT::i1 is associated with the PredRegs register class, but
433 // values of that type are still returned in R0. Generate an explicit
434 // copy into a predicate register from R0, and treat the value of the
435 // predicate register as the call result.
436 auto &MRI = DAG.getMachineFunction().getRegInfo();
437 SDValue FR0 = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
438 MVT::i32, Glue);
439 // FR0 = (Value, Chain, Glue)
440 Register PredR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
441 SDValue TPR = DAG.getCopyToReg(FR0.getValue(1), dl, PredR,
442 FR0.getValue(0), FR0.getValue(2));
443 // TPR = (Chain, Glue)
444 // Don't glue this CopyFromReg, because it copies from a virtual
445 // register. If it is glued to the call, InstrEmitter will add it
446 // as an implicit def to the call (EmitMachineNode).
447 RetVal = DAG.getCopyFromReg(TPR.getValue(0), dl, PredR, MVT::i1);
448 Glue = TPR.getValue(1);
449 Chain = TPR.getValue(0);
450 } else {
451 RetVal = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
452 RVLocs[i].getValVT(), Glue);
453 Glue = RetVal.getValue(2);
454 Chain = RetVal.getValue(1);
455 }
456 InVals.push_back(RetVal.getValue(0));
457 }
458
459 return Chain;
460}
461
462/// LowerCall - Functions arguments are copied from virtual regs to
463/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
466 SmallVectorImpl<SDValue> &InVals) const {
467 SelectionDAG &DAG = CLI.DAG;
468 SDLoc &dl = CLI.DL;
470 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
472 SDValue Chain = CLI.Chain;
473 SDValue Callee = CLI.Callee;
474 CallingConv::ID CallConv = CLI.CallConv;
475 bool IsVarArg = CLI.IsVarArg;
476 bool DoesNotReturn = CLI.DoesNotReturn;
477
478 bool IsStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
480 MachineFrameInfo &MFI = MF.getFrameInfo();
481 auto PtrVT = getPointerTy(MF.getDataLayout());
482
483 if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Callee))
484 Callee = DAG.getTargetGlobalAddress(GAN->getGlobal(), dl, MVT::i32);
485
486 // Linux ABI treats var-arg calls the same way as regular ones.
487 bool TreatAsVarArg = !Subtarget.isEnvironmentMusl() && IsVarArg;
488
489 // Analyze operands of the call, assigning locations to each operand.
491 CCState CCInfo(CallConv, TreatAsVarArg, MF, ArgLocs, *DAG.getContext());
492
493 if (Subtarget.useHVXOps())
494 CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_HVX);
496 CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_Legacy);
497 else
498 CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon);
499
500 if (CLI.IsTailCall) {
501 bool StructAttrFlag = MF.getFunction().hasStructRetAttr();
502 CLI.IsTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
503 IsVarArg, IsStructRet, StructAttrFlag, Outs,
504 OutVals, Ins, DAG);
505 for (const CCValAssign &VA : ArgLocs) {
506 if (VA.isMemLoc()) {
507 CLI.IsTailCall = false;
508 break;
509 }
510 }
511 LLVM_DEBUG(dbgs() << (CLI.IsTailCall ? "Eligible for Tail Call\n"
512 : "Argument must be passed on stack. "
513 "Not eligible for Tail Call\n"));
514 }
515 // Get a count of how many bytes are to be pushed on the stack.
516 unsigned NumBytes = CCInfo.getStackSize();
518 SmallVector<SDValue, 8> MemOpChains;
519
520 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
521 SDValue StackPtr =
522 DAG.getCopyFromReg(Chain, dl, HRI.getStackRegister(), PtrVT);
523
524 bool NeedsArgAlign = false;
525 Align LargestAlignSeen;
526 // Walk the register/memloc assignments, inserting copies/loads.
527 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
528 CCValAssign &VA = ArgLocs[i];
529 SDValue Arg = OutVals[i];
530 ISD::ArgFlagsTy Flags = Outs[i].Flags;
531 // Record if we need > 8 byte alignment on an argument.
532 bool ArgAlign = Subtarget.isHVXVectorType(VA.getValVT());
533 NeedsArgAlign |= ArgAlign;
534
535 // Promote the value if needed.
536 switch (VA.getLocInfo()) {
537 default:
538 // Loc info must be one of Full, BCvt, SExt, ZExt, or AExt.
539 llvm_unreachable("Unknown loc info!");
541 break;
543 Arg = DAG.getBitcast(VA.getLocVT(), Arg);
544 break;
546 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
547 break;
549 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
550 break;
552 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
553 break;
554 }
555
556 if (VA.isMemLoc()) {
557 unsigned LocMemOffset = VA.getLocMemOffset();
558 SDValue MemAddr = DAG.getConstant(LocMemOffset, dl,
559 StackPtr.getValueType());
560 MemAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, MemAddr);
561 if (ArgAlign)
562 LargestAlignSeen = std::max(
563 LargestAlignSeen, Align(VA.getLocVT().getStoreSizeInBits() / 8));
564 if (Flags.isByVal()) {
565 // The argument is a struct passed by value. According to LLVM, "Arg"
566 // is a pointer.
567 MemOpChains.push_back(CreateCopyOfByValArgument(Arg, MemAddr, Chain,
568 Flags, DAG, dl));
569 } else {
571 DAG.getMachineFunction(), LocMemOffset);
572 SDValue S = DAG.getStore(Chain, dl, Arg, MemAddr, LocPI);
573 MemOpChains.push_back(S);
574 }
575 continue;
576 }
577
578 // Arguments that can be passed on register must be kept at RegsToPass
579 // vector.
580 if (VA.isRegLoc())
581 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
582 }
583
584 if (NeedsArgAlign && Subtarget.hasV60Ops()) {
585 LLVM_DEBUG(dbgs() << "Function needs byte stack align due to call args\n");
586 Align VecAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
587 LargestAlignSeen = std::max(LargestAlignSeen, VecAlign);
588 MFI.ensureMaxAlignment(LargestAlignSeen);
589 }
590 // Transform all store nodes into one single node because all store
591 // nodes are independent of each other.
592 if (!MemOpChains.empty())
593 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
594
595 SDValue Glue;
596 if (!CLI.IsTailCall) {
597 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
598 Glue = Chain.getValue(1);
599 }
600
601 // Build a sequence of copy-to-reg nodes chained together with token
602 // chain and flag operands which copy the outgoing args into registers.
603 // The Glue is necessary since all emitted instructions must be
604 // stuck together.
605 if (!CLI.IsTailCall) {
606 for (const auto &R : RegsToPass) {
607 Chain = DAG.getCopyToReg(Chain, dl, R.first, R.second, Glue);
608 Glue = Chain.getValue(1);
609 }
610 } else {
611 // For tail calls lower the arguments to the 'real' stack slot.
612 //
613 // Force all the incoming stack arguments to be loaded from the stack
614 // before any new outgoing arguments are stored to the stack, because the
615 // outgoing stack slots may alias the incoming argument stack slots, and
616 // the alias isn't otherwise explicit. This is slightly more conservative
617 // than necessary, because it means that each store effectively depends
618 // on every argument instead of just those arguments it would clobber.
619 //
620 // Do not flag preceding copytoreg stuff together with the following stuff.
621 Glue = SDValue();
622 for (const auto &R : RegsToPass) {
623 Chain = DAG.getCopyToReg(Chain, dl, R.first, R.second, Glue);
624 Glue = Chain.getValue(1);
625 }
626 Glue = SDValue();
627 }
628
629 bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls();
630 unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0;
631
632 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
633 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
634 // node so that legalize doesn't hack it.
635 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
636 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, PtrVT, 0, Flags);
637 } else if (ExternalSymbolSDNode *S =
638 dyn_cast<ExternalSymbolSDNode>(Callee)) {
639 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, Flags);
640 }
641
642 // Returns a chain & a flag for retval copy to use.
644 Ops.push_back(Chain);
645 Ops.push_back(Callee);
646
647 // Add argument registers to the end of the list so that they are
648 // known live into the call.
649 for (const auto &R : RegsToPass)
650 Ops.push_back(DAG.getRegister(R.first, R.second.getValueType()));
651
652 const uint32_t *Mask = HRI.getCallPreservedMask(MF, CallConv);
653 assert(Mask && "Missing call preserved mask for calling convention");
654 Ops.push_back(DAG.getRegisterMask(Mask));
655
656 if (Glue.getNode())
657 Ops.push_back(Glue);
658
659 if (CLI.IsTailCall) {
660 MFI.setHasTailCall();
661 return DAG.getNode(HexagonISD::TC_RETURN, dl, MVT::Other, Ops);
662 }
663
664 // Set this here because we need to know this for "hasFP" in frame lowering.
665 // The target-independent code calls getFrameRegister before setting it, and
666 // getFrameRegister uses hasFP to determine whether the function has FP.
667 MFI.setHasCalls(true);
668
669 unsigned OpCode = DoesNotReturn ? HexagonISD::CALLnr : HexagonISD::CALL;
670 Chain = DAG.getNode(OpCode, dl, {MVT::Other, MVT::Glue}, Ops);
671 Glue = Chain.getValue(1);
672
673 // Create the CALLSEQ_END node.
674 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, dl);
675 Glue = Chain.getValue(1);
676
677 // Handle result values, copying them out of physregs into vregs that we
678 // return.
679 return LowerCallResult(Chain, Glue, CallConv, IsVarArg, Ins, dl, DAG,
680 InVals, OutVals, Callee);
681}
682
683/// Returns true by value, base pointer and offset pointer and addressing
684/// mode by reference if this node can be combined with a load / store to
685/// form a post-indexed load / store.
688 SelectionDAG &DAG) const {
689 LSBaseSDNode *LSN = dyn_cast<LSBaseSDNode>(N);
690 if (!LSN)
691 return false;
692 EVT VT = LSN->getMemoryVT();
693 if (!VT.isSimple())
694 return false;
695 bool IsLegalType = VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 ||
696 VT == MVT::i64 || VT == MVT::f32 || VT == MVT::f64 ||
697 VT == MVT::v2i16 || VT == MVT::v2i32 || VT == MVT::v4i8 ||
698 VT == MVT::v4i16 || VT == MVT::v8i8 ||
699 Subtarget.isHVXVectorType(VT.getSimpleVT());
700 if (!IsLegalType)
701 return false;
702
703 if (Op->getOpcode() != ISD::ADD)
704 return false;
705 Base = Op->getOperand(0);
706 Offset = Op->getOperand(1);
707 if (!isa<ConstantSDNode>(Offset.getNode()))
708 return false;
709 AM = ISD::POST_INC;
710
711 int32_t V = cast<ConstantSDNode>(Offset.getNode())->getSExtValue();
712 return Subtarget.getInstrInfo()->isValidAutoIncImm(VT, V);
713}
714
717 return SDValue();
718 else
719 return Op;
720}
721
725 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
726 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
727 unsigned LR = HRI.getRARegister();
728
729 if ((Op.getOpcode() != ISD::INLINEASM &&
730 Op.getOpcode() != ISD::INLINEASM_BR) || HMFI.hasClobberLR())
731 return Op;
732
733 unsigned NumOps = Op.getNumOperands();
734 if (Op.getOperand(NumOps-1).getValueType() == MVT::Glue)
735 --NumOps; // Ignore the flag operand.
736
737 for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
738 const InlineAsm::Flag Flags(Op.getConstantOperandVal(i));
739 unsigned NumVals = Flags.getNumOperandRegisters();
740 ++i; // Skip the ID value.
741
742 switch (Flags.getKind()) {
743 default:
744 llvm_unreachable("Bad flags!");
748 i += NumVals;
749 break;
753 for (; NumVals; --NumVals, ++i) {
754 Register Reg = cast<RegisterSDNode>(Op.getOperand(i))->getReg();
755 if (Reg != LR)
756 continue;
757 HMFI.setHasClobberLR(true);
758 return Op;
759 }
760 break;
761 }
762 }
763 }
764
765 return Op;
766}
767
768// Need to transform ISD::PREFETCH into something that doesn't inherit
769// all of the properties of ISD::PREFETCH, specifically SDNPMayLoad and
770// SDNPMayStore.
772 SelectionDAG &DAG) const {
773 SDValue Chain = Op.getOperand(0);
774 SDValue Addr = Op.getOperand(1);
775 // Lower it to DCFETCH($reg, #0). A "pat" will try to merge the offset in,
776 // if the "reg" is fed by an "add".
777 SDLoc DL(Op);
778 SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
779 return DAG.getNode(HexagonISD::DCFETCH, DL, MVT::Other, Chain, Addr, Zero);
780}
781
782// Custom-handle ISD::READCYCLECOUNTER because the target-independent SDNode
783// is marked as having side-effects, while the register read on Hexagon does
784// not have any. TableGen refuses to accept the direct pattern from that node
785// to the A4_tfrcpp.
787 SelectionDAG &DAG) const {
788 SDValue Chain = Op.getOperand(0);
789 SDLoc dl(Op);
790 SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Other);
791 return DAG.getNode(HexagonISD::READCYCLE, dl, VTs, Chain);
792}
793
794// Custom-handle ISD::READSTEADYCOUNTER because the target-independent SDNode
795// is marked as having side-effects, while the register read on Hexagon does
796// not have any. TableGen refuses to accept the direct pattern from that node
797// to the A4_tfrcpp.
799 SelectionDAG &DAG) const {
800 SDValue Chain = Op.getOperand(0);
801 SDLoc dl(Op);
802 SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Other);
803 return DAG.getNode(HexagonISD::READTIMER, dl, VTs, Chain);
804}
805
807 SelectionDAG &DAG) const {
808 SDValue Chain = Op.getOperand(0);
809 unsigned IntNo = Op.getConstantOperandVal(1);
810 // Lower the hexagon_prefetch builtin to DCFETCH, as above.
811 if (IntNo == Intrinsic::hexagon_prefetch) {
812 SDValue Addr = Op.getOperand(2);
813 SDLoc DL(Op);
814 SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
815 return DAG.getNode(HexagonISD::DCFETCH, DL, MVT::Other, Chain, Addr, Zero);
816 }
817 return SDValue();
818}
819
822 SelectionDAG &DAG) const {
823 SDValue Chain = Op.getOperand(0);
824 SDValue Size = Op.getOperand(1);
825 SDValue Align = Op.getOperand(2);
826 SDLoc dl(Op);
827
828 ConstantSDNode *AlignConst = dyn_cast<ConstantSDNode>(Align);
829 assert(AlignConst && "Non-constant Align in LowerDYNAMIC_STACKALLOC");
830
831 unsigned A = AlignConst->getSExtValue();
832 auto &HFI = *Subtarget.getFrameLowering();
833 // "Zero" means natural stack alignment.
834 if (A == 0)
835 A = HFI.getStackAlign().value();
836
837 LLVM_DEBUG({
838 dbgs () << __func__ << " Align: " << A << " Size: ";
839 Size.getNode()->dump(&DAG);
840 dbgs() << "\n";
841 });
842
843 SDValue AC = DAG.getConstant(A, dl, MVT::i32);
844 SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
845 SDValue AA = DAG.getNode(HexagonISD::ALLOCA, dl, VTs, Chain, Size, AC);
846
848 return AA;
849}
850
852 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
853 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
854 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
856 MachineFrameInfo &MFI = MF.getFrameInfo();
858
859 // Linux ABI treats var-arg calls the same way as regular ones.
860 bool TreatAsVarArg = !Subtarget.isEnvironmentMusl() && IsVarArg;
861
862 // Assign locations to all of the incoming arguments.
864 CCState CCInfo(CallConv, TreatAsVarArg, MF, ArgLocs, *DAG.getContext());
865
866 if (Subtarget.useHVXOps())
867 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon_HVX);
869 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon_Legacy);
870 else
871 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon);
872
873 // For LLVM, in the case when returning a struct by value (>8byte),
874 // the first argument is a pointer that points to the location on caller's
875 // stack where the return value will be stored. For Hexagon, the location on
876 // caller's stack is passed only when the struct size is smaller than (and
877 // equal to) 8 bytes. If not, no address will be passed into callee and
878 // callee return the result directly through R0/R1.
879 auto NextSingleReg = [] (const TargetRegisterClass &RC, unsigned Reg) {
880 switch (RC.getID()) {
881 case Hexagon::IntRegsRegClassID:
882 return Reg - Hexagon::R0 + 1;
883 case Hexagon::DoubleRegsRegClassID:
884 return (Reg - Hexagon::D0 + 1) * 2;
885 case Hexagon::HvxVRRegClassID:
886 return Reg - Hexagon::V0 + 1;
887 case Hexagon::HvxWRRegClassID:
888 return (Reg - Hexagon::W0 + 1) * 2;
889 }
890 llvm_unreachable("Unexpected register class");
891 };
892
893 auto &HFL = const_cast<HexagonFrameLowering&>(*Subtarget.getFrameLowering());
894 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
895 HFL.FirstVarArgSavedReg = 0;
897
898 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
899 CCValAssign &VA = ArgLocs[i];
900 ISD::ArgFlagsTy Flags = Ins[i].Flags;
901 bool ByVal = Flags.isByVal();
902
903 // Arguments passed in registers:
904 // 1. 32- and 64-bit values and HVX vectors are passed directly,
905 // 2. Large structs are passed via an address, and the address is
906 // passed in a register.
907 if (VA.isRegLoc() && ByVal && Flags.getByValSize() <= 8)
908 llvm_unreachable("ByValSize must be bigger than 8 bytes");
909
910 bool InReg = VA.isRegLoc() &&
911 (!ByVal || (ByVal && Flags.getByValSize() > 8));
912
913 if (InReg) {
914 MVT RegVT = VA.getLocVT();
915 if (VA.getLocInfo() == CCValAssign::BCvt)
916 RegVT = VA.getValVT();
917
918 const TargetRegisterClass *RC = getRegClassFor(RegVT);
919 Register VReg = MRI.createVirtualRegister(RC);
920 SDValue Copy = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
921
922 // Treat values of type MVT::i1 specially: they are passed in
923 // registers of type i32, but they need to remain as values of
924 // type i1 for consistency of the argument lowering.
925 if (VA.getValVT() == MVT::i1) {
926 assert(RegVT.getSizeInBits() <= 32);
927 SDValue T = DAG.getNode(ISD::AND, dl, RegVT,
928 Copy, DAG.getConstant(1, dl, RegVT));
929 Copy = DAG.getSetCC(dl, MVT::i1, T, DAG.getConstant(0, dl, RegVT),
930 ISD::SETNE);
931 } else {
932#ifndef NDEBUG
933 unsigned RegSize = RegVT.getSizeInBits();
934 assert(RegSize == 32 || RegSize == 64 ||
935 Subtarget.isHVXVectorType(RegVT));
936#endif
937 }
938 InVals.push_back(Copy);
939 MRI.addLiveIn(VA.getLocReg(), VReg);
940 HFL.FirstVarArgSavedReg = NextSingleReg(*RC, VA.getLocReg());
941 } else {
942 assert(VA.isMemLoc() && "Argument should be passed in memory");
943
944 // If it's a byval parameter, then we need to compute the
945 // "real" size, not the size of the pointer.
946 unsigned ObjSize = Flags.isByVal()
947 ? Flags.getByValSize()
948 : VA.getLocVT().getStoreSizeInBits() / 8;
949
950 // Create the frame index object for this incoming parameter.
952 int FI = MFI.CreateFixedObject(ObjSize, Offset, true);
953 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
954
955 if (Flags.isByVal()) {
956 // If it's a pass-by-value aggregate, then do not dereference the stack
957 // location. Instead, we should generate a reference to the stack
958 // location.
959 InVals.push_back(FIN);
960 } else {
961 SDValue L = DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
963 InVals.push_back(L);
964 }
965 }
966 }
967
968 if (IsVarArg && Subtarget.isEnvironmentMusl()) {
969 for (int i = HFL.FirstVarArgSavedReg; i < 6; i++)
970 MRI.addLiveIn(Hexagon::R0+i);
971 }
972
973 if (IsVarArg && Subtarget.isEnvironmentMusl()) {
974 HMFI.setFirstNamedArgFrameIndex(HMFI.getFirstNamedArgFrameIndex() - 1);
975 HMFI.setLastNamedArgFrameIndex(-int(MFI.getNumFixedObjects()));
976
977 // Create Frame index for the start of register saved area.
978 int NumVarArgRegs = 6 - HFL.FirstVarArgSavedReg;
979 bool RequiresPadding = (NumVarArgRegs & 1);
980 int RegSaveAreaSizePlusPadding = RequiresPadding
981 ? (NumVarArgRegs + 1) * 4
982 : NumVarArgRegs * 4;
983
984 if (RegSaveAreaSizePlusPadding > 0) {
985 // The offset to saved register area should be 8 byte aligned.
986 int RegAreaStart = HEXAGON_LRFP_SIZE + CCInfo.getStackSize();
987 if (!(RegAreaStart % 8))
988 RegAreaStart = (RegAreaStart + 7) & -8;
989
990 int RegSaveAreaFrameIndex =
991 MFI.CreateFixedObject(RegSaveAreaSizePlusPadding, RegAreaStart, true);
992 HMFI.setRegSavedAreaStartFrameIndex(RegSaveAreaFrameIndex);
993
994 // This will point to the next argument passed via stack.
995 int Offset = RegAreaStart + RegSaveAreaSizePlusPadding;
996 int FI = MFI.CreateFixedObject(Hexagon_PointerSize, Offset, true);
997 HMFI.setVarArgsFrameIndex(FI);
998 } else {
999 // This will point to the next argument passed via stack, when
1000 // there is no saved register area.
1001 int Offset = HEXAGON_LRFP_SIZE + CCInfo.getStackSize();
1002 int FI = MFI.CreateFixedObject(Hexagon_PointerSize, Offset, true);
1003 HMFI.setRegSavedAreaStartFrameIndex(FI);
1004 HMFI.setVarArgsFrameIndex(FI);
1005 }
1006 }
1007
1008
1009 if (IsVarArg && !Subtarget.isEnvironmentMusl()) {
1010 // This will point to the next argument passed via stack.
1011 int Offset = HEXAGON_LRFP_SIZE + CCInfo.getStackSize();
1012 int FI = MFI.CreateFixedObject(Hexagon_PointerSize, Offset, true);
1013 HMFI.setVarArgsFrameIndex(FI);
1014 }
1015
1016 return Chain;
1017}
1018
1019SDValue
1021 // VASTART stores the address of the VarArgsFrameIndex slot into the
1022 // memory location argument.
1025 SDValue Addr = DAG.getFrameIndex(QFI->getVarArgsFrameIndex(), MVT::i32);
1026 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1027
1028 if (!Subtarget.isEnvironmentMusl()) {
1029 return DAG.getStore(Op.getOperand(0), SDLoc(Op), Addr, Op.getOperand(1),
1030 MachinePointerInfo(SV));
1031 }
1032 auto &FuncInfo = *MF.getInfo<HexagonMachineFunctionInfo>();
1033 auto &HFL = *Subtarget.getFrameLowering();
1034 SDLoc DL(Op);
1036
1037 // Get frame index of va_list.
1038 SDValue FIN = Op.getOperand(1);
1039
1040 // If first Vararg register is odd, add 4 bytes to start of
1041 // saved register area to point to the first register location.
1042 // This is because the saved register area has to be 8 byte aligned.
1043 // In case of an odd start register, there will be 4 bytes of padding in
1044 // the beginning of saved register area. If all registers area used up,
1045 // the following condition will handle it correctly.
1046 SDValue SavedRegAreaStartFrameIndex =
1047 DAG.getFrameIndex(FuncInfo.getRegSavedAreaStartFrameIndex(), MVT::i32);
1048
1049 auto PtrVT = getPointerTy(DAG.getDataLayout());
1050
1051 if (HFL.FirstVarArgSavedReg & 1)
1052 SavedRegAreaStartFrameIndex =
1053 DAG.getNode(ISD::ADD, DL, PtrVT,
1054 DAG.getFrameIndex(FuncInfo.getRegSavedAreaStartFrameIndex(),
1055 MVT::i32),
1056 DAG.getIntPtrConstant(4, DL));
1057
1058 // Store the saved register area start pointer.
1059 SDValue Store =
1060 DAG.getStore(Op.getOperand(0), DL,
1061 SavedRegAreaStartFrameIndex,
1062 FIN, MachinePointerInfo(SV));
1063 MemOps.push_back(Store);
1064
1065 // Store saved register area end pointer.
1066 FIN = DAG.getNode(ISD::ADD, DL, PtrVT,
1067 FIN, DAG.getIntPtrConstant(4, DL));
1068 Store = DAG.getStore(Op.getOperand(0), DL,
1069 DAG.getFrameIndex(FuncInfo.getVarArgsFrameIndex(),
1070 PtrVT),
1071 FIN, MachinePointerInfo(SV, 4));
1072 MemOps.push_back(Store);
1073
1074 // Store overflow area pointer.
1075 FIN = DAG.getNode(ISD::ADD, DL, PtrVT,
1076 FIN, DAG.getIntPtrConstant(4, DL));
1077 Store = DAG.getStore(Op.getOperand(0), DL,
1078 DAG.getFrameIndex(FuncInfo.getVarArgsFrameIndex(),
1079 PtrVT),
1080 FIN, MachinePointerInfo(SV, 8));
1081 MemOps.push_back(Store);
1082
1083 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
1084}
1085
1086SDValue
1088 // Assert that the linux ABI is enabled for the current compilation.
1089 assert(Subtarget.isEnvironmentMusl() && "Linux ABI should be enabled");
1090 SDValue Chain = Op.getOperand(0);
1091 SDValue DestPtr = Op.getOperand(1);
1092 SDValue SrcPtr = Op.getOperand(2);
1093 const Value *DestSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
1094 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
1095 SDLoc DL(Op);
1096 // Size of the va_list is 12 bytes as it has 3 pointers. Therefore,
1097 // we need to memcopy 12 bytes from va_list to another similar list.
1098 return DAG.getMemcpy(
1099 Chain, DL, DestPtr, SrcPtr, DAG.getIntPtrConstant(12, DL), Align(4),
1100 /*isVolatile*/ false, false, /*CI=*/nullptr, std::nullopt,
1101 MachinePointerInfo(DestSV), MachinePointerInfo(SrcSV));
1102}
1103
1105 const SDLoc &dl(Op);
1106 SDValue LHS = Op.getOperand(0);
1107 SDValue RHS = Op.getOperand(1);
1108 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
1109 MVT ResTy = ty(Op);
1110 MVT OpTy = ty(LHS);
1111
1112 if (OpTy == MVT::v2i16 || OpTy == MVT::v4i8) {
1113 MVT ElemTy = OpTy.getVectorElementType();
1114 assert(ElemTy.isScalarInteger());
1116 OpTy.getVectorNumElements());
1117 return DAG.getSetCC(dl, ResTy,
1118 DAG.getSExtOrTrunc(LHS, SDLoc(LHS), WideTy),
1119 DAG.getSExtOrTrunc(RHS, SDLoc(RHS), WideTy), CC);
1120 }
1121
1122 // Treat all other vector types as legal.
1123 if (ResTy.isVector())
1124 return Op;
1125
1126 // Comparisons of short integers should use sign-extend, not zero-extend,
1127 // since we can represent small negative values in the compare instructions.
1128 // The LLVM default is to use zero-extend arbitrarily in these cases.
1129 auto isSExtFree = [this](SDValue N) {
1130 switch (N.getOpcode()) {
1131 case ISD::TRUNCATE: {
1132 // A sign-extend of a truncate of a sign-extend is free.
1133 SDValue Op = N.getOperand(0);
1134 if (Op.getOpcode() != ISD::AssertSext)
1135 return false;
1136 EVT OrigTy = cast<VTSDNode>(Op.getOperand(1))->getVT();
1137 unsigned ThisBW = ty(N).getSizeInBits();
1138 unsigned OrigBW = OrigTy.getSizeInBits();
1139 // The type that was sign-extended to get the AssertSext must be
1140 // narrower than the type of N (so that N has still the same value
1141 // as the original).
1142 return ThisBW >= OrigBW;
1143 }
1144 case ISD::LOAD:
1145 // We have sign-extended loads.
1146 return true;
1147 }
1148 return false;
1149 };
1150
1151 if (OpTy == MVT::i8 || OpTy == MVT::i16) {
1152 ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS);
1153 bool IsNegative = C && C->getAPIntValue().isNegative();
1154 if (IsNegative || isSExtFree(LHS) || isSExtFree(RHS))
1155 return DAG.getSetCC(dl, ResTy,
1156 DAG.getSExtOrTrunc(LHS, SDLoc(LHS), MVT::i32),
1157 DAG.getSExtOrTrunc(RHS, SDLoc(RHS), MVT::i32), CC);
1158 }
1159
1160 return SDValue();
1161}
1162
1163SDValue
1165 SDValue PredOp = Op.getOperand(0);
1166 SDValue Op1 = Op.getOperand(1), Op2 = Op.getOperand(2);
1167 MVT OpTy = ty(Op1);
1168 const SDLoc &dl(Op);
1169
1170 if (OpTy == MVT::v2i16 || OpTy == MVT::v4i8) {
1171 MVT ElemTy = OpTy.getVectorElementType();
1172 assert(ElemTy.isScalarInteger());
1174 OpTy.getVectorNumElements());
1175 // Generate (trunc (select (_, sext, sext))).
1176 return DAG.getSExtOrTrunc(
1177 DAG.getSelect(dl, WideTy, PredOp,
1178 DAG.getSExtOrTrunc(Op1, dl, WideTy),
1179 DAG.getSExtOrTrunc(Op2, dl, WideTy)),
1180 dl, OpTy);
1181 }
1182
1183 return SDValue();
1184}
1185
1186SDValue
1188 EVT ValTy = Op.getValueType();
1189 ConstantPoolSDNode *CPN = cast<ConstantPoolSDNode>(Op);
1190 Constant *CVal = nullptr;
1191 bool isVTi1Type = false;
1192 if (auto *CV = dyn_cast<ConstantVector>(CPN->getConstVal())) {
1193 if (cast<VectorType>(CV->getType())->getElementType()->isIntegerTy(1)) {
1194 IRBuilder<> IRB(CV->getContext());
1196 unsigned VecLen = CV->getNumOperands();
1197 assert(isPowerOf2_32(VecLen) &&
1198 "conversion only supported for pow2 VectorSize");
1199 for (unsigned i = 0; i < VecLen; ++i)
1200 NewConst.push_back(IRB.getInt8(CV->getOperand(i)->isZeroValue()));
1201
1202 CVal = ConstantVector::get(NewConst);
1203 isVTi1Type = true;
1204 }
1205 }
1206 Align Alignment = CPN->getAlign();
1207 bool IsPositionIndependent = isPositionIndependent();
1208 unsigned char TF = IsPositionIndependent ? HexagonII::MO_PCREL : 0;
1209
1210 unsigned Offset = 0;
1211 SDValue T;
1212 if (CPN->isMachineConstantPoolEntry())
1213 T = DAG.getTargetConstantPool(CPN->getMachineCPVal(), ValTy, Alignment,
1214 Offset, TF);
1215 else if (isVTi1Type)
1216 T = DAG.getTargetConstantPool(CVal, ValTy, Alignment, Offset, TF);
1217 else
1218 T = DAG.getTargetConstantPool(CPN->getConstVal(), ValTy, Alignment, Offset,
1219 TF);
1220
1221 assert(cast<ConstantPoolSDNode>(T)->getTargetFlags() == TF &&
1222 "Inconsistent target flag encountered");
1223
1224 if (IsPositionIndependent)
1225 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), ValTy, T);
1226 return DAG.getNode(HexagonISD::CP, SDLoc(Op), ValTy, T);
1227}
1228
1229SDValue
1231 EVT VT = Op.getValueType();
1232 int Idx = cast<JumpTableSDNode>(Op)->getIndex();
1233 if (isPositionIndependent()) {
1235 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), VT, T);
1236 }
1237
1238 SDValue T = DAG.getTargetJumpTable(Idx, VT);
1239 return DAG.getNode(HexagonISD::JT, SDLoc(Op), VT, T);
1240}
1241
1242SDValue
1244 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1246 MachineFrameInfo &MFI = MF.getFrameInfo();
1247 MFI.setReturnAddressIsTaken(true);
1248
1249 EVT VT = Op.getValueType();
1250 SDLoc dl(Op);
1251 unsigned Depth = Op.getConstantOperandVal(0);
1252 if (Depth) {
1253 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1254 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1255 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1256 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1258 }
1259
1260 // Return LR, which contains the return address. Mark it an implicit live-in.
1261 Register Reg = MF.addLiveIn(HRI.getRARegister(), getRegClassFor(MVT::i32));
1262 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1263}
1264
1265SDValue
1267 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1269 MFI.setFrameAddressIsTaken(true);
1270
1271 EVT VT = Op.getValueType();
1272 SDLoc dl(Op);
1273 unsigned Depth = Op.getConstantOperandVal(0);
1274 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1275 HRI.getFrameRegister(), VT);
1276 while (Depth--)
1277 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1279 return FrameAddr;
1280}
1281
1282SDValue
1284 SDLoc dl(Op);
1285 return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
1286}
1287
1288SDValue
1290 SDLoc dl(Op);
1291 auto *GAN = cast<GlobalAddressSDNode>(Op);
1292 auto PtrVT = getPointerTy(DAG.getDataLayout());
1293 auto *GV = GAN->getGlobal();
1294 int64_t Offset = GAN->getOffset();
1295
1296 auto &HLOF = *HTM.getObjFileLowering();
1298
1299 if (RM == Reloc::Static) {
1300 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset);
1301 const GlobalObject *GO = GV->getAliaseeObject();
1302 if (GO && Subtarget.useSmallData() && HLOF.isGlobalInSmallSection(GO, HTM))
1303 return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, GA);
1304 return DAG.getNode(HexagonISD::CONST32, dl, PtrVT, GA);
1305 }
1306
1307 bool UsePCRel = getTargetMachine().shouldAssumeDSOLocal(GV);
1308 if (UsePCRel) {
1309 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset,
1311 return DAG.getNode(HexagonISD::AT_PCREL, dl, PtrVT, GA);
1312 }
1313
1314 // Use GOT index.
1315 SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
1316 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, HexagonII::MO_GOT);
1317 SDValue Off = DAG.getConstant(Offset, dl, MVT::i32);
1318 return DAG.getNode(HexagonISD::AT_GOT, dl, PtrVT, GOT, GA, Off);
1319}
1320
1321// Specifies that for loads and stores VT can be promoted to PromotedLdStVT.
1322SDValue
1324 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1325 SDLoc dl(Op);
1326 EVT PtrVT = getPointerTy(DAG.getDataLayout());
1327
1329 if (RM == Reloc::Static) {
1330 SDValue A = DAG.getTargetBlockAddress(BA, PtrVT);
1331 return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, A);
1332 }
1333
1335 return DAG.getNode(HexagonISD::AT_PCREL, dl, PtrVT, A);
1336}
1337
1338SDValue
1340 const {
1341 EVT PtrVT = getPointerTy(DAG.getDataLayout());
1344 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), PtrVT, GOTSym);
1345}
1346
1347SDValue
1349 GlobalAddressSDNode *GA, SDValue Glue, EVT PtrVT, unsigned ReturnReg,
1350 unsigned char OperandFlags) const {
1352 MachineFrameInfo &MFI = MF.getFrameInfo();
1353 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1354 SDLoc dl(GA);
1355 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,
1356 GA->getValueType(0),
1357 GA->getOffset(),
1358 OperandFlags);
1359 // Create Operands for the call.The Operands should have the following:
1360 // 1. Chain SDValue
1361 // 2. Callee which in this case is the Global address value.
1362 // 3. Registers live into the call.In this case its R0, as we
1363 // have just one argument to be passed.
1364 // 4. Glue.
1365 // Note: The order is important.
1366
1367 const auto &HRI = *Subtarget.getRegisterInfo();
1368 const uint32_t *Mask = HRI.getCallPreservedMask(MF, CallingConv::C);
1369 assert(Mask && "Missing call preserved mask for calling convention");
1370 SDValue Ops[] = { Chain, TGA, DAG.getRegister(Hexagon::R0, PtrVT),
1371 DAG.getRegisterMask(Mask), Glue };
1372 Chain = DAG.getNode(HexagonISD::CALL, dl, NodeTys, Ops);
1373
1374 // Inform MFI that function has calls.
1375 MFI.setAdjustsStack(true);
1376
1377 Glue = Chain.getValue(1);
1378 return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Glue);
1379}
1380
1381//
1382// Lower using the initial executable model for TLS addresses
1383//
1384SDValue
1386 SelectionDAG &DAG) const {
1387 SDLoc dl(GA);
1388 int64_t Offset = GA->getOffset();
1389 auto PtrVT = getPointerTy(DAG.getDataLayout());
1390
1391 // Get the thread pointer.
1392 SDValue TP = DAG.getCopyFromReg(DAG.getEntryNode(), dl, Hexagon::UGP, PtrVT);
1393
1394 bool IsPositionIndependent = isPositionIndependent();
1395 unsigned char TF =
1396 IsPositionIndependent ? HexagonII::MO_IEGOT : HexagonII::MO_IE;
1397
1398 // First generate the TLS symbol address
1399 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, PtrVT,
1400 Offset, TF);
1401
1402 SDValue Sym = DAG.getNode(HexagonISD::CONST32, dl, PtrVT, TGA);
1403
1404 if (IsPositionIndependent) {
1405 // Generate the GOT pointer in case of position independent code
1407
1408 // Add the TLS Symbol address to GOT pointer.This gives
1409 // GOT relative relocation for the symbol.
1410 Sym = DAG.getNode(ISD::ADD, dl, PtrVT, GOT, Sym);
1411 }
1412
1413 // Load the offset value for TLS symbol.This offset is relative to
1414 // thread pointer.
1415 SDValue LoadOffset =
1416 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Sym, MachinePointerInfo());
1417
1418 // Address of the thread local variable is the add of thread
1419 // pointer and the offset of the variable.
1420 return DAG.getNode(ISD::ADD, dl, PtrVT, TP, LoadOffset);
1421}
1422
1423//
1424// Lower using the local executable model for TLS addresses
1425//
1426SDValue
1428 SelectionDAG &DAG) const {
1429 SDLoc dl(GA);
1430 int64_t Offset = GA->getOffset();
1431 auto PtrVT = getPointerTy(DAG.getDataLayout());
1432
1433 // Get the thread pointer.
1434 SDValue TP = DAG.getCopyFromReg(DAG.getEntryNode(), dl, Hexagon::UGP, PtrVT);
1435 // Generate the TLS symbol address
1436 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, PtrVT, Offset,
1438 SDValue Sym = DAG.getNode(HexagonISD::CONST32, dl, PtrVT, TGA);
1439
1440 // Address of the thread local variable is the add of thread
1441 // pointer and the offset of the variable.
1442 return DAG.getNode(ISD::ADD, dl, PtrVT, TP, Sym);
1443}
1444
1445//
1446// Lower using the general dynamic model for TLS addresses
1447//
1448SDValue
1450 SelectionDAG &DAG) const {
1451 SDLoc dl(GA);
1452 int64_t Offset = GA->getOffset();
1453 auto PtrVT = getPointerTy(DAG.getDataLayout());
1454
1455 // First generate the TLS symbol address
1456 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, PtrVT, Offset,
1458
1459 // Then, generate the GOT pointer
1460 SDValue GOT = LowerGLOBAL_OFFSET_TABLE(TGA, DAG);
1461
1462 // Add the TLS symbol and the GOT pointer
1463 SDValue Sym = DAG.getNode(HexagonISD::CONST32, dl, PtrVT, TGA);
1464 SDValue Chain = DAG.getNode(ISD::ADD, dl, PtrVT, GOT, Sym);
1465
1466 // Copy over the argument to R0
1467 SDValue InGlue;
1468 Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, Hexagon::R0, Chain, InGlue);
1469 InGlue = Chain.getValue(1);
1470
1471 unsigned Flags = DAG.getSubtarget<HexagonSubtarget>().useLongCalls()
1474
1475 return GetDynamicTLSAddr(DAG, Chain, GA, InGlue, PtrVT,
1476 Hexagon::R0, Flags);
1477}
1478
1479//
1480// Lower TLS addresses.
1481//
1482// For now for dynamic models, we only support the general dynamic model.
1483//
1484SDValue
1486 SelectionDAG &DAG) const {
1487 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
1488
1489 switch (HTM.getTLSModel(GA->getGlobal())) {
1492 return LowerToTLSGeneralDynamicModel(GA, DAG);
1494 return LowerToTLSInitialExecModel(GA, DAG);
1496 return LowerToTLSLocalExecModel(GA, DAG);
1497 }
1498 llvm_unreachable("Bogus TLS model");
1499}
1500
1501//===----------------------------------------------------------------------===//
1502// TargetLowering Implementation
1503//===----------------------------------------------------------------------===//
1504
1506 const HexagonSubtarget &ST)
1507 : TargetLowering(TM), HTM(static_cast<const HexagonTargetMachine&>(TM)),
1508 Subtarget(ST) {
1509 auto &HRI = *Subtarget.getRegisterInfo();
1510
1514 setStackPointerRegisterToSaveRestore(HRI.getStackRegister());
1517
1520
1523 else
1525
1526 // Limits for inline expansion of memcpy/memmove
1533
1534 //
1535 // Set up register classes.
1536 //
1537
1538 addRegisterClass(MVT::i1, &Hexagon::PredRegsRegClass);
1539 addRegisterClass(MVT::v2i1, &Hexagon::PredRegsRegClass); // bbbbaaaa
1540 addRegisterClass(MVT::v4i1, &Hexagon::PredRegsRegClass); // ddccbbaa
1541 addRegisterClass(MVT::v8i1, &Hexagon::PredRegsRegClass); // hgfedcba
1542 addRegisterClass(MVT::i32, &Hexagon::IntRegsRegClass);
1543 addRegisterClass(MVT::v2i16, &Hexagon::IntRegsRegClass);
1544 addRegisterClass(MVT::v4i8, &Hexagon::IntRegsRegClass);
1545 addRegisterClass(MVT::i64, &Hexagon::DoubleRegsRegClass);
1546 addRegisterClass(MVT::v8i8, &Hexagon::DoubleRegsRegClass);
1547 addRegisterClass(MVT::v4i16, &Hexagon::DoubleRegsRegClass);
1548 addRegisterClass(MVT::v2i32, &Hexagon::DoubleRegsRegClass);
1549
1550 addRegisterClass(MVT::f32, &Hexagon::IntRegsRegClass);
1551 addRegisterClass(MVT::f64, &Hexagon::DoubleRegsRegClass);
1552
1553 //
1554 // Handling of scalar operations.
1555 //
1556 // All operations default to "legal", except:
1557 // - indexed loads and stores (pre-/post-incremented),
1558 // - ANY_EXTEND_VECTOR_INREG, ATOMIC_CMP_SWAP_WITH_SUCCESS, CONCAT_VECTORS,
1559 // ConstantFP, FCEIL, FCOPYSIGN, FEXP, FEXP2, FFLOOR, FGETSIGN,
1560 // FLOG, FLOG2, FLOG10, FMAXIMUMNUM, FMINIMUMNUM, FNEARBYINT, FRINT, FROUND,
1561 // TRAP, FTRUNC, PREFETCH, SIGN_EXTEND_VECTOR_INREG,
1562 // ZERO_EXTEND_VECTOR_INREG,
1563 // which default to "expand" for at least one type.
1564
1565 // Misc operations.
1568 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1585
1586 // Custom legalize GlobalAddress nodes into CONST32.
1590
1591 // Hexagon needs to optimize cases with negative constants.
1595 setOperationAction(ISD::SETCC, MVT::v2i16, Custom);
1596
1597 // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
1599 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1600 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1601 if (Subtarget.isEnvironmentMusl())
1603 else
1605
1609
1610 if (EmitJumpTables)
1612 else
1613 setMinimumJumpTableEntries(std::numeric_limits<unsigned>::max());
1614 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
1615
1616 for (unsigned LegalIntOp :
1618 setOperationAction(LegalIntOp, MVT::i32, Legal);
1619 setOperationAction(LegalIntOp, MVT::i64, Legal);
1620 }
1621
1622 // Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit,
1623 // but they only operate on i64.
1624 for (MVT VT : MVT::integer_valuetypes()) {
1631 }
1634
1639
1640 // Popcount can count # of 1s in i64 but returns i32.
1645
1650
1655
1656 for (unsigned IntExpOp :
1661 for (MVT VT : MVT::integer_valuetypes())
1662 setOperationAction(IntExpOp, VT, Expand);
1663 }
1664
1665 for (unsigned FPExpOp :
1668 for (MVT VT : MVT::fp_valuetypes())
1669 setOperationAction(FPExpOp, VT, Expand);
1670 }
1671
1672 // No extending loads from i32.
1673 for (MVT VT : MVT::integer_valuetypes()) {
1674 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i32, Expand);
1675 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
1676 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i32, Expand);
1677 }
1678 // Turn FP truncstore into trunc + store.
1679 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
1680 // Turn FP extload into load/fpextend.
1681 for (MVT VT : MVT::fp_valuetypes())
1682 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
1683
1684 // Expand BR_CC and SELECT_CC for all integer and fp types.
1685 for (MVT VT : MVT::integer_valuetypes()) {
1688 }
1689 for (MVT VT : MVT::fp_valuetypes()) {
1692 }
1693 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
1694
1695 //
1696 // Handling of vector operations.
1697 //
1698
1699 // Set the action for vector operations to "expand", then override it with
1700 // either "custom" or "legal" for specific cases.
1701 // clang-format off
1702 static const unsigned VectExpOps[] = {
1703 // Integer arithmetic:
1707 // Logical/bit:
1710 // Floating point arithmetic/math functions:
1718 // Misc:
1720 // Vector:
1726 };
1727 // clang-format on
1728
1730 for (unsigned VectExpOp : VectExpOps)
1731 setOperationAction(VectExpOp, VT, Expand);
1732
1733 // Expand all extending loads and truncating stores:
1734 for (MVT TargetVT : MVT::fixedlen_vector_valuetypes()) {
1735 if (TargetVT == VT)
1736 continue;
1737 setLoadExtAction(ISD::EXTLOAD, TargetVT, VT, Expand);
1738 setLoadExtAction(ISD::ZEXTLOAD, TargetVT, VT, Expand);
1739 setLoadExtAction(ISD::SEXTLOAD, TargetVT, VT, Expand);
1740 setTruncStoreAction(VT, TargetVT, Expand);
1741 }
1742
1743 // Normalize all inputs to SELECT to be vectors of i32.
1744 if (VT.getVectorElementType() != MVT::i32) {
1745 MVT VT32 = MVT::getVectorVT(MVT::i32, VT.getSizeInBits()/32);
1747 AddPromotedToType(ISD::SELECT, VT, VT32);
1748 }
1752 }
1753
1756
1757 // Extending loads from (native) vectors of i8 into (native) vectors of i16
1758 // are legal.
1759 setLoadExtAction(ISD::EXTLOAD, MVT::v2i16, MVT::v2i8, Legal);
1760 setLoadExtAction(ISD::ZEXTLOAD, MVT::v2i16, MVT::v2i8, Legal);
1761 setLoadExtAction(ISD::SEXTLOAD, MVT::v2i16, MVT::v2i8, Legal);
1762 setLoadExtAction(ISD::EXTLOAD, MVT::v4i16, MVT::v4i8, Legal);
1763 setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i16, MVT::v4i8, Legal);
1764 setLoadExtAction(ISD::SEXTLOAD, MVT::v4i16, MVT::v4i8, Legal);
1765
1769
1770 // Types natively supported:
1771 for (MVT NativeVT : {MVT::v8i1, MVT::v4i1, MVT::v2i1, MVT::v4i8,
1772 MVT::v8i8, MVT::v2i16, MVT::v4i16, MVT::v2i32}) {
1779
1780 setOperationAction(ISD::ADD, NativeVT, Legal);
1781 setOperationAction(ISD::SUB, NativeVT, Legal);
1782 setOperationAction(ISD::MUL, NativeVT, Legal);
1783 setOperationAction(ISD::AND, NativeVT, Legal);
1784 setOperationAction(ISD::OR, NativeVT, Legal);
1785 setOperationAction(ISD::XOR, NativeVT, Legal);
1786
1787 if (NativeVT.getVectorElementType() != MVT::i1) {
1791 }
1792 }
1793
1794 for (MVT VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32}) {
1799 }
1800
1801 // Custom lower unaligned loads.
1802 // Also, for both loads and stores, verify the alignment of the address
1803 // in case it is a compile-time constant. This is a usability feature to
1804 // provide a meaningful error message to users.
1805 for (MVT VT : {MVT::i16, MVT::i32, MVT::v4i8, MVT::i64, MVT::v8i8,
1806 MVT::v2i16, MVT::v4i16, MVT::v2i32}) {
1809 }
1810
1811 // Custom-lower load/stores of boolean vectors.
1812 for (MVT VT : {MVT::v2i1, MVT::v4i1, MVT::v8i1}) {
1815 }
1816
1817 // Normalize integer compares to EQ/GT/UGT
1818 for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v8i8, MVT::v2i32, MVT::v4i16,
1819 MVT::v2i32}) {
1827 }
1828
1829 // Normalize boolean compares to [U]LE/[U]LT
1830 for (MVT VT : {MVT::i1, MVT::v2i1, MVT::v4i1, MVT::v8i1}) {
1835 }
1836
1837 // Custom-lower bitcasts from i8 to v8i1.
1839 setOperationAction(ISD::SETCC, MVT::v2i16, Custom);
1845
1846 // V5+.
1852
1855
1868
1869 // Special handling for half-precision floating point conversions.
1870 // Lower half float conversions into library calls.
1875
1876 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
1877 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
1878 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
1879 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
1880
1881 // Handling of indexed loads/stores: default is "expand".
1882 //
1883 for (MVT VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64, MVT::f32, MVT::f64,
1884 MVT::v2i16, MVT::v2i32, MVT::v4i8, MVT::v4i16, MVT::v8i8}) {
1887 }
1888
1889 // Subtarget-specific operation actions.
1890 //
1891 if (Subtarget.hasV60Ops()) {
1896 }
1897 if (Subtarget.hasV66Ops()) {
1900 }
1901 if (Subtarget.hasV67Ops()) {
1905 }
1906
1910
1911 if (Subtarget.useHVXOps())
1912 initializeHVXLowering();
1913
1915}
1916
1917const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
1918 switch ((HexagonISD::NodeType)Opcode) {
1919 case HexagonISD::ADDC: return "HexagonISD::ADDC";
1920 case HexagonISD::SUBC: return "HexagonISD::SUBC";
1921 case HexagonISD::ALLOCA: return "HexagonISD::ALLOCA";
1922 case HexagonISD::AT_GOT: return "HexagonISD::AT_GOT";
1923 case HexagonISD::AT_PCREL: return "HexagonISD::AT_PCREL";
1924 case HexagonISD::BARRIER: return "HexagonISD::BARRIER";
1925 case HexagonISD::CALL: return "HexagonISD::CALL";
1926 case HexagonISD::CALLnr: return "HexagonISD::CALLnr";
1927 case HexagonISD::CALLR: return "HexagonISD::CALLR";
1928 case HexagonISD::COMBINE: return "HexagonISD::COMBINE";
1929 case HexagonISD::CONST32_GP: return "HexagonISD::CONST32_GP";
1930 case HexagonISD::CONST32: return "HexagonISD::CONST32";
1931 case HexagonISD::CP: return "HexagonISD::CP";
1932 case HexagonISD::DCFETCH: return "HexagonISD::DCFETCH";
1933 case HexagonISD::EH_RETURN: return "HexagonISD::EH_RETURN";
1934 case HexagonISD::TSTBIT: return "HexagonISD::TSTBIT";
1935 case HexagonISD::EXTRACTU: return "HexagonISD::EXTRACTU";
1936 case HexagonISD::INSERT: return "HexagonISD::INSERT";
1937 case HexagonISD::JT: return "HexagonISD::JT";
1938 case HexagonISD::RET_GLUE: return "HexagonISD::RET_GLUE";
1939 case HexagonISD::TC_RETURN: return "HexagonISD::TC_RETURN";
1940 case HexagonISD::VASL: return "HexagonISD::VASL";
1941 case HexagonISD::VASR: return "HexagonISD::VASR";
1942 case HexagonISD::VLSR: return "HexagonISD::VLSR";
1943 case HexagonISD::MFSHL: return "HexagonISD::MFSHL";
1944 case HexagonISD::MFSHR: return "HexagonISD::MFSHR";
1945 case HexagonISD::SSAT: return "HexagonISD::SSAT";
1946 case HexagonISD::USAT: return "HexagonISD::USAT";
1947 case HexagonISD::SMUL_LOHI: return "HexagonISD::SMUL_LOHI";
1948 case HexagonISD::UMUL_LOHI: return "HexagonISD::UMUL_LOHI";
1949 case HexagonISD::USMUL_LOHI: return "HexagonISD::USMUL_LOHI";
1950 case HexagonISD::VEXTRACTW: return "HexagonISD::VEXTRACTW";
1951 case HexagonISD::VINSERTW0: return "HexagonISD::VINSERTW0";
1952 case HexagonISD::VROR: return "HexagonISD::VROR";
1953 case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE";
1954 case HexagonISD::READTIMER: return "HexagonISD::READTIMER";
1956 return "HexagonISD::THREAD_POINTER";
1957 case HexagonISD::PTRUE: return "HexagonISD::PTRUE";
1958 case HexagonISD::PFALSE: return "HexagonISD::PFALSE";
1959 case HexagonISD::D2P: return "HexagonISD::D2P";
1960 case HexagonISD::P2D: return "HexagonISD::P2D";
1961 case HexagonISD::V2Q: return "HexagonISD::V2Q";
1962 case HexagonISD::Q2V: return "HexagonISD::Q2V";
1963 case HexagonISD::QCAT: return "HexagonISD::QCAT";
1964 case HexagonISD::QTRUE: return "HexagonISD::QTRUE";
1965 case HexagonISD::QFALSE: return "HexagonISD::QFALSE";
1966 case HexagonISD::TL_EXTEND: return "HexagonISD::TL_EXTEND";
1967 case HexagonISD::TL_TRUNCATE: return "HexagonISD::TL_TRUNCATE";
1968 case HexagonISD::TYPECAST: return "HexagonISD::TYPECAST";
1969 case HexagonISD::VALIGN: return "HexagonISD::VALIGN";
1970 case HexagonISD::VALIGNADDR: return "HexagonISD::VALIGNADDR";
1971 case HexagonISD::ISEL: return "HexagonISD::ISEL";
1972 case HexagonISD::OP_END: break;
1973 }
1974 return nullptr;
1975}
1976
1977bool
1978HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
1979 const SDLoc &dl, SelectionDAG &DAG) const {
1980 auto *CA = dyn_cast<ConstantSDNode>(Ptr);
1981 if (!CA)
1982 return true;
1983 unsigned Addr = CA->getZExtValue();
1984 Align HaveAlign =
1985 Addr != 0 ? Align(1ull << llvm::countr_zero(Addr)) : NeedAlign;
1986 if (HaveAlign >= NeedAlign)
1987 return true;
1988
1989 static int DK_MisalignedTrap = llvm::getNextAvailablePluginDiagnosticKind();
1990
1991 struct DiagnosticInfoMisalignedTrap : public DiagnosticInfo {
1992 DiagnosticInfoMisalignedTrap(StringRef M)
1993 : DiagnosticInfo(DK_MisalignedTrap, DS_Remark), Msg(M) {}
1994 void print(DiagnosticPrinter &DP) const override {
1995 DP << Msg;
1996 }
1997 static bool classof(const DiagnosticInfo *DI) {
1998 return DI->getKind() == DK_MisalignedTrap;
1999 }
2000 StringRef Msg;
2001 };
2002
2003 std::string ErrMsg;
2004 raw_string_ostream O(ErrMsg);
2005 O << "Misaligned constant address: " << format_hex(Addr, 10)
2006 << " has alignment " << HaveAlign.value()
2007 << ", but the memory access requires " << NeedAlign.value();
2008 if (DebugLoc DL = dl.getDebugLoc())
2009 DL.print(O << ", at ");
2010 O << ". The instruction has been replaced with a trap.";
2011
2012 DAG.getContext()->diagnose(DiagnosticInfoMisalignedTrap(O.str()));
2013 return false;
2014}
2015
2016SDValue
2017HexagonTargetLowering::replaceMemWithUndef(SDValue Op, SelectionDAG &DAG)
2018 const {
2019 const SDLoc &dl(Op);
2020 auto *LS = cast<LSBaseSDNode>(Op.getNode());
2021 assert(!LS->isIndexed() && "Not expecting indexed ops on constant address");
2022
2023 SDValue Chain = LS->getChain();
2024 SDValue Trap = DAG.getNode(ISD::TRAP, dl, MVT::Other, Chain);
2025 if (LS->getOpcode() == ISD::LOAD)
2026 return DAG.getMergeValues({DAG.getUNDEF(ty(Op)), Trap}, dl);
2027 return Trap;
2028}
2029
2030// Bit-reverse Load Intrinsic: Check if the instruction is a bit reverse load
2031// intrinsic.
2032static bool isBrevLdIntrinsic(const Value *Inst) {
2033 unsigned ID = cast<IntrinsicInst>(Inst)->getIntrinsicID();
2034 return (ID == Intrinsic::hexagon_L2_loadrd_pbr ||
2035 ID == Intrinsic::hexagon_L2_loadri_pbr ||
2036 ID == Intrinsic::hexagon_L2_loadrh_pbr ||
2037 ID == Intrinsic::hexagon_L2_loadruh_pbr ||
2038 ID == Intrinsic::hexagon_L2_loadrb_pbr ||
2039 ID == Intrinsic::hexagon_L2_loadrub_pbr);
2040}
2041
2042// Bit-reverse Load Intrinsic :Crawl up and figure out the object from previous
2043// instruction. So far we only handle bitcast, extract value and bit reverse
2044// load intrinsic instructions. Should we handle CGEP ?
2046 if (Operator::getOpcode(V) == Instruction::ExtractValue ||
2047 Operator::getOpcode(V) == Instruction::BitCast)
2048 V = cast<Operator>(V)->getOperand(0);
2049 else if (isa<IntrinsicInst>(V) && isBrevLdIntrinsic(V))
2050 V = cast<Instruction>(V)->getOperand(0);
2051 return V;
2052}
2053
2054// Bit-reverse Load Intrinsic: For a PHI Node return either an incoming edge or
2055// a back edge. If the back edge comes from the intrinsic itself, the incoming
2056// edge is returned.
2057static Value *returnEdge(const PHINode *PN, Value *IntrBaseVal) {
2058 const BasicBlock *Parent = PN->getParent();
2059 int Idx = -1;
2060 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
2061 BasicBlock *Blk = PN->getIncomingBlock(i);
2062 // Determine if the back edge is originated from intrinsic.
2063 if (Blk == Parent) {
2064 Value *BackEdgeVal = PN->getIncomingValue(i);
2065 Value *BaseVal;
2066 // Loop over till we return the same Value or we hit the IntrBaseVal.
2067 do {
2068 BaseVal = BackEdgeVal;
2069 BackEdgeVal = getBrevLdObject(BackEdgeVal);
2070 } while ((BaseVal != BackEdgeVal) && (IntrBaseVal != BackEdgeVal));
2071 // If the getBrevLdObject returns IntrBaseVal, we should return the
2072 // incoming edge.
2073 if (IntrBaseVal == BackEdgeVal)
2074 continue;
2075 Idx = i;
2076 break;
2077 } else // Set the node to incoming edge.
2078 Idx = i;
2079 }
2080 assert(Idx >= 0 && "Unexpected index to incoming argument in PHI");
2081 return PN->getIncomingValue(Idx);
2082}
2083
2084// Bit-reverse Load Intrinsic: Figure out the underlying object the base
2085// pointer points to, for the bit-reverse load intrinsic. Setting this to
2086// memoperand might help alias analysis to figure out the dependencies.
2088 Value *IntrBaseVal = V;
2089 Value *BaseVal;
2090 // Loop over till we return the same Value, implies we either figure out
2091 // the object or we hit a PHI
2092 do {
2093 BaseVal = V;
2094 V = getBrevLdObject(V);
2095 } while (BaseVal != V);
2096
2097 // Identify the object from PHINode.
2098 if (const PHINode *PN = dyn_cast<PHINode>(V))
2099 return returnEdge(PN, IntrBaseVal);
2100 // For non PHI nodes, the object is the last value returned by getBrevLdObject
2101 else
2102 return V;
2103}
2104
2105/// Given an intrinsic, checks if on the target the intrinsic will need to map
2106/// to a MemIntrinsicNode (touches memory). If this is the case, it returns
2107/// true and store the intrinsic information into the IntrinsicInfo that was
2108/// passed to the function.
2110 const CallInst &I,
2111 MachineFunction &MF,
2112 unsigned Intrinsic) const {
2113 switch (Intrinsic) {
2114 case Intrinsic::hexagon_L2_loadrd_pbr:
2115 case Intrinsic::hexagon_L2_loadri_pbr:
2116 case Intrinsic::hexagon_L2_loadrh_pbr:
2117 case Intrinsic::hexagon_L2_loadruh_pbr:
2118 case Intrinsic::hexagon_L2_loadrb_pbr:
2119 case Intrinsic::hexagon_L2_loadrub_pbr: {
2121 auto &DL = I.getDataLayout();
2122 auto &Cont = I.getCalledFunction()->getParent()->getContext();
2123 // The intrinsic function call is of the form { ElTy, i8* }
2124 // @llvm.hexagon.L2.loadXX.pbr(i8*, i32). The pointer and memory access type
2125 // should be derived from ElTy.
2126 Type *ElTy = I.getCalledFunction()->getReturnType()->getStructElementType(0);
2127 Info.memVT = MVT::getVT(ElTy);
2128 llvm::Value *BasePtrVal = I.getOperand(0);
2129 Info.ptrVal = getUnderLyingObjectForBrevLdIntr(BasePtrVal);
2130 // The offset value comes through Modifier register. For now, assume the
2131 // offset is 0.
2132 Info.offset = 0;
2133 Info.align = DL.getABITypeAlign(Info.memVT.getTypeForEVT(Cont));
2135 return true;
2136 }
2137 case Intrinsic::hexagon_V6_vgathermw:
2138 case Intrinsic::hexagon_V6_vgathermw_128B:
2139 case Intrinsic::hexagon_V6_vgathermh:
2140 case Intrinsic::hexagon_V6_vgathermh_128B:
2141 case Intrinsic::hexagon_V6_vgathermhw:
2142 case Intrinsic::hexagon_V6_vgathermhw_128B:
2143 case Intrinsic::hexagon_V6_vgathermwq:
2144 case Intrinsic::hexagon_V6_vgathermwq_128B:
2145 case Intrinsic::hexagon_V6_vgathermhq:
2146 case Intrinsic::hexagon_V6_vgathermhq_128B:
2147 case Intrinsic::hexagon_V6_vgathermhwq:
2148 case Intrinsic::hexagon_V6_vgathermhwq_128B: {
2149 const Module &M = *I.getParent()->getParent()->getParent();
2151 Type *VecTy = I.getArgOperand(1)->getType();
2152 Info.memVT = MVT::getVT(VecTy);
2153 Info.ptrVal = I.getArgOperand(0);
2154 Info.offset = 0;
2155 Info.align =
2156 MaybeAlign(M.getDataLayout().getTypeAllocSizeInBits(VecTy) / 8);
2160 return true;
2161 }
2162 default:
2163 break;
2164 }
2165 return false;
2166}
2167
2169 return X.getValueType().isScalarInteger(); // 'tstbit'
2170}
2171
2173 return isTruncateFree(EVT::getEVT(Ty1), EVT::getEVT(Ty2));
2174}
2175
2177 if (!VT1.isSimple() || !VT2.isSimple())
2178 return false;
2179 return VT1.getSimpleVT() == MVT::i64 && VT2.getSimpleVT() == MVT::i32;
2180}
2181
2183 const MachineFunction &MF, EVT VT) const {
2185}
2186
2187// Should we expand the build vector with shuffles?
2189 unsigned DefinedValues) const {
2190 return false;
2191}
2192
2194 unsigned Index) const {
2196 if (!ResVT.isSimple() || !SrcVT.isSimple())
2197 return false;
2198
2199 MVT ResTy = ResVT.getSimpleVT(), SrcTy = SrcVT.getSimpleVT();
2200 if (ResTy.getVectorElementType() != MVT::i1)
2201 return true;
2202
2203 // Non-HVX bool vectors are relatively cheap.
2204 return SrcTy.getVectorNumElements() <= 8;
2205}
2206
2208 return Op.getOpcode() == ISD::CONCAT_VECTORS ||
2210}
2211
2213 EVT VT) const {
2214 return true;
2215}
2216
2219 unsigned VecLen = VT.getVectorMinNumElements();
2220 MVT ElemTy = VT.getVectorElementType();
2221
2222 if (VecLen == 1 || VT.isScalableVector())
2224
2225 if (Subtarget.useHVXOps()) {
2226 unsigned Action = getPreferredHvxVectorAction(VT);
2227 if (Action != ~0u)
2228 return static_cast<TargetLoweringBase::LegalizeTypeAction>(Action);
2229 }
2230
2231 // Always widen (remaining) vectors of i1.
2232 if (ElemTy == MVT::i1)
2234 // Widen non-power-of-2 vectors. Such types cannot be split right now,
2235 // and computeRegisterProperties will override "split" with "widen",
2236 // which can cause other issues.
2237 if (!isPowerOf2_32(VecLen))
2239
2241}
2242
2245 if (Subtarget.useHVXOps()) {
2246 unsigned Action = getCustomHvxOperationAction(Op);
2247 if (Action != ~0u)
2248 return static_cast<TargetLoweringBase::LegalizeAction>(Action);
2249 }
2251}
2252
2253std::pair<SDValue, int>
2254HexagonTargetLowering::getBaseAndOffset(SDValue Addr) const {
2255 if (Addr.getOpcode() == ISD::ADD) {
2256 SDValue Op1 = Addr.getOperand(1);
2257 if (auto *CN = dyn_cast<const ConstantSDNode>(Op1.getNode()))
2258 return { Addr.getOperand(0), CN->getSExtValue() };
2259 }
2260 return { Addr, 0 };
2261}
2262
2263// Lower a vector shuffle (V1, V2, V3). V1 and V2 are the two vectors
2264// to select data from, V3 is the permutation.
2265SDValue
2267 const {
2268 const auto *SVN = cast<ShuffleVectorSDNode>(Op);
2269 ArrayRef<int> AM = SVN->getMask();
2270 assert(AM.size() <= 8 && "Unexpected shuffle mask");
2271 unsigned VecLen = AM.size();
2272
2273 MVT VecTy = ty(Op);
2274 assert(!Subtarget.isHVXVectorType(VecTy, true) &&
2275 "HVX shuffles should be legal");
2276 assert(VecTy.getSizeInBits() <= 64 && "Unexpected vector length");
2277
2278 SDValue Op0 = Op.getOperand(0);
2279 SDValue Op1 = Op.getOperand(1);
2280 const SDLoc &dl(Op);
2281
2282 // If the inputs are not the same as the output, bail. This is not an
2283 // error situation, but complicates the handling and the default expansion
2284 // (into BUILD_VECTOR) should be adequate.
2285 if (ty(Op0) != VecTy || ty(Op1) != VecTy)
2286 return SDValue();
2287
2288 // Normalize the mask so that the first non-negative index comes from
2289 // the first operand.
2290 SmallVector<int, 8> Mask(AM);
2291 unsigned F = llvm::find_if(AM, [](int M) { return M >= 0; }) - AM.data();
2292 if (F == AM.size())
2293 return DAG.getUNDEF(VecTy);
2294 if (AM[F] >= int(VecLen)) {
2296 std::swap(Op0, Op1);
2297 }
2298
2299 // Express the shuffle mask in terms of bytes.
2300 SmallVector<int,8> ByteMask;
2301 unsigned ElemBytes = VecTy.getVectorElementType().getSizeInBits() / 8;
2302 for (int M : Mask) {
2303 if (M < 0) {
2304 for (unsigned j = 0; j != ElemBytes; ++j)
2305 ByteMask.push_back(-1);
2306 } else {
2307 for (unsigned j = 0; j != ElemBytes; ++j)
2308 ByteMask.push_back(M*ElemBytes + j);
2309 }
2310 }
2311 assert(ByteMask.size() <= 8);
2312
2313 // All non-undef (non-negative) indexes are well within [0..127], so they
2314 // fit in a single byte. Build two 64-bit words:
2315 // - MaskIdx where each byte is the corresponding index (for non-negative
2316 // indexes), and 0xFF for negative indexes, and
2317 // - MaskUnd that has 0xFF for each negative index.
2318 uint64_t MaskIdx = 0;
2319 uint64_t MaskUnd = 0;
2320 for (unsigned i = 0, e = ByteMask.size(); i != e; ++i) {
2321 unsigned S = 8*i;
2322 uint64_t M = ByteMask[i] & 0xFF;
2323 if (M == 0xFF)
2324 MaskUnd |= M << S;
2325 MaskIdx |= M << S;
2326 }
2327
2328 if (ByteMask.size() == 4) {
2329 // Identity.
2330 if (MaskIdx == (0x03020100 | MaskUnd))
2331 return Op0;
2332 // Byte swap.
2333 if (MaskIdx == (0x00010203 | MaskUnd)) {
2334 SDValue T0 = DAG.getBitcast(MVT::i32, Op0);
2335 SDValue T1 = DAG.getNode(ISD::BSWAP, dl, MVT::i32, T0);
2336 return DAG.getBitcast(VecTy, T1);
2337 }
2338
2339 // Byte packs.
2340 SDValue Concat10 =
2341 getCombine(Op1, Op0, dl, typeJoin({ty(Op1), ty(Op0)}), DAG);
2342 if (MaskIdx == (0x06040200 | MaskUnd))
2343 return getInstr(Hexagon::S2_vtrunehb, dl, VecTy, {Concat10}, DAG);
2344 if (MaskIdx == (0x07050301 | MaskUnd))
2345 return getInstr(Hexagon::S2_vtrunohb, dl, VecTy, {Concat10}, DAG);
2346
2347 SDValue Concat01 =
2348 getCombine(Op0, Op1, dl, typeJoin({ty(Op0), ty(Op1)}), DAG);
2349 if (MaskIdx == (0x02000604 | MaskUnd))
2350 return getInstr(Hexagon::S2_vtrunehb, dl, VecTy, {Concat01}, DAG);
2351 if (MaskIdx == (0x03010705 | MaskUnd))
2352 return getInstr(Hexagon::S2_vtrunohb, dl, VecTy, {Concat01}, DAG);
2353 }
2354
2355 if (ByteMask.size() == 8) {
2356 // Identity.
2357 if (MaskIdx == (0x0706050403020100ull | MaskUnd))
2358 return Op0;
2359 // Byte swap.
2360 if (MaskIdx == (0x0001020304050607ull | MaskUnd)) {
2361 SDValue T0 = DAG.getBitcast(MVT::i64, Op0);
2362 SDValue T1 = DAG.getNode(ISD::BSWAP, dl, MVT::i64, T0);
2363 return DAG.getBitcast(VecTy, T1);
2364 }
2365
2366 // Halfword picks.
2367 if (MaskIdx == (0x0d0c050409080100ull | MaskUnd))
2368 return getInstr(Hexagon::S2_shuffeh, dl, VecTy, {Op1, Op0}, DAG);
2369 if (MaskIdx == (0x0f0e07060b0a0302ull | MaskUnd))
2370 return getInstr(Hexagon::S2_shuffoh, dl, VecTy, {Op1, Op0}, DAG);
2371 if (MaskIdx == (0x0d0c090805040100ull | MaskUnd))
2372 return getInstr(Hexagon::S2_vtrunewh, dl, VecTy, {Op1, Op0}, DAG);
2373 if (MaskIdx == (0x0f0e0b0a07060302ull | MaskUnd))
2374 return getInstr(Hexagon::S2_vtrunowh, dl, VecTy, {Op1, Op0}, DAG);
2375 if (MaskIdx == (0x0706030205040100ull | MaskUnd)) {
2376 VectorPair P = opSplit(Op0, dl, DAG);
2377 return getInstr(Hexagon::S2_packhl, dl, VecTy, {P.second, P.first}, DAG);
2378 }
2379
2380 // Byte packs.
2381 if (MaskIdx == (0x0e060c040a020800ull | MaskUnd))
2382 return getInstr(Hexagon::S2_shuffeb, dl, VecTy, {Op1, Op0}, DAG);
2383 if (MaskIdx == (0x0f070d050b030901ull | MaskUnd))
2384 return getInstr(Hexagon::S2_shuffob, dl, VecTy, {Op1, Op0}, DAG);
2385 }
2386
2387 return SDValue();
2388}
2389
2390SDValue
2391HexagonTargetLowering::getSplatValue(SDValue Op, SelectionDAG &DAG) const {
2392 switch (Op.getOpcode()) {
2393 case ISD::BUILD_VECTOR:
2394 if (SDValue S = cast<BuildVectorSDNode>(Op)->getSplatValue())
2395 return S;
2396 break;
2397 case ISD::SPLAT_VECTOR:
2398 return Op.getOperand(0);
2399 }
2400 return SDValue();
2401}
2402
2403// Create a Hexagon-specific node for shifting a vector by an integer.
2404SDValue
2405HexagonTargetLowering::getVectorShiftByInt(SDValue Op, SelectionDAG &DAG)
2406 const {
2407 unsigned NewOpc;
2408 switch (Op.getOpcode()) {
2409 case ISD::SHL:
2410 NewOpc = HexagonISD::VASL;
2411 break;
2412 case ISD::SRA:
2413 NewOpc = HexagonISD::VASR;
2414 break;
2415 case ISD::SRL:
2416 NewOpc = HexagonISD::VLSR;
2417 break;
2418 default:
2419 llvm_unreachable("Unexpected shift opcode");
2420 }
2421
2422 if (SDValue Sp = getSplatValue(Op.getOperand(1), DAG))
2423 return DAG.getNode(NewOpc, SDLoc(Op), ty(Op), Op.getOperand(0), Sp);
2424 return SDValue();
2425}
2426
2427SDValue
2429 const SDLoc &dl(Op);
2430
2431 // First try to convert the shift (by vector) to a shift by a scalar.
2432 // If we first split the shift, the shift amount will become 'extract
2433 // subvector', and will no longer be recognized as scalar.
2434 SDValue Res = Op;
2435 if (SDValue S = getVectorShiftByInt(Op, DAG))
2436 Res = S;
2437
2438 unsigned Opc = Res.getOpcode();
2439 switch (Opc) {
2440 case HexagonISD::VASR:
2441 case HexagonISD::VLSR:
2442 case HexagonISD::VASL:
2443 break;
2444 default:
2445 // No instructions for shifts by non-scalars.
2446 return SDValue();
2447 }
2448
2449 MVT ResTy = ty(Res);
2450 if (ResTy.getVectorElementType() != MVT::i8)
2451 return Res;
2452
2453 // For shifts of i8, extend the inputs to i16, then truncate back to i8.
2454 assert(ResTy.getVectorElementType() == MVT::i8);
2455 SDValue Val = Res.getOperand(0), Amt = Res.getOperand(1);
2456
2457 auto ShiftPartI8 = [&dl, &DAG, this](unsigned Opc, SDValue V, SDValue A) {
2458 MVT Ty = ty(V);
2459 MVT ExtTy = MVT::getVectorVT(MVT::i16, Ty.getVectorNumElements());
2460 SDValue ExtV = Opc == HexagonISD::VASR ? DAG.getSExtOrTrunc(V, dl, ExtTy)
2461 : DAG.getZExtOrTrunc(V, dl, ExtTy);
2462 SDValue ExtS = DAG.getNode(Opc, dl, ExtTy, {ExtV, A});
2463 return DAG.getZExtOrTrunc(ExtS, dl, Ty);
2464 };
2465
2466 if (ResTy.getSizeInBits() == 32)
2467 return ShiftPartI8(Opc, Val, Amt);
2468
2469 auto [LoV, HiV] = opSplit(Val, dl, DAG);
2470 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResTy,
2471 {ShiftPartI8(Opc, LoV, Amt), ShiftPartI8(Opc, HiV, Amt)});
2472}
2473
2474SDValue
2476 if (isa<ConstantSDNode>(Op.getOperand(1).getNode()))
2477 return Op;
2478 return SDValue();
2479}
2480
2481SDValue
2483 MVT ResTy = ty(Op);
2484 SDValue InpV = Op.getOperand(0);
2485 MVT InpTy = ty(InpV);
2486 assert(ResTy.getSizeInBits() == InpTy.getSizeInBits());
2487 const SDLoc &dl(Op);
2488
2489 // Handle conversion from i8 to v8i1.
2490 if (InpTy == MVT::i8) {
2491 if (ResTy == MVT::v8i1) {
2492 SDValue Sc = DAG.getBitcast(tyScalar(InpTy), InpV);
2493 SDValue Ext = DAG.getZExtOrTrunc(Sc, dl, MVT::i32);
2494 return getInstr(Hexagon::C2_tfrrp, dl, ResTy, Ext, DAG);
2495 }
2496 return SDValue();
2497 }
2498
2499 return Op;
2500}
2501
2502bool
2503HexagonTargetLowering::getBuildVectorConstInts(ArrayRef<SDValue> Values,
2504 MVT VecTy, SelectionDAG &DAG,
2505 MutableArrayRef<ConstantInt*> Consts) const {
2506 MVT ElemTy = VecTy.getVectorElementType();
2507 unsigned ElemWidth = ElemTy.getSizeInBits();
2508 IntegerType *IntTy = IntegerType::get(*DAG.getContext(), ElemWidth);
2509 bool AllConst = true;
2510
2511 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
2512 SDValue V = Values[i];
2513 if (V.isUndef()) {
2514 Consts[i] = ConstantInt::get(IntTy, 0);
2515 continue;
2516 }
2517 // Make sure to always cast to IntTy.
2518 if (auto *CN = dyn_cast<ConstantSDNode>(V.getNode())) {
2519 const ConstantInt *CI = CN->getConstantIntValue();
2520 Consts[i] = ConstantInt::get(IntTy, CI->getValue().getSExtValue());
2521 } else if (auto *CN = dyn_cast<ConstantFPSDNode>(V.getNode())) {
2522 const ConstantFP *CF = CN->getConstantFPValue();
2524 Consts[i] = ConstantInt::get(IntTy, A.getZExtValue());
2525 } else {
2526 AllConst = false;
2527 }
2528 }
2529 return AllConst;
2530}
2531
2532SDValue
2533HexagonTargetLowering::buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl,
2534 MVT VecTy, SelectionDAG &DAG) const {
2535 MVT ElemTy = VecTy.getVectorElementType();
2536 assert(VecTy.getVectorNumElements() == Elem.size());
2537
2538 SmallVector<ConstantInt*,4> Consts(Elem.size());
2539 bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
2540
2541 unsigned First, Num = Elem.size();
2542 for (First = 0; First != Num; ++First) {
2543 if (!isUndef(Elem[First]))
2544 break;
2545 }
2546 if (First == Num)
2547 return DAG.getUNDEF(VecTy);
2548
2549 if (AllConst &&
2550 llvm::all_of(Consts, [](ConstantInt *CI) { return CI->isZero(); }))
2551 return getZero(dl, VecTy, DAG);
2552
2553 if (ElemTy == MVT::i16 || ElemTy == MVT::f16) {
2554 assert(Elem.size() == 2);
2555 if (AllConst) {
2556 // The 'Consts' array will have all values as integers regardless
2557 // of the vector element type.
2558 uint32_t V = (Consts[0]->getZExtValue() & 0xFFFF) |
2559 Consts[1]->getZExtValue() << 16;
2560 return DAG.getBitcast(VecTy, DAG.getConstant(V, dl, MVT::i32));
2561 }
2562 SDValue E0, E1;
2563 if (ElemTy == MVT::f16) {
2564 E0 = DAG.getZExtOrTrunc(DAG.getBitcast(MVT::i16, Elem[0]), dl, MVT::i32);
2565 E1 = DAG.getZExtOrTrunc(DAG.getBitcast(MVT::i16, Elem[1]), dl, MVT::i32);
2566 } else {
2567 E0 = Elem[0];
2568 E1 = Elem[1];
2569 }
2570 SDValue N = getInstr(Hexagon::A2_combine_ll, dl, MVT::i32, {E1, E0}, DAG);
2571 return DAG.getBitcast(VecTy, N);
2572 }
2573
2574 if (ElemTy == MVT::i8) {
2575 // First try generating a constant.
2576 if (AllConst) {
2577 uint32_t V = (Consts[0]->getZExtValue() & 0xFF) |
2578 (Consts[1]->getZExtValue() & 0xFF) << 8 |
2579 (Consts[2]->getZExtValue() & 0xFF) << 16 |
2580 Consts[3]->getZExtValue() << 24;
2581 return DAG.getBitcast(MVT::v4i8, DAG.getConstant(V, dl, MVT::i32));
2582 }
2583
2584 // Then try splat.
2585 bool IsSplat = true;
2586 for (unsigned i = First+1; i != Num; ++i) {
2587 if (Elem[i] == Elem[First] || isUndef(Elem[i]))
2588 continue;
2589 IsSplat = false;
2590 break;
2591 }
2592 if (IsSplat) {
2593 // Legalize the operand of SPLAT_VECTOR.
2594 SDValue Ext = DAG.getZExtOrTrunc(Elem[First], dl, MVT::i32);
2595 return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext);
2596 }
2597
2598 // Generate
2599 // (zxtb(Elem[0]) | (zxtb(Elem[1]) << 8)) |
2600 // (zxtb(Elem[2]) | (zxtb(Elem[3]) << 8)) << 16
2601 assert(Elem.size() == 4);
2602 SDValue Vs[4];
2603 for (unsigned i = 0; i != 4; ++i) {
2604 Vs[i] = DAG.getZExtOrTrunc(Elem[i], dl, MVT::i32);
2605 Vs[i] = DAG.getZeroExtendInReg(Vs[i], dl, MVT::i8);
2606 }
2607 SDValue S8 = DAG.getConstant(8, dl, MVT::i32);
2608 SDValue T0 = DAG.getNode(ISD::SHL, dl, MVT::i32, {Vs[1], S8});
2609 SDValue T1 = DAG.getNode(ISD::SHL, dl, MVT::i32, {Vs[3], S8});
2610 SDValue B0 = DAG.getNode(ISD::OR, dl, MVT::i32, {Vs[0], T0});
2611 SDValue B1 = DAG.getNode(ISD::OR, dl, MVT::i32, {Vs[2], T1});
2612
2613 SDValue R = getInstr(Hexagon::A2_combine_ll, dl, MVT::i32, {B1, B0}, DAG);
2614 return DAG.getBitcast(MVT::v4i8, R);
2615 }
2616
2617#ifndef NDEBUG
2618 dbgs() << "VecTy: " << VecTy << '\n';
2619#endif
2620 llvm_unreachable("Unexpected vector element type");
2621}
2622
2623SDValue
2624HexagonTargetLowering::buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl,
2625 MVT VecTy, SelectionDAG &DAG) const {
2626 MVT ElemTy = VecTy.getVectorElementType();
2627 assert(VecTy.getVectorNumElements() == Elem.size());
2628
2629 SmallVector<ConstantInt*,8> Consts(Elem.size());
2630 bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
2631
2632 unsigned First, Num = Elem.size();
2633 for (First = 0; First != Num; ++First) {
2634 if (!isUndef(Elem[First]))
2635 break;
2636 }
2637 if (First == Num)
2638 return DAG.getUNDEF(VecTy);
2639
2640 if (AllConst &&
2641 llvm::all_of(Consts, [](ConstantInt *CI) { return CI->isZero(); }))
2642 return getZero(dl, VecTy, DAG);
2643
2644 // First try splat if possible.
2645 if (ElemTy == MVT::i16 || ElemTy == MVT::f16) {
2646 bool IsSplat = true;
2647 for (unsigned i = First+1; i != Num; ++i) {
2648 if (Elem[i] == Elem[First] || isUndef(Elem[i]))
2649 continue;
2650 IsSplat = false;
2651 break;
2652 }
2653 if (IsSplat) {
2654 // Legalize the operand of SPLAT_VECTOR
2655 SDValue S = ElemTy == MVT::f16 ? DAG.getBitcast(MVT::i16, Elem[First])
2656 : Elem[First];
2657 SDValue Ext = DAG.getZExtOrTrunc(S, dl, MVT::i32);
2658 return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext);
2659 }
2660 }
2661
2662 // Then try constant.
2663 if (AllConst) {
2664 uint64_t Val = 0;
2665 unsigned W = ElemTy.getSizeInBits();
2666 uint64_t Mask = (1ull << W) - 1;
2667 for (unsigned i = 0; i != Num; ++i)
2668 Val = (Val << W) | (Consts[Num-1-i]->getZExtValue() & Mask);
2669 SDValue V0 = DAG.getConstant(Val, dl, MVT::i64);
2670 return DAG.getBitcast(VecTy, V0);
2671 }
2672
2673 // Build two 32-bit vectors and concatenate.
2674 MVT HalfTy = MVT::getVectorVT(ElemTy, Num/2);
2675 SDValue L = (ElemTy == MVT::i32)
2676 ? Elem[0]
2677 : buildVector32(Elem.take_front(Num/2), dl, HalfTy, DAG);
2678 SDValue H = (ElemTy == MVT::i32)
2679 ? Elem[1]
2680 : buildVector32(Elem.drop_front(Num/2), dl, HalfTy, DAG);
2681 return getCombine(H, L, dl, VecTy, DAG);
2682}
2683
2684SDValue
2685HexagonTargetLowering::extractVector(SDValue VecV, SDValue IdxV,
2686 const SDLoc &dl, MVT ValTy, MVT ResTy,
2687 SelectionDAG &DAG) const {
2688 MVT VecTy = ty(VecV);
2689 assert(!ValTy.isVector() ||
2690 VecTy.getVectorElementType() == ValTy.getVectorElementType());
2691 if (VecTy.getVectorElementType() == MVT::i1)
2692 return extractVectorPred(VecV, IdxV, dl, ValTy, ResTy, DAG);
2693
2694 unsigned VecWidth = VecTy.getSizeInBits();
2695 unsigned ValWidth = ValTy.getSizeInBits();
2696 unsigned ElemWidth = VecTy.getVectorElementType().getSizeInBits();
2697 assert((VecWidth % ElemWidth) == 0);
2698 assert(VecWidth == 32 || VecWidth == 64);
2699
2700 // Cast everything to scalar integer types.
2701 MVT ScalarTy = tyScalar(VecTy);
2702 VecV = DAG.getBitcast(ScalarTy, VecV);
2703
2704 SDValue WidthV = DAG.getConstant(ValWidth, dl, MVT::i32);
2705 SDValue ExtV;
2706
2707 if (auto *IdxN = dyn_cast<ConstantSDNode>(IdxV)) {
2708 unsigned Off = IdxN->getZExtValue() * ElemWidth;
2709 if (VecWidth == 64 && ValWidth == 32) {
2710 assert(Off == 0 || Off == 32);
2711 ExtV = Off == 0 ? LoHalf(VecV, DAG) : HiHalf(VecV, DAG);
2712 } else if (Off == 0 && (ValWidth % 8) == 0) {
2713 ExtV = DAG.getZeroExtendInReg(VecV, dl, tyScalar(ValTy));
2714 } else {
2715 SDValue OffV = DAG.getConstant(Off, dl, MVT::i32);
2716 // The return type of EXTRACTU must be the same as the type of the
2717 // input vector.
2718 ExtV = DAG.getNode(HexagonISD::EXTRACTU, dl, ScalarTy,
2719 {VecV, WidthV, OffV});
2720 }
2721 } else {
2722 if (ty(IdxV) != MVT::i32)
2723 IdxV = DAG.getZExtOrTrunc(IdxV, dl, MVT::i32);
2724 SDValue OffV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
2725 DAG.getConstant(ElemWidth, dl, MVT::i32));
2726 ExtV = DAG.getNode(HexagonISD::EXTRACTU, dl, ScalarTy,
2727 {VecV, WidthV, OffV});
2728 }
2729
2730 // Cast ExtV to the requested result type.
2731 ExtV = DAG.getZExtOrTrunc(ExtV, dl, tyScalar(ResTy));
2732 ExtV = DAG.getBitcast(ResTy, ExtV);
2733 return ExtV;
2734}
2735
2736SDValue
2737HexagonTargetLowering::extractVectorPred(SDValue VecV, SDValue IdxV,
2738 const SDLoc &dl, MVT ValTy, MVT ResTy,
2739 SelectionDAG &DAG) const {
2740 // Special case for v{8,4,2}i1 (the only boolean vectors legal in Hexagon
2741 // without any coprocessors).
2742 MVT VecTy = ty(VecV);
2743 unsigned VecWidth = VecTy.getSizeInBits();
2744 unsigned ValWidth = ValTy.getSizeInBits();
2745 assert(VecWidth == VecTy.getVectorNumElements() &&
2746 "Vector elements should equal vector width size");
2747 assert(VecWidth == 8 || VecWidth == 4 || VecWidth == 2);
2748
2749 // Check if this is an extract of the lowest bit.
2750 if (isNullConstant(IdxV) && ValTy.getSizeInBits() == 1) {
2751 // Extracting the lowest bit is a no-op, but it changes the type,
2752 // so it must be kept as an operation to avoid errors related to
2753 // type mismatches.
2754 return DAG.getNode(HexagonISD::TYPECAST, dl, MVT::i1, VecV);
2755 }
2756
2757 // If the value extracted is a single bit, use tstbit.
2758 if (ValWidth == 1) {
2759 SDValue A0 = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {VecV}, DAG);
2760 SDValue M0 = DAG.getConstant(8 / VecWidth, dl, MVT::i32);
2761 SDValue I0 = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, M0);
2762 return DAG.getNode(HexagonISD::TSTBIT, dl, MVT::i1, A0, I0);
2763 }
2764
2765 // Each bool vector (v2i1, v4i1, v8i1) always occupies 8 bits in
2766 // a predicate register. The elements of the vector are repeated
2767 // in the register (if necessary) so that the total number is 8.
2768 // The extracted subvector will need to be expanded in such a way.
2769 unsigned Scale = VecWidth / ValWidth;
2770
2771 // Generate (p2d VecV) >> 8*Idx to move the interesting bytes to
2772 // position 0.
2773 assert(ty(IdxV) == MVT::i32);
2774 unsigned VecRep = 8 / VecWidth;
2775 SDValue S0 = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
2776 DAG.getConstant(8*VecRep, dl, MVT::i32));
2777 SDValue T0 = DAG.getNode(HexagonISD::P2D, dl, MVT::i64, VecV);
2778 SDValue T1 = DAG.getNode(ISD::SRL, dl, MVT::i64, T0, S0);
2779 while (Scale > 1) {
2780 // The longest possible subvector is at most 32 bits, so it is always
2781 // contained in the low subregister.
2782 T1 = LoHalf(T1, DAG);
2783 T1 = expandPredicate(T1, dl, DAG);
2784 Scale /= 2;
2785 }
2786
2787 return DAG.getNode(HexagonISD::D2P, dl, ResTy, T1);
2788}
2789
2790SDValue
2791HexagonTargetLowering::insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
2792 const SDLoc &dl, MVT ValTy,
2793 SelectionDAG &DAG) const {
2794 MVT VecTy = ty(VecV);
2795 if (VecTy.getVectorElementType() == MVT::i1)
2796 return insertVectorPred(VecV, ValV, IdxV, dl, ValTy, DAG);
2797
2798 unsigned VecWidth = VecTy.getSizeInBits();
2799 unsigned ValWidth = ValTy.getSizeInBits();
2800 assert(VecWidth == 32 || VecWidth == 64);
2801 assert((VecWidth % ValWidth) == 0);
2802
2803 // Cast everything to scalar integer types.
2804 MVT ScalarTy = MVT::getIntegerVT(VecWidth);
2805 // The actual type of ValV may be different than ValTy (which is related
2806 // to the vector type).
2807 unsigned VW = ty(ValV).getSizeInBits();
2808 ValV = DAG.getBitcast(MVT::getIntegerVT(VW), ValV);
2809 VecV = DAG.getBitcast(ScalarTy, VecV);
2810 if (VW != VecWidth)
2811 ValV = DAG.getAnyExtOrTrunc(ValV, dl, ScalarTy);
2812
2813 SDValue WidthV = DAG.getConstant(ValWidth, dl, MVT::i32);
2814 SDValue InsV;
2815
2816 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(IdxV)) {
2817 unsigned W = C->getZExtValue() * ValWidth;
2818 SDValue OffV = DAG.getConstant(W, dl, MVT::i32);
2819 InsV = DAG.getNode(HexagonISD::INSERT, dl, ScalarTy,
2820 {VecV, ValV, WidthV, OffV});
2821 } else {
2822 if (ty(IdxV) != MVT::i32)
2823 IdxV = DAG.getZExtOrTrunc(IdxV, dl, MVT::i32);
2824 SDValue OffV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, WidthV);
2825 InsV = DAG.getNode(HexagonISD::INSERT, dl, ScalarTy,
2826 {VecV, ValV, WidthV, OffV});
2827 }
2828
2829 return DAG.getNode(ISD::BITCAST, dl, VecTy, InsV);
2830}
2831
2832SDValue
2833HexagonTargetLowering::insertVectorPred(SDValue VecV, SDValue ValV,
2834 SDValue IdxV, const SDLoc &dl,
2835 MVT ValTy, SelectionDAG &DAG) const {
2836 MVT VecTy = ty(VecV);
2837 unsigned VecLen = VecTy.getVectorNumElements();
2838
2839 if (ValTy == MVT::i1) {
2840 SDValue ToReg = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {VecV}, DAG);
2841 SDValue Ext = DAG.getSExtOrTrunc(ValV, dl, MVT::i32);
2842 SDValue Width = DAG.getConstant(8 / VecLen, dl, MVT::i32);
2843 SDValue Idx = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, Width);
2844 SDValue Ins =
2845 DAG.getNode(HexagonISD::INSERT, dl, MVT::i32, {ToReg, Ext, Width, Idx});
2846 return getInstr(Hexagon::C2_tfrrp, dl, VecTy, {Ins}, DAG);
2847 }
2848
2849 assert(ValTy.getVectorElementType() == MVT::i1);
2850 SDValue ValR = ValTy.isVector()
2851 ? DAG.getNode(HexagonISD::P2D, dl, MVT::i64, ValV)
2852 : DAG.getSExtOrTrunc(ValV, dl, MVT::i64);
2853
2854 unsigned Scale = VecLen / ValTy.getVectorNumElements();
2855 assert(Scale > 1);
2856
2857 for (unsigned R = Scale; R > 1; R /= 2) {
2858 ValR = contractPredicate(ValR, dl, DAG);
2859 ValR = getCombine(DAG.getUNDEF(MVT::i32), ValR, dl, MVT::i64, DAG);
2860 }
2861
2862 SDValue Width = DAG.getConstant(64 / Scale, dl, MVT::i32);
2863 SDValue Idx = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, Width);
2864 SDValue VecR = DAG.getNode(HexagonISD::P2D, dl, MVT::i64, VecV);
2865 SDValue Ins =
2866 DAG.getNode(HexagonISD::INSERT, dl, MVT::i64, {VecR, ValR, Width, Idx});
2867 return DAG.getNode(HexagonISD::D2P, dl, VecTy, Ins);
2868}
2869
2870SDValue
2871HexagonTargetLowering::expandPredicate(SDValue Vec32, const SDLoc &dl,
2872 SelectionDAG &DAG) const {
2873 assert(ty(Vec32).getSizeInBits() == 32);
2874 if (isUndef(Vec32))
2875 return DAG.getUNDEF(MVT::i64);
2876 SDValue P = DAG.getBitcast(MVT::v4i8, Vec32);
2877 SDValue X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i16, P);
2878 return DAG.getBitcast(MVT::i64, X);
2879}
2880
2881SDValue
2882HexagonTargetLowering::contractPredicate(SDValue Vec64, const SDLoc &dl,
2883 SelectionDAG &DAG) const {
2884 assert(ty(Vec64).getSizeInBits() == 64);
2885 if (isUndef(Vec64))
2886 return DAG.getUNDEF(MVT::i32);
2887 // Collect even bytes:
2888 SDValue A = DAG.getBitcast(MVT::v8i8, Vec64);
2889 SDValue S = DAG.getVectorShuffle(MVT::v8i8, dl, A, DAG.getUNDEF(MVT::v8i8),
2890 {0, 2, 4, 6, 1, 3, 5, 7});
2891 return extractVector(S, DAG.getConstant(0, dl, MVT::i32), dl, MVT::v4i8,
2892 MVT::i32, DAG);
2893}
2894
2895SDValue
2896HexagonTargetLowering::getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG)
2897 const {
2898 if (Ty.isVector()) {
2899 unsigned W = Ty.getSizeInBits();
2900 if (W <= 64)
2901 return DAG.getBitcast(Ty, DAG.getConstant(0, dl, MVT::getIntegerVT(W)));
2902 return DAG.getNode(ISD::SPLAT_VECTOR, dl, Ty, getZero(dl, MVT::i32, DAG));
2903 }
2904
2905 if (Ty.isInteger())
2906 return DAG.getConstant(0, dl, Ty);
2907 if (Ty.isFloatingPoint())
2908 return DAG.getConstantFP(0.0, dl, Ty);
2909 llvm_unreachable("Invalid type for zero");
2910}
2911
2912SDValue
2913HexagonTargetLowering::appendUndef(SDValue Val, MVT ResTy, SelectionDAG &DAG)
2914 const {
2915 MVT ValTy = ty(Val);
2917
2918 unsigned ValLen = ValTy.getVectorNumElements();
2919 unsigned ResLen = ResTy.getVectorNumElements();
2920 if (ValLen == ResLen)
2921 return Val;
2922
2923 const SDLoc &dl(Val);
2924 assert(ValLen < ResLen);
2925 assert(ResLen % ValLen == 0);
2926
2927 SmallVector<SDValue, 4> Concats = {Val};
2928 for (unsigned i = 1, e = ResLen / ValLen; i < e; ++i)
2929 Concats.push_back(DAG.getUNDEF(ValTy));
2930
2931 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResTy, Concats);
2932}
2933
2934SDValue
2935HexagonTargetLowering::getCombine(SDValue Hi, SDValue Lo, const SDLoc &dl,
2936 MVT ResTy, SelectionDAG &DAG) const {
2937 MVT ElemTy = ty(Hi);
2938 assert(ElemTy == ty(Lo));
2939
2940 if (!ElemTy.isVector()) {
2941 assert(ElemTy.isScalarInteger());
2942 MVT PairTy = MVT::getIntegerVT(2 * ElemTy.getSizeInBits());
2943 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, PairTy, Lo, Hi);
2944 return DAG.getBitcast(ResTy, Pair);
2945 }
2946
2947 unsigned Width = ElemTy.getSizeInBits();
2948 MVT IntTy = MVT::getIntegerVT(Width);
2949 MVT PairTy = MVT::getIntegerVT(2 * Width);
2950 SDValue Pair =
2952 {DAG.getBitcast(IntTy, Lo), DAG.getBitcast(IntTy, Hi)});
2953 return DAG.getBitcast(ResTy, Pair);
2954}
2955
2956SDValue
2958 MVT VecTy = ty(Op);
2959 unsigned BW = VecTy.getSizeInBits();
2960 const SDLoc &dl(Op);
2962 for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i)
2963 Ops.push_back(Op.getOperand(i));
2964
2965 if (BW == 32)
2966 return buildVector32(Ops, dl, VecTy, DAG);
2967 if (BW == 64)
2968 return buildVector64(Ops, dl, VecTy, DAG);
2969
2970 if (VecTy == MVT::v8i1 || VecTy == MVT::v4i1 || VecTy == MVT::v2i1) {
2971 // Check if this is a special case or all-0 or all-1.
2972 bool All0 = true, All1 = true;
2973 for (SDValue P : Ops) {
2974 auto *CN = dyn_cast<ConstantSDNode>(P.getNode());
2975 if (CN == nullptr) {
2976 All0 = All1 = false;
2977 break;
2978 }
2979 uint32_t C = CN->getZExtValue();
2980 All0 &= (C == 0);
2981 All1 &= (C == 1);
2982 }
2983 if (All0)
2984 return DAG.getNode(HexagonISD::PFALSE, dl, VecTy);
2985 if (All1)
2986 return DAG.getNode(HexagonISD::PTRUE, dl, VecTy);
2987
2988 // For each i1 element in the resulting predicate register, put 1
2989 // shifted by the index of the element into a general-purpose register,
2990 // then or them together and transfer it back into a predicate register.
2991 SDValue Rs[8];
2992 SDValue Z = getZero(dl, MVT::i32, DAG);
2993 // Always produce 8 bits, repeat inputs if necessary.
2994 unsigned Rep = 8 / VecTy.getVectorNumElements();
2995 for (unsigned i = 0; i != 8; ++i) {
2996 SDValue S = DAG.getConstant(1ull << i, dl, MVT::i32);
2997 Rs[i] = DAG.getSelect(dl, MVT::i32, Ops[i/Rep], S, Z);
2998 }
2999 for (ArrayRef<SDValue> A(Rs); A.size() != 1; A = A.drop_back(A.size()/2)) {
3000 for (unsigned i = 0, e = A.size()/2; i != e; ++i)
3001 Rs[i] = DAG.getNode(ISD::OR, dl, MVT::i32, Rs[2*i], Rs[2*i+1]);
3002 }
3003 // Move the value directly to a predicate register.
3004 return getInstr(Hexagon::C2_tfrrp, dl, VecTy, {Rs[0]}, DAG);
3005 }
3006
3007 return SDValue();
3008}
3009
3010SDValue
3012 SelectionDAG &DAG) const {
3013 MVT VecTy = ty(Op);
3014 const SDLoc &dl(Op);
3015 if (VecTy.getSizeInBits() == 64) {
3016 assert(Op.getNumOperands() == 2);
3017 return getCombine(Op.getOperand(1), Op.getOperand(0), dl, VecTy, DAG);
3018 }
3019
3020 MVT ElemTy = VecTy.getVectorElementType();
3021 if (ElemTy == MVT::i1) {
3022 assert(VecTy == MVT::v2i1 || VecTy == MVT::v4i1 || VecTy == MVT::v8i1);
3023 MVT OpTy = ty(Op.getOperand(0));
3024 // Scale is how many times the operands need to be contracted to match
3025 // the representation in the target register.
3026 unsigned Scale = VecTy.getVectorNumElements() / OpTy.getVectorNumElements();
3027 assert(Scale == Op.getNumOperands() && Scale > 1);
3028
3029 // First, convert all bool vectors to integers, then generate pairwise
3030 // inserts to form values of doubled length. Up until there are only
3031 // two values left to concatenate, all of these values will fit in a
3032 // 32-bit integer, so keep them as i32 to use 32-bit inserts.
3033 SmallVector<SDValue,4> Words[2];
3034 unsigned IdxW = 0;
3035
3036 for (SDValue P : Op.getNode()->op_values()) {
3037 SDValue W = DAG.getNode(HexagonISD::P2D, dl, MVT::i64, P);
3038 for (unsigned R = Scale; R > 1; R /= 2) {
3039 W = contractPredicate(W, dl, DAG);
3040 W = getCombine(DAG.getUNDEF(MVT::i32), W, dl, MVT::i64, DAG);
3041 }
3042 W = LoHalf(W, DAG);
3043 Words[IdxW].push_back(W);
3044 }
3045
3046 while (Scale > 2) {
3047 SDValue WidthV = DAG.getConstant(64 / Scale, dl, MVT::i32);
3048 Words[IdxW ^ 1].clear();
3049
3050 for (unsigned i = 0, e = Words[IdxW].size(); i != e; i += 2) {
3051 SDValue W0 = Words[IdxW][i], W1 = Words[IdxW][i+1];
3052 // Insert W1 into W0 right next to the significant bits of W0.
3053 SDValue T = DAG.getNode(HexagonISD::INSERT, dl, MVT::i32,
3054 {W0, W1, WidthV, WidthV});
3055 Words[IdxW ^ 1].push_back(T);
3056 }
3057 IdxW ^= 1;
3058 Scale /= 2;
3059 }
3060
3061 // At this point there should only be two words left, and Scale should be 2.
3062 assert(Scale == 2 && Words[IdxW].size() == 2);
3063
3064 SDValue WW = getCombine(Words[IdxW][1], Words[IdxW][0], dl, MVT::i64, DAG);
3065 return DAG.getNode(HexagonISD::D2P, dl, VecTy, WW);
3066 }
3067
3068 return SDValue();
3069}
3070
3071SDValue
3073 SelectionDAG &DAG) const {
3074 SDValue Vec = Op.getOperand(0);
3075 MVT ElemTy = ty(Vec).getVectorElementType();
3076 return extractVector(Vec, Op.getOperand(1), SDLoc(Op), ElemTy, ty(Op), DAG);
3077}
3078
3079SDValue
3081 SelectionDAG &DAG) const {
3082 return extractVector(Op.getOperand(0), Op.getOperand(1), SDLoc(Op),
3083 ty(Op), ty(Op), DAG);
3084}
3085
3086SDValue
3088 SelectionDAG &DAG) const {
3089 return insertVector(Op.getOperand(0), Op.getOperand(1), Op.getOperand(2),
3090 SDLoc(Op), ty(Op).getVectorElementType(), DAG);
3091}
3092
3093SDValue
3095 SelectionDAG &DAG) const {
3096 SDValue ValV = Op.getOperand(1);
3097 return insertVector(Op.getOperand(0), ValV, Op.getOperand(2),
3098 SDLoc(Op), ty(ValV), DAG);
3099}
3100
3101bool
3103 // Assuming the caller does not have either a signext or zeroext modifier, and
3104 // only one value is accepted, any reasonable truncation is allowed.
3105 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
3106 return false;
3107
3108 // FIXME: in principle up to 64-bit could be made safe, but it would be very
3109 // fragile at the moment: any support for multiple value returns would be
3110 // liable to disallow tail calls involving i64 -> iN truncation in many cases.
3111 return Ty1->getPrimitiveSizeInBits() <= 32;
3112}
3113
3114SDValue
3116 MVT Ty = ty(Op);
3117 const SDLoc &dl(Op);
3118 LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
3119 MVT MemTy = LN->getMemoryVT().getSimpleVT();
3121
3122 bool LoadPred = MemTy == MVT::v2i1 || MemTy == MVT::v4i1 || MemTy == MVT::v8i1;
3123 if (LoadPred) {
3124 SDValue NL = DAG.getLoad(
3125 LN->getAddressingMode(), ISD::ZEXTLOAD, MVT::i32, dl, LN->getChain(),
3126 LN->getBasePtr(), LN->getOffset(), LN->getPointerInfo(),
3127 /*MemoryVT*/ MVT::i8, LN->getAlign(), LN->getMemOperand()->getFlags(),
3128 LN->getAAInfo(), LN->getRanges());
3129 LN = cast<LoadSDNode>(NL.getNode());
3130 }
3131
3132 Align ClaimAlign = LN->getAlign();
3133 if (!validateConstPtrAlignment(LN->getBasePtr(), ClaimAlign, dl, DAG))
3134 return replaceMemWithUndef(Op, DAG);
3135
3136 // Call LowerUnalignedLoad for all loads, it recognizes loads that
3137 // don't need extra aligning.
3138 SDValue LU = LowerUnalignedLoad(SDValue(LN, 0), DAG);
3139 if (LoadPred) {
3140 SDValue TP = getInstr(Hexagon::C2_tfrrp, dl, MemTy, {LU}, DAG);
3141 if (ET == ISD::SEXTLOAD) {
3142 TP = DAG.getSExtOrTrunc(TP, dl, Ty);
3143 } else if (ET != ISD::NON_EXTLOAD) {
3144 TP = DAG.getZExtOrTrunc(TP, dl, Ty);
3145 }
3146 SDValue Ch = cast<LoadSDNode>(LU.getNode())->getChain();
3147 return DAG.getMergeValues({TP, Ch}, dl);
3148 }
3149 return LU;
3150}
3151
3152SDValue
3154 const SDLoc &dl(Op);
3155 StoreSDNode *SN = cast<StoreSDNode>(Op.getNode());
3156 SDValue Val = SN->getValue();
3157 MVT Ty = ty(Val);
3158
3159 if (Ty == MVT::v2i1 || Ty == MVT::v4i1 || Ty == MVT::v8i1) {
3160 // Store the exact predicate (all bits).
3161 SDValue TR = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {Val}, DAG);
3162 SDValue NS = DAG.getTruncStore(SN->getChain(), dl, TR, SN->getBasePtr(),
3163 MVT::i8, SN->getMemOperand());
3164 if (SN->isIndexed()) {
3165 NS = DAG.getIndexedStore(NS, dl, SN->getBasePtr(), SN->getOffset(),
3166 SN->getAddressingMode());
3167 }
3168 SN = cast<StoreSDNode>(NS.getNode());
3169 }
3170
3171 Align ClaimAlign = SN->getAlign();
3172 if (!validateConstPtrAlignment(SN->getBasePtr(), ClaimAlign, dl, DAG))
3173 return replaceMemWithUndef(Op, DAG);
3174
3175 MVT StoreTy = SN->getMemoryVT().getSimpleVT();
3176 Align NeedAlign = Subtarget.getTypeAlignment(StoreTy);
3177 if (ClaimAlign < NeedAlign)
3178 return expandUnalignedStore(SN, DAG);
3179 return SDValue(SN, 0);
3180}
3181
3182SDValue
3184 const {
3185 LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
3186 MVT LoadTy = ty(Op);
3187 unsigned NeedAlign = Subtarget.getTypeAlignment(LoadTy).value();
3188 unsigned HaveAlign = LN->getAlign().value();
3189 if (HaveAlign >= NeedAlign)
3190 return Op;
3191
3192 const SDLoc &dl(Op);
3193 const DataLayout &DL = DAG.getDataLayout();
3194 LLVMContext &Ctx = *DAG.getContext();
3195
3196 // If the load aligning is disabled or the load can be broken up into two
3197 // smaller legal loads, do the default (target-independent) expansion.
3198 bool DoDefault = false;
3199 // Handle it in the default way if this is an indexed load.
3200 if (!LN->isUnindexed())
3201 DoDefault = true;
3202
3203 if (!AlignLoads) {
3205 *LN->getMemOperand()))
3206 return Op;
3207 DoDefault = true;
3208 }
3209 if (!DoDefault && (2 * HaveAlign) == NeedAlign) {
3210 // The PartTy is the equivalent of "getLoadableTypeOfSize(HaveAlign)".
3211 MVT PartTy = HaveAlign <= 8 ? MVT::getIntegerVT(8 * HaveAlign)
3212 : MVT::getVectorVT(MVT::i8, HaveAlign);
3213 DoDefault =
3214 allowsMemoryAccessForAlignment(Ctx, DL, PartTy, *LN->getMemOperand());
3215 }
3216 if (DoDefault) {
3217 std::pair<SDValue, SDValue> P = expandUnalignedLoad(LN, DAG);
3218 return DAG.getMergeValues({P.first, P.second}, dl);
3219 }
3220
3221 // The code below generates two loads, both aligned as NeedAlign, and
3222 // with the distance of NeedAlign between them. For that to cover the
3223 // bits that need to be loaded (and without overlapping), the size of
3224 // the loads should be equal to NeedAlign. This is true for all loadable
3225 // types, but add an assertion in case something changes in the future.
3226 assert(LoadTy.getSizeInBits() == 8*NeedAlign);
3227
3228 unsigned LoadLen = NeedAlign;
3229 SDValue Base = LN->getBasePtr();
3230 SDValue Chain = LN->getChain();
3231 auto BO = getBaseAndOffset(Base);
3232 unsigned BaseOpc = BO.first.getOpcode();
3233 if (BaseOpc == HexagonISD::VALIGNADDR && BO.second % LoadLen == 0)
3234 return Op;
3235
3236 if (BO.second % LoadLen != 0) {
3237 BO.first = DAG.getNode(ISD::ADD, dl, MVT::i32, BO.first,
3238 DAG.getConstant(BO.second % LoadLen, dl, MVT::i32));
3239 BO.second -= BO.second % LoadLen;
3240 }
3241 SDValue BaseNoOff = (BaseOpc != HexagonISD::VALIGNADDR)
3242 ? DAG.getNode(HexagonISD::VALIGNADDR, dl, MVT::i32, BO.first,
3243 DAG.getConstant(NeedAlign, dl, MVT::i32))
3244 : BO.first;
3245 SDValue Base0 =
3246 DAG.getMemBasePlusOffset(BaseNoOff, TypeSize::getFixed(BO.second), dl);
3247 SDValue Base1 = DAG.getMemBasePlusOffset(
3248 BaseNoOff, TypeSize::getFixed(BO.second + LoadLen), dl);
3249
3250 MachineMemOperand *WideMMO = nullptr;
3251 if (MachineMemOperand *MMO = LN->getMemOperand()) {
3253 WideMMO = MF.getMachineMemOperand(
3254 MMO->getPointerInfo(), MMO->getFlags(), 2 * LoadLen, Align(LoadLen),
3255 MMO->getAAInfo(), MMO->getRanges(), MMO->getSyncScopeID(),
3256 MMO->getSuccessOrdering(), MMO->getFailureOrdering());
3257 }
3258
3259 SDValue Load0 = DAG.getLoad(LoadTy, dl, Chain, Base0, WideMMO);
3260 SDValue Load1 = DAG.getLoad(LoadTy, dl, Chain, Base1, WideMMO);
3261
3262 SDValue Aligned = DAG.getNode(HexagonISD::VALIGN, dl, LoadTy,
3263 {Load1, Load0, BaseNoOff.getOperand(0)});
3264 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
3265 Load0.getValue(1), Load1.getValue(1));
3266 SDValue M = DAG.getMergeValues({Aligned, NewChain}, dl);
3267 return M;
3268}
3269
3270SDValue
3272 SDValue X = Op.getOperand(0), Y = Op.getOperand(1);
3273 auto *CY = dyn_cast<ConstantSDNode>(Y);
3274 if (!CY)
3275 return SDValue();
3276
3277 const SDLoc &dl(Op);
3278 SDVTList VTs = Op.getNode()->getVTList();
3279 assert(VTs.NumVTs == 2);
3280 assert(VTs.VTs[1] == MVT::i1);
3281 unsigned Opc = Op.getOpcode();
3282
3283 if (CY) {
3284 uint64_t VY = CY->getZExtValue();
3285 assert(VY != 0 && "This should have been folded");
3286 // X +/- 1
3287 if (VY != 1)
3288 return SDValue();
3289
3290 if (Opc == ISD::UADDO) {
3291 SDValue Op = DAG.getNode(ISD::ADD, dl, VTs.VTs[0], {X, Y});
3292 SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op, getZero(dl, ty(Op), DAG),
3293 ISD::SETEQ);
3294 return DAG.getMergeValues({Op, Ov}, dl);
3295 }
3296 if (Opc == ISD::USUBO) {
3297 SDValue Op = DAG.getNode(ISD::SUB, dl, VTs.VTs[0], {X, Y});
3298 SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op,
3299 DAG.getAllOnesConstant(dl, ty(Op)), ISD::SETEQ);
3300 return DAG.getMergeValues({Op, Ov}, dl);
3301 }
3302 }
3303
3304 return SDValue();
3305}
3306
3308 SelectionDAG &DAG) const {
3309 const SDLoc &dl(Op);
3310 unsigned Opc = Op.getOpcode();
3311 SDValue X = Op.getOperand(0), Y = Op.getOperand(1), C = Op.getOperand(2);
3312
3313 if (Opc == ISD::UADDO_CARRY)
3314 return DAG.getNode(HexagonISD::ADDC, dl, Op.getNode()->getVTList(),
3315 { X, Y, C });
3316
3317 EVT CarryTy = C.getValueType();
3318 SDValue SubC = DAG.getNode(HexagonISD::SUBC, dl, Op.getNode()->getVTList(),
3319 { X, Y, DAG.getLogicalNOT(dl, C, CarryTy) });
3320 SDValue Out[] = { SubC.getValue(0),
3321 DAG.getLogicalNOT(dl, SubC.getValue(1), CarryTy) };
3322 return DAG.getMergeValues(Out, dl);
3323}
3324
3325SDValue
3327 SDValue Chain = Op.getOperand(0);
3328 SDValue Offset = Op.getOperand(1);
3329 SDValue Handler = Op.getOperand(2);
3330 SDLoc dl(Op);
3331 auto PtrVT = getPointerTy(DAG.getDataLayout());
3332
3333 // Mark function as containing a call to EH_RETURN.
3334 HexagonMachineFunctionInfo *FuncInfo =
3336 FuncInfo->setHasEHReturn();
3337
3338 unsigned OffsetReg = Hexagon::R28;
3339
3340 SDValue StoreAddr =
3341 DAG.getNode(ISD::ADD, dl, PtrVT, DAG.getRegister(Hexagon::R30, PtrVT),
3342 DAG.getIntPtrConstant(4, dl));
3343 Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo());
3344 Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset);
3345
3346 // Not needed we already use it as explicit input to EH_RETURN.
3347 // MF.getRegInfo().addLiveOut(OffsetReg);
3348
3349 return DAG.getNode(HexagonISD::EH_RETURN, dl, MVT::Other, Chain);
3350}
3351
3352SDValue
3354 unsigned Opc = Op.getOpcode();
3355
3356 // Handle INLINEASM first.
3358 return LowerINLINEASM(Op, DAG);
3359
3360 if (isHvxOperation(Op.getNode(), DAG)) {
3361 // If HVX lowering returns nothing, try the default lowering.
3362 if (SDValue V = LowerHvxOperation(Op, DAG))
3363 return V;
3364 }
3365
3366 switch (Opc) {
3367 default:
3368#ifndef NDEBUG
3369 Op.getNode()->dumpr(&DAG);
3371 errs() << "Error: check for a non-legal type in this operation\n";
3372#endif
3373 llvm_unreachable("Should not custom lower this!");
3374
3375 case ISD::FDIV:
3376 return LowerFDIV(Op, DAG);
3377 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
3382 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
3383 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
3384 case ISD::BITCAST: return LowerBITCAST(Op, DAG);
3385 case ISD::LOAD: return LowerLoad(Op, DAG);
3386 case ISD::STORE: return LowerStore(Op, DAG);
3387 case ISD::UADDO:
3388 case ISD::USUBO: return LowerUAddSubO(Op, DAG);
3389 case ISD::UADDO_CARRY:
3390 case ISD::USUBO_CARRY: return LowerUAddSubOCarry(Op, DAG);
3391 case ISD::SRA:
3392 case ISD::SHL:
3393 case ISD::SRL: return LowerVECTOR_SHIFT(Op, DAG);
3394 case ISD::ROTL: return LowerROTL(Op, DAG);
3395 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
3396 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
3397 case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
3398 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
3399 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
3401 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
3402 case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
3403 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
3405 case ISD::VACOPY: return LowerVACOPY(Op, DAG);
3406 case ISD::VASTART: return LowerVASTART(Op, DAG);
3408 case ISD::SETCC: return LowerSETCC(Op, DAG);
3409 case ISD::VSELECT: return LowerVSELECT(Op, DAG);
3411 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG);
3412 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG);
3415 break;
3416 }
3417
3418 return SDValue();
3419}
3420
3421void
3424 SelectionDAG &DAG) const {
3425 if (isHvxOperation(N, DAG)) {
3426 LowerHvxOperationWrapper(N, Results, DAG);
3427 if (!Results.empty())
3428 return;
3429 }
3430
3431 SDValue Op(N, 0);
3432 unsigned Opc = N->getOpcode();
3433
3434 switch (Opc) {
3435 case HexagonISD::SSAT:
3436 case HexagonISD::USAT:
3437 Results.push_back(opJoin(SplitVectorOp(Op, DAG), SDLoc(Op), DAG));
3438 break;
3439 case ISD::STORE:
3440 // We are only custom-lowering stores to verify the alignment of the
3441 // address if it is a compile-time constant. Since a store can be
3442 // modified during type-legalization (the value being stored may need
3443 // legalization), return empty Results here to indicate that we don't
3444 // really make any changes in the custom lowering.
3445 return;
3446 default:
3448 break;
3449 }
3450}
3451
3452void
3455 SelectionDAG &DAG) const {
3456 if (isHvxOperation(N, DAG)) {
3457 ReplaceHvxNodeResults(N, Results, DAG);
3458 if (!Results.empty())
3459 return;
3460 }
3461
3462 const SDLoc &dl(N);
3463 switch (N->getOpcode()) {
3464 case ISD::SRL:
3465 case ISD::SRA:
3466 case ISD::SHL:
3467 return;
3468 case ISD::BITCAST:
3469 // Handle a bitcast from v8i1 to i8.
3470 if (N->getValueType(0) == MVT::i8) {
3471 if (N->getOperand(0).getValueType() == MVT::v8i1) {
3472 SDValue P = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32,
3473 N->getOperand(0), DAG);
3474 SDValue T = DAG.getAnyExtOrTrunc(P, dl, MVT::i8);
3475 Results.push_back(T);
3476 }
3477 }
3478 break;
3479 }
3480}
3481
3482SDValue
3484 DAGCombinerInfo &DCI) const {
3485 if (isHvxOperation(N, DCI.DAG)) {
3486 if (SDValue V = PerformHvxDAGCombine(N, DCI))
3487 return V;
3488 return SDValue();
3489 }
3490
3491 SDValue Op(N, 0);
3492 const SDLoc &dl(Op);
3493 unsigned Opc = Op.getOpcode();
3494
3495 if (Opc == ISD::TRUNCATE) {
3496 SDValue Op0 = Op.getOperand(0);
3497 // fold (truncate (build pair x, y)) -> (truncate x) or x
3498 if (Op0.getOpcode() == ISD::BUILD_PAIR) {
3499 EVT TruncTy = Op.getValueType();
3500 SDValue Elem0 = Op0.getOperand(0);
3501 // if we match the low element of the pair, just return it.
3502 if (Elem0.getValueType() == TruncTy)
3503 return Elem0;
3504 // otherwise, if the low part is still too large, apply the truncate.
3505 if (Elem0.getValueType().bitsGT(TruncTy))
3506 return DCI.DAG.getNode(ISD::TRUNCATE, dl, TruncTy, Elem0);
3507 }
3508 }
3509
3510 if (DCI.isBeforeLegalizeOps())
3511 return SDValue();
3512
3513 if (Opc == HexagonISD::P2D) {
3514 SDValue P = Op.getOperand(0);
3515 switch (P.getOpcode()) {
3516 case HexagonISD::PTRUE:
3517 return DCI.DAG.getAllOnesConstant(dl, ty(Op));
3518 case HexagonISD::PFALSE:
3519 return getZero(dl, ty(Op), DCI.DAG);
3520 default:
3521 break;
3522 }
3523 } else if (Opc == ISD::VSELECT) {
3524 // This is pretty much duplicated in HexagonISelLoweringHVX...
3525 //
3526 // (vselect (xor x, ptrue), v0, v1) -> (vselect x, v1, v0)
3527 SDValue Cond = Op.getOperand(0);
3528 if (Cond->getOpcode() == ISD::XOR) {
3529 SDValue C0 = Cond.getOperand(0), C1 = Cond.getOperand(1);
3530 if (C1->getOpcode() == HexagonISD::PTRUE) {
3531 SDValue VSel = DCI.DAG.getNode(ISD::VSELECT, dl, ty(Op), C0,
3532 Op.getOperand(2), Op.getOperand(1));
3533 return VSel;
3534 }
3535 }
3536 } else if (Opc == ISD::TRUNCATE) {
3537 SDValue Op0 = Op.getOperand(0);
3538 // fold (truncate (build pair x, y)) -> (truncate x) or x
3539 if (Op0.getOpcode() == ISD::BUILD_PAIR) {
3540 MVT TruncTy = ty(Op);
3541 SDValue Elem0 = Op0.getOperand(0);
3542 // if we match the low element of the pair, just return it.
3543 if (ty(Elem0) == TruncTy)
3544 return Elem0;
3545 // otherwise, if the low part is still too large, apply the truncate.
3546 if (ty(Elem0).bitsGT(TruncTy))
3547 return DCI.DAG.getNode(ISD::TRUNCATE, dl, TruncTy, Elem0);
3548 }
3549 } else if (Opc == ISD::OR) {
3550 // fold (or (shl xx, s), (zext y)) -> (COMBINE (shl xx, s-32), y)
3551 // if s >= 32
3552 auto fold0 = [&, this](SDValue Op) {
3553 if (ty(Op) != MVT::i64)
3554 return SDValue();
3555 SDValue Shl = Op.getOperand(0);
3556 SDValue Zxt = Op.getOperand(1);
3557 if (Shl.getOpcode() != ISD::SHL)
3558 std::swap(Shl, Zxt);
3559
3560 if (Shl.getOpcode() != ISD::SHL || Zxt.getOpcode() != ISD::ZERO_EXTEND)
3561 return SDValue();
3562
3563 SDValue Z = Zxt.getOperand(0);
3564 auto *Amt = dyn_cast<ConstantSDNode>(Shl.getOperand(1));
3565 if (Amt && Amt->getZExtValue() >= 32 && ty(Z).getSizeInBits() <= 32) {
3566 unsigned A = Amt->getZExtValue();
3567 SDValue S = Shl.getOperand(0);
3568 SDValue T0 = DCI.DAG.getNode(ISD::SHL, dl, ty(S), S,
3569 DCI.DAG.getConstant(A - 32, dl, MVT::i32));
3570 SDValue T1 = DCI.DAG.getZExtOrTrunc(T0, dl, MVT::i32);
3571 SDValue T2 = DCI.DAG.getZExtOrTrunc(Z, dl, MVT::i32);
3572 return DCI.DAG.getNode(HexagonISD::COMBINE, dl, MVT::i64, {T1, T2});
3573 }
3574 return SDValue();
3575 };
3576
3577 if (SDValue R = fold0(Op))
3578 return R;
3579 }
3580
3581 return SDValue();
3582}
3583
3584/// Returns relocation base for the given PIC jumptable.
3585SDValue
3587 SelectionDAG &DAG) const {
3588 int Idx = cast<JumpTableSDNode>(Table)->getIndex();
3589 EVT VT = Table.getValueType();
3591 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Table), VT, T);
3592}
3593
3594//===----------------------------------------------------------------------===//
3595// Inline Assembly Support
3596//===----------------------------------------------------------------------===//
3597
3600 if (Constraint.size() == 1) {
3601 switch (Constraint[0]) {
3602 case 'q':
3603 case 'v':
3604 if (Subtarget.useHVXOps())
3605 return C_RegisterClass;
3606 break;
3607 case 'a':
3608 return C_RegisterClass;
3609 default:
3610 break;
3611 }
3612 }
3613 return TargetLowering::getConstraintType(Constraint);
3614}
3615
3616std::pair<unsigned, const TargetRegisterClass*>
3618 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
3619
3620 if (Constraint.size() == 1) {
3621 switch (Constraint[0]) {
3622 case 'r': // R0-R31
3623 switch (VT.SimpleTy) {
3624 default:
3625 return {0u, nullptr};
3626 case MVT::i1:
3627 case MVT::i8:
3628 case MVT::i16:
3629 case MVT::i32:
3630 case MVT::f32:
3631 return {0u, &Hexagon::IntRegsRegClass};
3632 case MVT::i64:
3633 case MVT::f64:
3634 return {0u, &Hexagon::DoubleRegsRegClass};
3635 }
3636 break;
3637 case 'a': // M0-M1
3638 if (VT != MVT::i32)
3639 return {0u, nullptr};
3640 return {0u, &Hexagon::ModRegsRegClass};
3641 case 'q': // q0-q3
3642 switch (VT.getSizeInBits()) {
3643 default:
3644 return {0u, nullptr};
3645 case 64:
3646 case 128:
3647 return {0u, &Hexagon::HvxQRRegClass};
3648 }
3649 break;
3650 case 'v': // V0-V31
3651 switch (VT.getSizeInBits()) {
3652 default:
3653 return {0u, nullptr};
3654 case 512:
3655 return {0u, &Hexagon::HvxVRRegClass};
3656 case 1024:
3657 if (Subtarget.hasV60Ops() && Subtarget.useHVX128BOps())
3658 return {0u, &Hexagon::HvxVRRegClass};
3659 return {0u, &Hexagon::HvxWRRegClass};
3660 case 2048:
3661 return {0u, &Hexagon::HvxWRRegClass};
3662 }
3663 break;
3664 default:
3665 return {0u, nullptr};
3666 }
3667 }
3668
3669 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3670}
3671
3672/// isFPImmLegal - Returns true if the target can instruction select the
3673/// specified FP immediate natively. If false, the legalizer will
3674/// materialize the FP immediate as a load from a constant pool.
3676 bool ForCodeSize) const {
3677 return true;
3678}
3679
3680/// Returns true if it is beneficial to convert a load of a constant
3681/// to just the constant itself.
3683 Type *Ty) const {
3684 if (!ConstantLoadsToImm)
3685 return false;
3686
3687 assert(Ty->isIntegerTy());
3688 unsigned BitSize = Ty->getPrimitiveSizeInBits();
3689 return (BitSize > 0 && BitSize <= 64);
3690}
3691
3692/// isLegalAddressingMode - Return true if the addressing mode represented by
3693/// AM is legal for this target, for a load/store of the specified type.
3695 const AddrMode &AM, Type *Ty,
3696 unsigned AS, Instruction *I) const {
3697 if (Ty->isSized()) {
3698 // When LSR detects uses of the same base address to access different
3699 // types (e.g. unions), it will assume a conservative type for these
3700 // uses:
3701 // LSR Use: Kind=Address of void in addrspace(4294967295), ...
3702 // The type Ty passed here would then be "void". Skip the alignment
3703 // checks, but do not return false right away, since that confuses
3704 // LSR into crashing.
3705 Align A = DL.getABITypeAlign(Ty);
3706 // The base offset must be a multiple of the alignment.
3707 if (!isAligned(A, AM.BaseOffs))
3708 return false;
3709 // The shifted offset must fit in 11 bits.
3710 if (!isInt<11>(AM.BaseOffs >> Log2(A)))
3711 return false;
3712 }
3713
3714 // No global is ever allowed as a base.
3715 if (AM.BaseGV)
3716 return false;
3717
3718 int Scale = AM.Scale;
3719 if (Scale < 0)
3720 Scale = -Scale;
3721 switch (Scale) {
3722 case 0: // No scale reg, "r+i", "r", or just "i".
3723 break;
3724 default: // No scaled addressing mode.
3725 return false;
3726 }
3727 return true;
3728}
3729
3730/// Return true if folding a constant offset with the given GlobalAddress is
3731/// legal. It is frequently not legal in PIC relocation models.
3733 const {
3734 return HTM.getRelocationModel() == Reloc::Static;
3735}
3736
3737/// isLegalICmpImmediate - Return true if the specified immediate is legal
3738/// icmp immediate, that is the target has icmp instructions which can compare
3739/// a register against the immediate without having to materialize the
3740/// immediate into a register.
3742 return Imm >= -512 && Imm <= 511;
3743}
3744
3745/// IsEligibleForTailCallOptimization - Check whether the call is eligible
3746/// for tail call optimization. Targets which want to do tail call
3747/// optimization should implement this function.
3749 SDValue Callee,
3750 CallingConv::ID CalleeCC,
3751 bool IsVarArg,
3752 bool IsCalleeStructRet,
3753 bool IsCallerStructRet,
3755 const SmallVectorImpl<SDValue> &OutVals,
3757 SelectionDAG& DAG) const {
3758 const Function &CallerF = DAG.getMachineFunction().getFunction();
3759 CallingConv::ID CallerCC = CallerF.getCallingConv();
3760 bool CCMatch = CallerCC == CalleeCC;
3761
3762 // ***************************************************************************
3763 // Look for obvious safe cases to perform tail call optimization that do not
3764 // require ABI changes.
3765 // ***************************************************************************
3766
3767 // If this is a tail call via a function pointer, then don't do it!
3768 if (!isa<GlobalAddressSDNode>(Callee) &&
3769 !isa<ExternalSymbolSDNode>(Callee)) {
3770 return false;
3771 }
3772
3773 // Do not optimize if the calling conventions do not match and the conventions
3774 // used are not C or Fast.
3775 if (!CCMatch) {
3776 bool R = (CallerCC == CallingConv::C || CallerCC == CallingConv::Fast);
3777 bool E = (CalleeCC == CallingConv::C || CalleeCC == CallingConv::Fast);
3778 // If R & E, then ok.
3779 if (!R || !E)
3780 return false;
3781 }
3782
3783 // Do not tail call optimize vararg calls.
3784 if (IsVarArg)
3785 return false;
3786
3787 // Also avoid tail call optimization if either caller or callee uses struct
3788 // return semantics.
3789 if (IsCalleeStructRet || IsCallerStructRet)
3790 return false;
3791
3792 // In addition to the cases above, we also disable Tail Call Optimization if
3793 // the calling convention code that at least one outgoing argument needs to
3794 // go on the stack. We cannot check that here because at this point that
3795 // information is not available.
3796 return true;
3797}
3798
3799/// Returns the target specific optimal type for load and store operations as
3800/// a result of memset, memcpy, and memmove lowering.
3801///
3802/// If DstAlign is zero that means it's safe to destination alignment can
3803/// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
3804/// a need to check it against alignment requirement, probably because the
3805/// source does not need to be loaded. If 'IsMemset' is true, that means it's
3806/// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of
3807/// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
3808/// does not need to be loaded. It returns EVT::Other if the type should be
3809/// determined using generic target-independent logic.
3811 LLVMContext &Context, const MemOp &Op,
3812 const AttributeList &FuncAttributes) const {
3813 if (Op.size() >= 8 && Op.isAligned(Align(8)))
3814 return MVT::i64;
3815 if (Op.size() >= 4 && Op.isAligned(Align(4)))
3816 return MVT::i32;
3817 if (Op.size() >= 2 && Op.isAligned(Align(2)))
3818 return MVT::i16;
3819 return MVT::Other;
3820}
3821
3823 LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace,
3824 Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const {
3825 if (!VT.isSimple())
3826 return false;
3827 MVT SVT = VT.getSimpleVT();
3828 if (Subtarget.isHVXVectorType(SVT, true))
3829 return allowsHvxMemoryAccess(SVT, Flags, Fast);
3831 Context, DL, VT, AddrSpace, Alignment, Flags, Fast);
3832}
3833
3835 EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags,
3836 unsigned *Fast) const {
3837 if (!VT.isSimple())
3838 return false;
3839 MVT SVT = VT.getSimpleVT();
3840 if (Subtarget.isHVXVectorType(SVT, true))
3841 return allowsHvxMisalignedMemoryAccesses(SVT, Flags, Fast);
3842 if (Fast)
3843 *Fast = 0;
3844 return false;
3845}
3846
3847std::pair<const TargetRegisterClass*, uint8_t>
3848HexagonTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
3849 MVT VT) const {
3850 if (Subtarget.isHVXVectorType(VT, true)) {
3851 unsigned BitWidth = VT.getSizeInBits();
3852 unsigned VecWidth = Subtarget.getVectorLength() * 8;
3853
3854 if (VT.getVectorElementType() == MVT::i1)
3855 return std::make_pair(&Hexagon::HvxQRRegClass, 1);
3856 if (BitWidth == VecWidth)
3857 return std::make_pair(&Hexagon::HvxVRRegClass, 1);
3858 assert(BitWidth == 2 * VecWidth);
3859 return std::make_pair(&Hexagon::HvxWRRegClass, 1);
3860 }
3861
3863}
3864
3866 SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
3867 std::optional<unsigned> ByteOffset) const {
3868 // TODO: This may be worth removing. Check regression tests for diffs.
3869 if (!TargetLoweringBase::shouldReduceLoadWidth(Load, ExtTy, NewVT,
3870 ByteOffset))
3871 return false;
3872
3873 auto *L = cast<LoadSDNode>(Load);
3874 std::pair<SDValue, int> BO = getBaseAndOffset(L->getBasePtr());
3875 // Small-data object, do not shrink.
3876 if (BO.first.getOpcode() == HexagonISD::CONST32_GP)
3877 return false;
3878 if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(BO.first)) {
3879 auto &HTM = static_cast<const HexagonTargetMachine &>(getTargetMachine());
3880 const auto *GO = dyn_cast_or_null<const GlobalObject>(GA->getGlobal());
3881 return !GO || !HTM.getObjFileLowering()->isGlobalInSmallSection(GO, HTM);
3882 }
3883 return true;
3884}
3885
3887 SDNode *Node) const {
3888 AdjustHvxInstrPostInstrSelection(MI, Node);
3889}
3890
3892 Type *ValueTy, Value *Addr,
3893 AtomicOrdering Ord) const {
3894 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
3895 assert((SZ == 32 || SZ == 64) && "Only 32/64-bit atomic loads supported");
3896 Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_L2_loadw_locked
3897 : Intrinsic::hexagon_L4_loadd_locked;
3898
3899 Value *Call =
3900 Builder.CreateIntrinsic(IntID, Addr, /*FMFSource=*/nullptr, "larx");
3901
3902 return Builder.CreateBitCast(Call, ValueTy);
3903}
3904
3905/// Perform a store-conditional operation to Addr. Return the status of the
3906/// store. This should be 0 if the store succeeded, non-zero otherwise.
3908 Value *Val, Value *Addr,
3909 AtomicOrdering Ord) const {
3910 BasicBlock *BB = Builder.GetInsertBlock();
3911 Module *M = BB->getParent()->getParent();
3912 Type *Ty = Val->getType();
3913 unsigned SZ = Ty->getPrimitiveSizeInBits();
3914
3915 Type *CastTy = Builder.getIntNTy(SZ);
3916 assert((SZ == 32 || SZ == 64) && "Only 32/64-bit atomic stores supported");
3917 Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_S2_storew_locked
3918 : Intrinsic::hexagon_S4_stored_locked;
3919
3920 Val = Builder.CreateBitCast(Val, CastTy);
3921
3922 Value *Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
3923 /*FMFSource=*/nullptr, "stcx");
3924 Value *Cmp = Builder.CreateICmpEQ(Call, Builder.getInt32(0), "");
3925 Value *Ext = Builder.CreateZExt(Cmp, Type::getInt32Ty(M->getContext()));
3926 return Ext;
3927}
3928
3931 // Do not expand loads and stores that don't exceed 64 bits.
3932 return LI->getType()->getPrimitiveSizeInBits() > 64
3935}
3936
3939 // Do not expand loads and stores that don't exceed 64 bits.
3940 return SI->getValueOperand()->getType()->getPrimitiveSizeInBits() > 64
3943}
3944
3947 AtomicCmpXchgInst *AI) const {
3949}
unsigned const MachineRegisterInfo * MRI
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
constexpr LLT S8
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static cl::opt< int > MaxStoresPerMemcpyCL("max-store-memcpy", cl::Hidden, cl::init(6), cl::desc("Max #stores to inline memcpy"))
static cl::opt< bool > ConstantLoadsToImm("constant-loads-to-imm", cl::Hidden, cl::init(true), cl::desc("Convert constant loads to immediate values."))
static Value * getUnderLyingObjectForBrevLdIntr(Value *V)
static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static cl::opt< bool > AlignLoads("hexagon-align-loads", cl::Hidden, cl::init(false), cl::desc("Rewrite unaligned loads as a pair of aligned loads"))
static bool isBrevLdIntrinsic(const Value *Inst)
static cl::opt< int > MaxStoresPerMemmoveOptSizeCL("max-store-memmove-Os", cl::Hidden, cl::init(4), cl::desc("Max #stores to inline memmove"))
static cl::opt< int > MaxStoresPerMemmoveCL("max-store-memmove", cl::Hidden, cl::init(6), cl::desc("Max #stores to inline memmove"))
static Value * getBrevLdObject(Value *V)
static cl::opt< int > MaxStoresPerMemsetCL("max-store-memset", cl::Hidden, cl::init(8), cl::desc("Max #stores to inline memset"))
static cl::opt< bool > DisableArgsMinAlignment("hexagon-disable-args-min-alignment", cl::Hidden, cl::init(false), cl::desc("Disable minimum alignment of 1 for " "arguments passed by value on stack"))
static Value * returnEdge(const PHINode *PN, Value *IntrBaseVal)
static cl::opt< int > MaxStoresPerMemcpyOptSizeCL("max-store-memcpy-Os", cl::Hidden, cl::init(4), cl::desc("Max #stores to inline memcpy"))
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
static cl::opt< int > MaxStoresPerMemsetOptSizeCL("max-store-memset-Os", cl::Hidden, cl::init(4), cl::desc("Max #stores to inline memset"))
static cl::opt< bool > EmitJumpTables("hexagon-emit-jump-tables", cl::init(true), cl::Hidden, cl::desc("Control jump table emission on Hexagon target"))
static cl::opt< int > MinimumJumpTables("minimum-jump-tables", cl::Hidden, cl::init(5), cl::desc("Set minimum jump tables"))
static cl::opt< bool > EnableHexSDNodeSched("enable-hexagon-sdnode-sched", cl::Hidden, cl::desc("Enable Hexagon SDNode scheduling"))
#define Hexagon_PointerSize
#define HEXAGON_LRFP_SIZE
#define HEXAGON_GOT_SYM_NAME
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define RegName(no)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
#define H(x, y, z)
Definition: MD5.cpp:57
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
Register const TargetRegisterInfo * TRI
#define T1
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
#define P(N)
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition: Debug.h:119
static llvm::Type * getVectorElementType(llvm::Type *Ty)
Value * RHS
Value * LHS
APInt bitcastToAPInt() const
Definition: APFloat.h:1353
Class for arbitrary precision integers.
Definition: APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1562
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:224
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:200
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
const T * data() const
Definition: ArrayRef.h:144
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:506
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:213
The address of a basic block.
Definition: Constants.h:899
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
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...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
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...
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.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
bool isMemLoc() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
bool isTailCall() const
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:277
const APFloat & getValueAPF() const
Definition: Constants.h:320
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Definition: Constants.h:214
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:154
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
int64_t getSExtValue() const
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
Definition: Constants.cpp:1423
This is an important base class in LLVM.
Definition: Constant.h:43
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:124
This is the base abstract class for diagnostic reporting in the backend.
Interface for custom diagnostic printing.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition: Function.h:706
bool empty() const
Definition: Function.h:857
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:270
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:687
const GlobalValue * getGlobal() const
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:663
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition: Globals.cpp:419
bool isValidAutoIncImm(const EVT VT, const int Offset) const
Hexagon target-specific information for each MachineFunction.
Register getFrameRegister(const MachineFunction &MF) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
const HexagonRegisterInfo * getRegisterInfo() const override
bool isHVXVectorType(EVT VecTy, bool IncludeBool=false) const
Align getTypeAlignment(MVT Ty) const
unsigned getVectorLength() const
bool isEnvironmentMusl() const
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
bool isTargetCanonicalConstantNode(SDValue Op) const override
Returns true if the given Opc is considered a canonical constant for the target, which should not be ...
ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const
SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT, std::optional< unsigned > ByteOffset) const override
Return true if it is profitable to reduce a load to a smaller type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const
AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be expanded by the IR-level AtomicExpand pass into.
SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA, SDValue InGlue, EVT PtrVT, unsigned ReturnReg, unsigned char OperandGlues) 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,...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
Returns true by value, base pointer and offset pointer and addressing mode by reference if this node ...
SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFDIV(SDValue Op, SelectionDAG &DAG) const
SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
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,...
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.
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be expanded by the IR-level AtomicExpand pass.
SDValue LowerCallResult(SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals, const SmallVectorImpl< SDValue > &OutVals, SDValue Callee) const
LowerCallResult - Lower the result values of an ISD::CALL into the appropriate copies out of appropri...
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const
SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const
bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Return true if the target supports a memory access of this type for the given address space and align...
SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, unsigned Index) const override
Return true if EXTRACT_SUBVECTOR is cheap for extracting this result type from this source type with ...
SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
SDValue LowerLoad(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...
bool isShuffleMaskLegal(ArrayRef< int > Mask, EVT VT) const override
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
LegalizeAction getCustomOperationAction(SDNode &Op) const override
How to legalize this custom operation?
SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerUAddSubOCarry(SDValue Op, SelectionDAG &DAG) const
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
LowerCall - Functions arguments are copied from virtual regs to (physical regs)/(stack frame),...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const
SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const
SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
bool hasBitTest(SDValue X, SDValue Y) const override
Return true if the target has a bit-test instruction: (X & (1 << Y)) ==/!= 0 This knowledge can be us...
HexagonTargetLowering(const TargetMachine &TM, const HexagonSubtarget &ST)
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
bool IsEligibleForTailCallOptimization(SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet, bool isCallerStructRet, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SmallVectorImpl< ISD::InputArg > &Ins, SelectionDAG &DAG) const
IsEligibleForTailCallOptimization - Check whether the call is eligible for tail call optimization.
SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &, EVT) const override
Return true if an FMA operation is faster than a pair of mul and add instructions.
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const
LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, 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 LowerGLOBALADDRESS(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.
std::pair< MVT, unsigned > handleMaskRegisterForCallingConv(const HexagonSubtarget &Subtarget, EVT VT) const
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const
SDValue LowerREADSTEADYCOUNTER(SDValue Op, SelectionDAG &DAG) const
HexagonTargetObjectFile * getObjFileLowering() const override
bool isGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM) const
Return true if this global value should be placed into small data/bss section.
Common base class shared among various IRBuilders.
Definition: IRBuilder.h:114
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition: IRBuilder.h:575
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition: IRBuilder.h:512
BasicBlock * GetInsertBlock() const
Definition: IRBuilder.h:201
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition: IRBuilder.cpp:834
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:522
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2329
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2204
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition: IRBuilder.h:2082
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
Class to represent integer types.
Definition: DerivedTypes.h:42
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:319
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Base class for LoadSDNode and StoreSDNode.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
An instruction for reading from memory.
Definition: Instructions.h:180
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Machine Value Type.
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
SimpleValueType SimpleTy
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool isScalableVector() const
Return true if this is a vector value type where the runtime length is machine dependent.
static LLVM_ABI MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:247
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
TypeSize getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void print(raw_ostream &OS, const SlotIndexes *=nullptr, bool IsStandalone=true) const
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.
LLVM_ABI void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
unsigned getNumFixedObjects() const
Return the number of fixed objects.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
Representation of each machine instruction.
Definition: MachineInstr.h:72
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
Align getAlign() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:303
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
Definition: Operator.h:43
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
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
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:229
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:758
const TargetSubtargetInfo & getSubtarget() const
Definition: SelectionDAG.h:500
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:813
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 SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:768
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
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)
Definition: SelectionDAG.h:839
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:498
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 getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
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 getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM)
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:808
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:493
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVMContext * getContext() const
Definition: SelectionDAG.h:511
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)
Definition: SelectionDAG.h:777
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:581
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
LLVM_ABI SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a logical NOT operation as (XOR Val, BooleanOne).
static void commuteMask(MutableArrayRef< int > Mask)
Change values in a shuffle permute mask assuming the two vector operands have swapped position.
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
An instruction for storing to memory.
Definition: Instructions.h:296
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:154
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
R Default(T Value)
Definition: StringSwitch.h:177
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...
virtual bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT, std::optional< unsigned > ByteOffset=std::nullopt) const
Return true if it is profitable to reduce a load to a smaller type.
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
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 setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
virtual bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
Return true if the target supports a memory access of this type for the given address space and align...
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....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
virtual std::pair< const TargetRegisterClass *, uint8_t > findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const
Return the largest legal super-reg register class of the register class for the specified type and it...
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...
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual bool isTargetCanonicalConstantNode(SDValue Op) const
Returns true if the given Opc is considered a canonical constant for the target, which should not be ...
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
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.
virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:83
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:346
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:311
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:240
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
const ParentTy * getParent() const
Definition: ilist_node.h:34
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:126
@ 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
@ MO_PCREL
MO_PCREL - On a symbol operand, indicates a PC-relative relocation Used for computing a global addres...
@ MO_GOT
MO_GOT - Indicates a GOT-relative relocation.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:801
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1236
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1232
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:270
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition: ISDOpcodes.h:587
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:765
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1265
@ ConstantFP
Definition: ISDOpcodes.h:87
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:259
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1141
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:835
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:511
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition: ISDOpcodes.h:215
@ GlobalAddress
Definition: ISDOpcodes.h:88
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:862
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition: ISDOpcodes.h:571
@ FADD
Simple binary floating point operators.
Definition: ISDOpcodes.h:410
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:738
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1343
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:275
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:985
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:975
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition: ISDOpcodes.h:249
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
Definition: ISDOpcodes.h:1018
@ GlobalTLSAddress
Definition: ISDOpcodes.h:89
@ EH_RETURN
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...
Definition: ISDOpcodes.h:151
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:826
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition: ISDOpcodes.h:656
@ READSTEADYCOUNTER
READSTEADYCOUNTER - This corresponds to the readfixedcounter intrinsic.
Definition: ISDOpcodes.h:1298
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
Definition: ISDOpcodes.h:1331
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:1090
@ FNEG
Perform various unary floating-point operations inspired by libm.
Definition: ISDOpcodes.h:1002
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1187
@ SSUBO
Same for subtraction.
Definition: ISDOpcodes.h:347
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1166
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:778
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition: ISDOpcodes.h:663
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1261
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition: ISDOpcodes.h:343
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:756
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:636
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition: ISDOpcodes.h:601
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:563
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:832
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
Definition: ISDOpcodes.h:1321
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:793
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1151
@ ConstantPool
Definition: ISDOpcodes.h:92
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:870
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition: ISDOpcodes.h:718
@ GLOBAL_OFFSET_TABLE
The address of the GOT.
Definition: ISDOpcodes.h:103
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition: ISDOpcodes.h:787
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:323
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
Definition: ISDOpcodes.h:1207
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:110
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:908
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
Definition: ISDOpcodes.h:1292
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:730
@ TRAP
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:1318
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:200
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition: ISDOpcodes.h:552
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:53
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:1204
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:838
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1256
@ BlockAddress
Definition: ISDOpcodes.h:94
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:815
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:521
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition: ISDOpcodes.h:360
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
Definition: ISDOpcodes.h:1086
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition: ISDOpcodes.h:208
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:543
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:1634
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1685
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1665
@ GeneralDynamic
Definition: CodeGen.h:46
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
constexpr double e
Definition: MathExtras.h:47
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1744
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1702
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition: Alignment.h:145
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: bit.h:157
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:288
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:188
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
DWARFExpression::Operation Op
LLVM_ABI int getNextAvailablePluginDiagnosticKind()
Get the next available kind ID for a plugin diagnostic.
unsigned M0(unsigned Val)
Definition: VE.h:376
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:223
@ DS_Remark
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1777
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Extended Value Type.
Definition: ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:137
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
Definition: ValueTypes.h:279
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
Definition: ValueTypes.h:465
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:299
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:168
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:323
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:331
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
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:117
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
unsigned int NumVTs
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals