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