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