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 if (CLI.CFIType)
648 Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
649 Glue = Chain.getValue(1);
650
651 // Create the CALLSEQ_END node.
652 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, dl);
653 Glue = Chain.getValue(1);
654
655 // Handle result values, copying them out of physregs into vregs that we
656 // return.
657 return LowerCallResult(Chain, Glue, CallConv, IsVarArg, Ins, dl, DAG,
658 InVals, OutVals, Callee);
659}
660
661/// Returns true by value, base pointer and offset pointer and addressing
662/// mode by reference if this node can be combined with a load / store to
663/// form a post-indexed load / store.
666 SelectionDAG &DAG) const {
668 if (!LSN)
669 return false;
670 EVT VT = LSN->getMemoryVT();
671 if (!VT.isSimple())
672 return false;
673 bool IsLegalType = VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 ||
674 VT == MVT::i64 || VT == MVT::f32 || VT == MVT::f64 ||
675 VT == MVT::v2i16 || VT == MVT::v2i32 || VT == MVT::v4i8 ||
676 VT == MVT::v4i16 || VT == MVT::v8i8 ||
677 Subtarget.isHVXVectorType(VT.getSimpleVT());
678 if (!IsLegalType)
679 return false;
680
681 if (Op->getOpcode() != ISD::ADD)
682 return false;
683 Base = Op->getOperand(0);
684 Offset = Op->getOperand(1);
685 if (!isa<ConstantSDNode>(Offset.getNode()))
686 return false;
687 AM = ISD::POST_INC;
688
689 int32_t V = cast<ConstantSDNode>(Offset.getNode())->getSExtValue();
690 return Subtarget.getInstrInfo()->isValidAutoIncImm(VT, V);
691}
692
695 return SDValue();
696 else
697 return Op;
698}
699
703 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
704 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
705 unsigned LR = HRI.getRARegister();
706
707 if ((Op.getOpcode() != ISD::INLINEASM &&
708 Op.getOpcode() != ISD::INLINEASM_BR) || HMFI.hasClobberLR())
709 return Op;
710
711 unsigned NumOps = Op.getNumOperands();
712 if (Op.getOperand(NumOps-1).getValueType() == MVT::Glue)
713 --NumOps; // Ignore the flag operand.
714
715 for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
716 const InlineAsm::Flag Flags(Op.getConstantOperandVal(i));
717 unsigned NumVals = Flags.getNumOperandRegisters();
718 ++i; // Skip the ID value.
719
720 switch (Flags.getKind()) {
721 default:
722 llvm_unreachable("Bad flags!");
726 i += NumVals;
727 break;
731 for (; NumVals; --NumVals, ++i) {
732 Register Reg = cast<RegisterSDNode>(Op.getOperand(i))->getReg();
733 if (Reg != LR)
734 continue;
735 HMFI.setHasClobberLR(true);
736 return Op;
737 }
738 break;
739 }
740 }
741 }
742
743 return Op;
744}
745
746// Need to transform ISD::PREFETCH into something that doesn't inherit
747// all of the properties of ISD::PREFETCH, specifically SDNPMayLoad and
748// SDNPMayStore.
750 SelectionDAG &DAG) const {
751 SDValue Chain = Op.getOperand(0);
752 SDValue Addr = Op.getOperand(1);
753 // Lower it to DCFETCH($reg, #0). A "pat" will try to merge the offset in,
754 // if the "reg" is fed by an "add".
755 SDLoc DL(Op);
756 SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
757 return DAG.getNode(HexagonISD::DCFETCH, DL, MVT::Other, Chain, Addr, Zero);
758}
759
761 SelectionDAG &DAG) const {
762 SDValue Chain = Op.getOperand(0);
763 unsigned IntNo = Op.getConstantOperandVal(1);
764 // Lower the hexagon_prefetch builtin to DCFETCH, as above.
765 if (IntNo == Intrinsic::hexagon_prefetch) {
766 SDValue Addr = Op.getOperand(2);
767 SDLoc DL(Op);
768 SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
769 return DAG.getNode(HexagonISD::DCFETCH, DL, MVT::Other, Chain, Addr, Zero);
770 }
771 return SDValue();
772}
773
776 SelectionDAG &DAG) const {
777 SDValue Chain = Op.getOperand(0);
778 SDValue Size = Op.getOperand(1);
779 SDValue Align = Op.getOperand(2);
780 SDLoc dl(Op);
781
783 assert(AlignConst && "Non-constant Align in LowerDYNAMIC_STACKALLOC");
784
785 unsigned A = AlignConst->getSExtValue();
786 auto &HFI = *Subtarget.getFrameLowering();
787 // "Zero" means natural stack alignment.
788 if (A == 0)
789 A = HFI.getStackAlign().value();
790
791 LLVM_DEBUG({
792 dbgs () << __func__ << " Align: " << A << " Size: ";
793 Size.getNode()->dump(&DAG);
794 dbgs() << "\n";
795 });
796
797 SDValue AC = DAG.getConstant(A, dl, MVT::i32);
798 SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
799 SDValue AA = DAG.getNode(HexagonISD::ALLOCA, dl, VTs, Chain, Size, AC);
800
802 return AA;
803}
804
806 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
807 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
808 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
810 MachineFrameInfo &MFI = MF.getFrameInfo();
812
813 // Linux ABI treats var-arg calls the same way as regular ones.
814 bool TreatAsVarArg = !Subtarget.isEnvironmentMusl() && IsVarArg;
815
816 // Assign locations to all of the incoming arguments.
818 CCState CCInfo(CallConv, TreatAsVarArg, MF, ArgLocs, *DAG.getContext());
819
820 if (Subtarget.useHVXOps())
821 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon_HVX);
823 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon_Legacy);
824 else
825 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon);
826
827 // For LLVM, in the case when returning a struct by value (>8byte),
828 // the first argument is a pointer that points to the location on caller's
829 // stack where the return value will be stored. For Hexagon, the location on
830 // caller's stack is passed only when the struct size is smaller than (and
831 // equal to) 8 bytes. If not, no address will be passed into callee and
832 // callee return the result directly through R0/R1.
833 auto NextSingleReg = [] (const TargetRegisterClass &RC, unsigned Reg) {
834 switch (RC.getID()) {
835 case Hexagon::IntRegsRegClassID:
836 return Reg - Hexagon::R0 + 1;
837 case Hexagon::DoubleRegsRegClassID:
838 return (Reg - Hexagon::D0 + 1) * 2;
839 case Hexagon::HvxVRRegClassID:
840 return Reg - Hexagon::V0 + 1;
841 case Hexagon::HvxWRRegClassID:
842 return (Reg - Hexagon::W0 + 1) * 2;
843 }
844 llvm_unreachable("Unexpected register class");
845 };
846
847 auto &HFL = const_cast<HexagonFrameLowering&>(*Subtarget.getFrameLowering());
848 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
849 HFL.FirstVarArgSavedReg = 0;
851
852 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
853 CCValAssign &VA = ArgLocs[i];
854 ISD::ArgFlagsTy Flags = Ins[i].Flags;
855 bool ByVal = Flags.isByVal();
856
857 // Arguments passed in registers:
858 // 1. 32- and 64-bit values and HVX vectors are passed directly,
859 // 2. Large structs are passed via an address, and the address is
860 // passed in a register.
861 if (VA.isRegLoc() && ByVal && Flags.getByValSize() <= 8)
862 llvm_unreachable("ByValSize must be bigger than 8 bytes");
863
864 bool InReg = VA.isRegLoc() &&
865 (!ByVal || (ByVal && Flags.getByValSize() > 8));
866
867 if (InReg) {
868 MVT RegVT = VA.getLocVT();
869 if (VA.getLocInfo() == CCValAssign::BCvt)
870 RegVT = VA.getValVT();
871
872 const TargetRegisterClass *RC = getRegClassFor(RegVT);
873 Register VReg = MRI.createVirtualRegister(RC);
874 SDValue Copy = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
875
876 // Treat values of type MVT::i1 specially: they are passed in
877 // registers of type i32, but they need to remain as values of
878 // type i1 for consistency of the argument lowering.
879 if (VA.getValVT() == MVT::i1) {
880 assert(RegVT.getSizeInBits() <= 32);
881 SDValue T = DAG.getNode(ISD::AND, dl, RegVT,
882 Copy, DAG.getConstant(1, dl, RegVT));
883 Copy = DAG.getSetCC(dl, MVT::i1, T, DAG.getConstant(0, dl, RegVT),
884 ISD::SETNE);
885 } else {
886#ifndef NDEBUG
887 unsigned RegSize = RegVT.getSizeInBits();
888 assert(RegSize == 32 || RegSize == 64 ||
889 Subtarget.isHVXVectorType(RegVT));
890#endif
891 }
892 InVals.push_back(Copy);
893 MRI.addLiveIn(VA.getLocReg(), VReg);
894 HFL.FirstVarArgSavedReg = NextSingleReg(*RC, VA.getLocReg());
895 } else {
896 assert(VA.isMemLoc() && "Argument should be passed in memory");
897
898 // If it's a byval parameter, then we need to compute the
899 // "real" size, not the size of the pointer.
900 unsigned ObjSize = Flags.isByVal()
901 ? Flags.getByValSize()
902 : VA.getLocVT().getStoreSizeInBits() / 8;
903
904 // Create the frame index object for this incoming parameter.
906 int FI = MFI.CreateFixedObject(ObjSize, Offset, true);
907 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
908
909 if (Flags.isByVal()) {
910 // If it's a pass-by-value aggregate, then do not dereference the stack
911 // location. Instead, we should generate a reference to the stack
912 // location.
913 InVals.push_back(FIN);
914 } else {
915 SDValue L = DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
917 InVals.push_back(L);
918 }
919 }
920 }
921
922 if (IsVarArg && Subtarget.isEnvironmentMusl()) {
923 for (int i = HFL.FirstVarArgSavedReg; i < 6; i++)
924 MRI.addLiveIn(Hexagon::R0+i);
925 }
926
927 if (IsVarArg && Subtarget.isEnvironmentMusl()) {
928 HMFI.setFirstNamedArgFrameIndex(HMFI.getFirstNamedArgFrameIndex() - 1);
929 HMFI.setLastNamedArgFrameIndex(-int(MFI.getNumFixedObjects()));
930
931 // Create Frame index for the start of register saved area.
932 int NumVarArgRegs = 6 - HFL.FirstVarArgSavedReg;
933 bool RequiresPadding = (NumVarArgRegs & 1);
934 int RegSaveAreaSizePlusPadding = RequiresPadding
935 ? (NumVarArgRegs + 1) * 4
936 : NumVarArgRegs * 4;
937
938 if (RegSaveAreaSizePlusPadding > 0) {
939 // The offset to saved register area should be 8 byte aligned.
940 int RegAreaStart = HEXAGON_LRFP_SIZE + CCInfo.getStackSize();
941 if (!(RegAreaStart % 8))
942 RegAreaStart = (RegAreaStart + 7) & -8;
943
944 int RegSaveAreaFrameIndex =
945 MFI.CreateFixedObject(RegSaveAreaSizePlusPadding, RegAreaStart, true);
946 HMFI.setRegSavedAreaStartFrameIndex(RegSaveAreaFrameIndex);
947
948 // This will point to the next argument passed via stack.
949 int Offset = RegAreaStart + RegSaveAreaSizePlusPadding;
950 int FI = MFI.CreateFixedObject(Hexagon_PointerSize, Offset, true);
951 HMFI.setVarArgsFrameIndex(FI);
952 } else {
953 // This will point to the next argument passed via stack, when
954 // there is no saved register area.
955 int Offset = HEXAGON_LRFP_SIZE + CCInfo.getStackSize();
956 int FI = MFI.CreateFixedObject(Hexagon_PointerSize, Offset, true);
957 HMFI.setRegSavedAreaStartFrameIndex(FI);
958 HMFI.setVarArgsFrameIndex(FI);
959 }
960 }
961
962
963 if (IsVarArg && !Subtarget.isEnvironmentMusl()) {
964 // This will point to the next argument passed via stack.
965 int Offset = HEXAGON_LRFP_SIZE + CCInfo.getStackSize();
966 int FI = MFI.CreateFixedObject(Hexagon_PointerSize, Offset, true);
967 HMFI.setVarArgsFrameIndex(FI);
968 }
969
970 return Chain;
971}
972
975 // VASTART stores the address of the VarArgsFrameIndex slot into the
976 // memory location argument.
979 SDValue Addr = DAG.getFrameIndex(QFI->getVarArgsFrameIndex(), MVT::i32);
980 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
981
982 if (!Subtarget.isEnvironmentMusl()) {
983 return DAG.getStore(Op.getOperand(0), SDLoc(Op), Addr, Op.getOperand(1),
985 }
986 auto &FuncInfo = *MF.getInfo<HexagonMachineFunctionInfo>();
987 auto &HFL = *Subtarget.getFrameLowering();
988 SDLoc DL(Op);
990
991 // Get frame index of va_list.
992 SDValue FIN = Op.getOperand(1);
993
994 // If first Vararg register is odd, add 4 bytes to start of
995 // saved register area to point to the first register location.
996 // This is because the saved register area has to be 8 byte aligned.
997 // In case of an odd start register, there will be 4 bytes of padding in
998 // the beginning of saved register area. If all registers area used up,
999 // the following condition will handle it correctly.
1000 SDValue SavedRegAreaStartFrameIndex =
1001 DAG.getFrameIndex(FuncInfo.getRegSavedAreaStartFrameIndex(), MVT::i32);
1002
1003 auto PtrVT = getPointerTy(DAG.getDataLayout());
1004
1005 if (HFL.FirstVarArgSavedReg & 1)
1006 SavedRegAreaStartFrameIndex =
1007 DAG.getNode(ISD::ADD, DL, PtrVT,
1008 DAG.getFrameIndex(FuncInfo.getRegSavedAreaStartFrameIndex(),
1009 MVT::i32),
1010 DAG.getIntPtrConstant(4, DL));
1011
1012 // Store the saved register area start pointer.
1013 SDValue Store =
1014 DAG.getStore(Op.getOperand(0), DL,
1015 SavedRegAreaStartFrameIndex,
1016 FIN, MachinePointerInfo(SV));
1017 MemOps.push_back(Store);
1018
1019 // Store saved register area end pointer.
1020 FIN = DAG.getNode(ISD::ADD, DL, PtrVT,
1021 FIN, DAG.getIntPtrConstant(4, DL));
1022 Store = DAG.getStore(Op.getOperand(0), DL,
1023 DAG.getFrameIndex(FuncInfo.getVarArgsFrameIndex(),
1024 PtrVT),
1025 FIN, MachinePointerInfo(SV, 4));
1026 MemOps.push_back(Store);
1027
1028 // Store overflow area pointer.
1029 FIN = DAG.getNode(ISD::ADD, DL, PtrVT,
1030 FIN, DAG.getIntPtrConstant(4, DL));
1031 Store = DAG.getStore(Op.getOperand(0), DL,
1032 DAG.getFrameIndex(FuncInfo.getVarArgsFrameIndex(),
1033 PtrVT),
1034 FIN, MachinePointerInfo(SV, 8));
1035 MemOps.push_back(Store);
1036
1037 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
1038}
1039
1040SDValue
1042 // Assert that the linux ABI is enabled for the current compilation.
1043 assert(Subtarget.isEnvironmentMusl() && "Linux ABI should be enabled");
1044 SDValue Chain = Op.getOperand(0);
1045 SDValue DestPtr = Op.getOperand(1);
1046 SDValue SrcPtr = Op.getOperand(2);
1047 const Value *DestSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
1048 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
1049 SDLoc DL(Op);
1050 // Size of the va_list is 12 bytes as it has 3 pointers. Therefore,
1051 // we need to memcopy 12 bytes from va_list to another similar list.
1052 return DAG.getMemcpy(Chain, DL, DestPtr, SrcPtr,
1053 DAG.getIntPtrConstant(12, DL), Align(4), Align(4),
1054 /*isVolatile*/ false, false, /*CI=*/nullptr,
1055 std::nullopt, MachinePointerInfo(DestSV),
1056 MachinePointerInfo(SrcSV));
1057}
1058
1060 const SDLoc &dl(Op);
1061 SDValue LHS = Op.getOperand(0);
1062 SDValue RHS = Op.getOperand(1);
1063 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
1064 MVT ResTy = ty(Op);
1065 MVT OpTy = ty(LHS);
1066
1067 if (OpTy == MVT::v2i16 || OpTy == MVT::v4i8) {
1068 MVT ElemTy = OpTy.getVectorElementType();
1069 assert(ElemTy.isScalarInteger());
1070 MVT WideTy = MVT::getVectorVT(MVT::getIntegerVT(2*ElemTy.getSizeInBits()),
1071 OpTy.getVectorNumElements());
1072 return DAG.getSetCC(dl, ResTy,
1073 DAG.getSExtOrTrunc(LHS, SDLoc(LHS), WideTy),
1074 DAG.getSExtOrTrunc(RHS, SDLoc(RHS), WideTy), CC);
1075 }
1076
1077 // Treat all other vector types as legal.
1078 if (ResTy.isVector())
1079 return Op;
1080
1081 // Comparisons of short integers should use sign-extend, not zero-extend,
1082 // since we can represent small negative values in the compare instructions.
1083 // The LLVM default is to use zero-extend arbitrarily in these cases.
1084 auto isSExtFree = [this](SDValue N) {
1085 switch (N.getOpcode()) {
1086 case ISD::TRUNCATE: {
1087 // A sign-extend of a truncate of a sign-extend is free.
1088 SDValue Op = N.getOperand(0);
1089 if (Op.getOpcode() != ISD::AssertSext)
1090 return false;
1091 EVT OrigTy = cast<VTSDNode>(Op.getOperand(1))->getVT();
1092 unsigned ThisBW = ty(N).getSizeInBits();
1093 unsigned OrigBW = OrigTy.getSizeInBits();
1094 // The type that was sign-extended to get the AssertSext must be
1095 // narrower than the type of N (so that N has still the same value
1096 // as the original).
1097 return ThisBW >= OrigBW;
1098 }
1099 case ISD::LOAD:
1100 // We have sign-extended loads.
1101 return true;
1102 }
1103 return false;
1104 };
1105
1106 if (OpTy == MVT::i8 || OpTy == MVT::i16) {
1108 bool IsNegative = C && C->getAPIntValue().isNegative();
1109 if (IsNegative || isSExtFree(LHS) || isSExtFree(RHS))
1110 return DAG.getSetCC(dl, ResTy,
1111 DAG.getSExtOrTrunc(LHS, SDLoc(LHS), MVT::i32),
1112 DAG.getSExtOrTrunc(RHS, SDLoc(RHS), MVT::i32), CC);
1113 }
1114
1115 return SDValue();
1116}
1117
1118SDValue
1120 SDValue PredOp = Op.getOperand(0);
1121 SDValue Op1 = Op.getOperand(1), Op2 = Op.getOperand(2);
1122 MVT OpTy = ty(Op1);
1123 const SDLoc &dl(Op);
1124
1125 if (OpTy == MVT::v2i16 || OpTy == MVT::v4i8) {
1126 MVT ElemTy = OpTy.getVectorElementType();
1127 assert(ElemTy.isScalarInteger());
1128 MVT WideTy = MVT::getVectorVT(MVT::getIntegerVT(2*ElemTy.getSizeInBits()),
1129 OpTy.getVectorNumElements());
1130 // Generate (trunc (select (_, sext, sext))).
1131 return DAG.getSExtOrTrunc(
1132 DAG.getSelect(dl, WideTy, PredOp,
1133 DAG.getSExtOrTrunc(Op1, dl, WideTy),
1134 DAG.getSExtOrTrunc(Op2, dl, WideTy)),
1135 dl, OpTy);
1136 }
1137
1138 return SDValue();
1139}
1140
1141SDValue
1143 EVT ValTy = Op.getValueType();
1145 Constant *CVal = nullptr;
1146 bool isVTi1Type = false;
1147 if (auto *CV = dyn_cast<ConstantVector>(CPN->getConstVal())) {
1148 if (cast<VectorType>(CV->getType())->getElementType()->isIntegerTy(1)) {
1149 IRBuilder<> IRB(CV->getContext());
1151 unsigned VecLen = CV->getNumOperands();
1152 assert(isPowerOf2_32(VecLen) &&
1153 "conversion only supported for pow2 VectorSize");
1154 for (unsigned i = 0; i < VecLen; ++i)
1155 NewConst.push_back(IRB.getInt8(CV->getOperand(i)->isNullValue()));
1156
1157 CVal = ConstantVector::get(NewConst);
1158 isVTi1Type = true;
1159 }
1160 }
1161 Align Alignment = CPN->getAlign();
1162 bool IsPositionIndependent = isPositionIndependent();
1163 unsigned char TF = IsPositionIndependent ? HexagonII::MO_PCREL : 0;
1164
1165 unsigned Offset = 0;
1166 SDValue T;
1167 if (CPN->isMachineConstantPoolEntry())
1168 T = DAG.getTargetConstantPool(CPN->getMachineCPVal(), ValTy, Alignment,
1169 Offset, TF);
1170 else if (isVTi1Type)
1171 T = DAG.getTargetConstantPool(CVal, ValTy, Alignment, Offset, TF);
1172 else
1173 T = DAG.getTargetConstantPool(CPN->getConstVal(), ValTy, Alignment, Offset,
1174 TF);
1175
1176 assert(cast<ConstantPoolSDNode>(T)->getTargetFlags() == TF &&
1177 "Inconsistent target flag encountered");
1178
1179 if (IsPositionIndependent)
1180 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), ValTy, T);
1181 return DAG.getNode(HexagonISD::CP, SDLoc(Op), ValTy, T);
1182}
1183
1184SDValue
1186 EVT VT = Op.getValueType();
1187 int Idx = cast<JumpTableSDNode>(Op)->getIndex();
1188 if (isPositionIndependent()) {
1190 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), VT, T);
1191 }
1192
1193 SDValue T = DAG.getTargetJumpTable(Idx, VT);
1194 return DAG.getNode(HexagonISD::JT, SDLoc(Op), VT, T);
1195}
1196
1197SDValue
1199 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1201 MachineFrameInfo &MFI = MF.getFrameInfo();
1202 MFI.setReturnAddressIsTaken(true);
1203
1204 EVT VT = Op.getValueType();
1205 SDLoc dl(Op);
1206 unsigned Depth = Op.getConstantOperandVal(0);
1207 if (Depth) {
1208 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1209 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1210 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1211 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1213 }
1214
1215 // Return LR, which contains the return address. Mark it an implicit live-in.
1216 Register Reg = MF.addLiveIn(HRI.getRARegister(), getRegClassFor(MVT::i32));
1217 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1218}
1219
1220SDValue
1222 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1224 MFI.setFrameAddressIsTaken(true);
1225
1226 EVT VT = Op.getValueType();
1227 SDLoc dl(Op);
1228 unsigned Depth = Op.getConstantOperandVal(0);
1229 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1230 HRI.getFrameRegister(), VT);
1231 while (Depth--)
1232 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1234 return FrameAddr;
1235}
1236
1237SDValue
1239 SDLoc dl(Op);
1240 return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
1241}
1242
1243SDValue
1245 SDLoc dl(Op);
1246 auto *GAN = cast<GlobalAddressSDNode>(Op);
1247 auto PtrVT = getPointerTy(DAG.getDataLayout());
1248 auto *GV = GAN->getGlobal();
1249 int64_t Offset = GAN->getOffset();
1250
1251 auto &HLOF = *HTM.getObjFileLowering();
1252 Reloc::Model RM = HTM.getRelocationModel();
1253
1254 if (RM == Reloc::Static) {
1255 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset);
1256 const GlobalObject *GO = GV->getAliaseeObject();
1257 if (GO && Subtarget.useSmallData() && HLOF.isGlobalInSmallSection(GO, HTM))
1258 return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, GA);
1259 return DAG.getNode(HexagonISD::CONST32, dl, PtrVT, GA);
1260 }
1261
1262 bool UsePCRel = getTargetMachine().shouldAssumeDSOLocal(GV);
1263 if (UsePCRel) {
1264 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset,
1266 return DAG.getNode(HexagonISD::AT_PCREL, dl, PtrVT, GA);
1267 }
1268
1269 // Use GOT index.
1270 SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
1271 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, HexagonII::MO_GOT);
1272 SDValue Off = DAG.getConstant(Offset, dl, MVT::i32);
1273 return DAG.getNode(HexagonISD::AT_GOT, dl, PtrVT, GOT, GA, Off);
1274}
1275
1276// Specifies that for loads and stores VT can be promoted to PromotedLdStVT.
1277SDValue
1279 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1280 SDLoc dl(Op);
1281 EVT PtrVT = getPointerTy(DAG.getDataLayout());
1282
1283 Reloc::Model RM = HTM.getRelocationModel();
1284 if (RM == Reloc::Static) {
1285 SDValue A = DAG.getTargetBlockAddress(BA, PtrVT);
1286 return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, A);
1287 }
1288
1290 return DAG.getNode(HexagonISD::AT_PCREL, dl, PtrVT, A);
1291}
1292
1293SDValue
1295 const {
1296 EVT PtrVT = getPointerTy(DAG.getDataLayout());
1299 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), PtrVT, GOTSym);
1300}
1301
1302SDValue
1304 GlobalAddressSDNode *GA, SDValue Glue, EVT PtrVT, unsigned ReturnReg,
1305 unsigned char OperandFlags) const {
1307 MachineFrameInfo &MFI = MF.getFrameInfo();
1308 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1309 SDLoc dl(GA);
1310 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,
1311 GA->getValueType(0),
1312 GA->getOffset(),
1313 OperandFlags);
1314 // Create Operands for the call.The Operands should have the following:
1315 // 1. Chain SDValue
1316 // 2. Callee which in this case is the Global address value.
1317 // 3. Registers live into the call.In this case its R0, as we
1318 // have just one argument to be passed.
1319 // 4. Glue.
1320 // Note: The order is important.
1321
1322 const auto &HRI = *Subtarget.getRegisterInfo();
1323 const uint32_t *Mask = HRI.getCallPreservedMask(MF, CallingConv::C);
1324 assert(Mask && "Missing call preserved mask for calling convention");
1325 SDValue Ops[] = { Chain, TGA, DAG.getRegister(Hexagon::R0, PtrVT),
1326 DAG.getRegisterMask(Mask), Glue };
1327 Chain = DAG.getNode(HexagonISD::CALL, dl, NodeTys, Ops);
1328
1329 // Inform MFI that function has calls.
1330 MFI.setAdjustsStack(true);
1331
1332 Glue = Chain.getValue(1);
1333 return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Glue);
1334}
1335
1336//
1337// Lower using the initial executable model for TLS addresses
1338//
1339SDValue
1341 SelectionDAG &DAG) const {
1342 SDLoc dl(GA);
1343 int64_t Offset = GA->getOffset();
1344 auto PtrVT = getPointerTy(DAG.getDataLayout());
1345
1346 // Get the thread pointer.
1347 SDValue TP = DAG.getCopyFromReg(DAG.getEntryNode(), dl, Hexagon::UGP, PtrVT);
1348
1349 bool IsPositionIndependent = isPositionIndependent();
1350 unsigned char TF =
1351 IsPositionIndependent ? HexagonII::MO_IEGOT : HexagonII::MO_IE;
1352
1353 // First generate the TLS symbol address
1354 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, PtrVT,
1355 Offset, TF);
1356
1357 SDValue Sym = DAG.getNode(HexagonISD::CONST32, dl, PtrVT, TGA);
1358
1359 if (IsPositionIndependent) {
1360 // Generate the GOT pointer in case of position independent code
1361 SDValue GOT = LowerGLOBAL_OFFSET_TABLE(Sym, DAG);
1362
1363 // Add the TLS Symbol address to GOT pointer.This gives
1364 // GOT relative relocation for the symbol.
1365 Sym = DAG.getNode(ISD::ADD, dl, PtrVT, GOT, Sym);
1366 }
1367
1368 // Load the offset value for TLS symbol.This offset is relative to
1369 // thread pointer.
1370 SDValue LoadOffset =
1371 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Sym, MachinePointerInfo());
1372
1373 // Address of the thread local variable is the add of thread
1374 // pointer and the offset of the variable.
1375 return DAG.getNode(ISD::ADD, dl, PtrVT, TP, LoadOffset);
1376}
1377
1378//
1379// Lower using the local executable model for TLS addresses
1380//
1381SDValue
1383 SelectionDAG &DAG) const {
1384 SDLoc dl(GA);
1385 int64_t Offset = GA->getOffset();
1386 auto PtrVT = getPointerTy(DAG.getDataLayout());
1387
1388 // Get the thread pointer.
1389 SDValue TP = DAG.getCopyFromReg(DAG.getEntryNode(), dl, Hexagon::UGP, PtrVT);
1390 // Generate the TLS symbol address
1391 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, PtrVT, Offset,
1393 SDValue Sym = DAG.getNode(HexagonISD::CONST32, dl, PtrVT, TGA);
1394
1395 // Address of the thread local variable is the add of thread
1396 // pointer and the offset of the variable.
1397 return DAG.getNode(ISD::ADD, dl, PtrVT, TP, Sym);
1398}
1399
1400//
1401// Lower using the general dynamic model for TLS addresses
1402//
1403SDValue
1405 SelectionDAG &DAG) const {
1406 SDLoc dl(GA);
1407 int64_t Offset = GA->getOffset();
1408 auto PtrVT = getPointerTy(DAG.getDataLayout());
1409
1410 // First generate the TLS symbol address
1411 SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, PtrVT, Offset,
1413
1414 // Then, generate the GOT pointer
1415 SDValue GOT = LowerGLOBAL_OFFSET_TABLE(TGA, DAG);
1416
1417 // Add the TLS symbol and the GOT pointer
1418 SDValue Sym = DAG.getNode(HexagonISD::CONST32, dl, PtrVT, TGA);
1419 SDValue Chain = DAG.getNode(ISD::ADD, dl, PtrVT, GOT, Sym);
1420
1421 // Copy over the argument to R0
1422 SDValue InGlue;
1423 Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, Hexagon::R0, Chain, InGlue);
1424 InGlue = Chain.getValue(1);
1425
1426 unsigned Flags = DAG.getSubtarget<HexagonSubtarget>().useLongCalls()
1429
1430 return GetDynamicTLSAddr(DAG, Chain, GA, InGlue, PtrVT,
1431 Hexagon::R0, Flags);
1432}
1433
1434//
1435// Lower TLS addresses.
1436//
1437// For now for dynamic models, we only support the general dynamic model.
1438//
1439SDValue
1441 SelectionDAG &DAG) const {
1443
1444 switch (HTM.getTLSModel(GA->getGlobal())) {
1447 return LowerToTLSGeneralDynamicModel(GA, DAG);
1449 return LowerToTLSInitialExecModel(GA, DAG);
1451 return LowerToTLSLocalExecModel(GA, DAG);
1452 }
1453 llvm_unreachable("Bogus TLS model");
1454}
1455
1456//===----------------------------------------------------------------------===//
1457// TargetLowering Implementation
1458//===----------------------------------------------------------------------===//
1459
1461 const HexagonSubtarget &ST)
1462 : TargetLowering(TM, ST),
1463 HTM(static_cast<const HexagonTargetMachine &>(TM)), Subtarget(ST) {
1464 auto &HRI = *Subtarget.getRegisterInfo();
1465
1469 setStackPointerRegisterToSaveRestore(HRI.getStackRegister());
1472
1475
1478 else
1480
1481 // Limits for inline expansion of memcpy/memmove
1488
1490
1491 //
1492 // Set up register classes.
1493 //
1494
1495 addRegisterClass(MVT::i1, &Hexagon::PredRegsRegClass);
1496 addRegisterClass(MVT::v2i1, &Hexagon::PredRegsRegClass); // bbbbaaaa
1497 addRegisterClass(MVT::v4i1, &Hexagon::PredRegsRegClass); // ddccbbaa
1498 addRegisterClass(MVT::v8i1, &Hexagon::PredRegsRegClass); // hgfedcba
1499 addRegisterClass(MVT::i32, &Hexagon::IntRegsRegClass);
1500 addRegisterClass(MVT::v2i16, &Hexagon::IntRegsRegClass);
1501 addRegisterClass(MVT::v4i8, &Hexagon::IntRegsRegClass);
1502 addRegisterClass(MVT::i64, &Hexagon::DoubleRegsRegClass);
1503 addRegisterClass(MVT::v8i8, &Hexagon::DoubleRegsRegClass);
1504 addRegisterClass(MVT::v4i16, &Hexagon::DoubleRegsRegClass);
1505 addRegisterClass(MVT::v2i32, &Hexagon::DoubleRegsRegClass);
1506
1507 addRegisterClass(MVT::f32, &Hexagon::IntRegsRegClass);
1508 addRegisterClass(MVT::f64, &Hexagon::DoubleRegsRegClass);
1509
1510 //
1511 // Handling of scalar operations.
1512 //
1513 // All operations default to "legal", except:
1514 // - indexed loads and stores (pre-/post-incremented),
1515 // - ANY_EXTEND_VECTOR_INREG, ATOMIC_CMP_SWAP_WITH_SUCCESS, CONCAT_VECTORS,
1516 // ConstantFP, FCEIL, FCOPYSIGN, FEXP, FEXP2, FFLOOR, FGETSIGN,
1517 // FLOG, FLOG2, FLOG10, FMAXIMUMNUM, FMINIMUMNUM, FNEARBYINT, FRINT, FROUND,
1518 // TRAP, FTRUNC, PREFETCH, SIGN_EXTEND_VECTOR_INREG,
1519 // ZERO_EXTEND_VECTOR_INREG,
1520 // which default to "expand" for at least one type.
1521
1522 // Misc operations.
1525 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1542
1543 // Custom legalize GlobalAddress nodes into CONST32.
1547
1548 // Hexagon needs to optimize cases with negative constants.
1552 setOperationAction(ISD::SETCC, MVT::v2i16, Custom);
1553
1554 // VASTART needs to be custom lowered to use the VarArgsFrameIndex.
1556 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1557 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1558 if (Subtarget.isEnvironmentMusl())
1560 else
1562
1566
1567 if (EmitJumpTables)
1569 else
1570 setMinimumJumpTableEntries(std::numeric_limits<unsigned>::max());
1571 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
1572
1573 for (unsigned LegalIntOp :
1575 setOperationAction(LegalIntOp, MVT::i32, Legal);
1576 setOperationAction(LegalIntOp, MVT::i64, Legal);
1577 }
1578
1579 // Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit,
1580 // but they only operate on i64.
1581 for (MVT VT : MVT::integer_valuetypes()) {
1588 }
1591
1596
1597 // Popcount can count # of 1s in i64 but returns i32.
1602
1607
1612
1613 for (unsigned IntExpOp :
1618 for (MVT VT : MVT::integer_valuetypes())
1619 setOperationAction(IntExpOp, VT, Expand);
1620 }
1621 for (MVT VT : MVT::fp_valuetypes()) {
1622 for (unsigned FPExpOp : {ISD::FDIV, ISD::FSQRT, ISD::FSIN, ISD::FCOS,
1624 setOperationAction(FPExpOp, VT, Expand);
1625
1627 }
1628
1629 // No extending loads from i32.
1630 for (MVT VT : MVT::integer_valuetypes()) {
1631 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i32, Expand);
1632 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
1633 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i32, Expand);
1634 }
1635 // Turn FP truncstore into trunc + store.
1636 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
1637 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
1638 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
1639 // Turn FP extload into load/fpextend.
1640 for (MVT VT : MVT::fp_valuetypes())
1641 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
1642
1643 // Expand BR_CC and SELECT_CC for all integer and fp types.
1644 for (MVT VT : MVT::integer_valuetypes()) {
1647 }
1648 for (MVT VT : MVT::fp_valuetypes()) {
1651 }
1652 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
1653
1654 //
1655 // Handling of vector operations.
1656 //
1657
1658 // Set the action for vector operations to "expand", then override it with
1659 // either "custom" or "legal" for specific cases.
1660 // clang-format off
1661 static const unsigned VectExpOps[] = {
1662 // Integer arithmetic:
1666 // Logical/bit:
1669 // Floating point arithmetic/math functions:
1677 // Misc:
1679 // Vector:
1685 };
1686 // clang-format on
1687
1689 for (unsigned VectExpOp : VectExpOps)
1690 setOperationAction(VectExpOp, VT, Expand);
1691
1692 // Expand all extending loads and truncating stores:
1693 for (MVT TargetVT : MVT::fixedlen_vector_valuetypes()) {
1694 if (TargetVT == VT)
1695 continue;
1696 setLoadExtAction(ISD::EXTLOAD, TargetVT, VT, Expand);
1697 setLoadExtAction(ISD::ZEXTLOAD, TargetVT, VT, Expand);
1698 setLoadExtAction(ISD::SEXTLOAD, TargetVT, VT, Expand);
1699 setTruncStoreAction(VT, TargetVT, Expand);
1700 }
1701
1702 // Normalize all inputs to SELECT to be vectors of i32.
1703 if (VT.getVectorElementType() != MVT::i32) {
1704 MVT VT32 = MVT::getVectorVT(MVT::i32, VT.getSizeInBits()/32);
1706 AddPromotedToType(ISD::SELECT, VT, VT32);
1707 }
1711 }
1712
1715
1716 // Extending loads from (native) vectors of i8 into (native) vectors of i16
1717 // are legal.
1718 setLoadExtAction(ISD::EXTLOAD, MVT::v2i16, MVT::v2i8, Legal);
1719 setLoadExtAction(ISD::ZEXTLOAD, MVT::v2i16, MVT::v2i8, Legal);
1720 setLoadExtAction(ISD::SEXTLOAD, MVT::v2i16, MVT::v2i8, Legal);
1721 setLoadExtAction(ISD::EXTLOAD, MVT::v4i16, MVT::v4i8, Legal);
1722 setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i16, MVT::v4i8, Legal);
1723 setLoadExtAction(ISD::SEXTLOAD, MVT::v4i16, MVT::v4i8, Legal);
1724
1728
1729 // Types natively supported:
1730 for (MVT NativeVT : {MVT::v8i1, MVT::v4i1, MVT::v2i1, MVT::v4i8,
1731 MVT::v8i8, MVT::v2i16, MVT::v4i16, MVT::v2i32}) {
1738
1739 setOperationAction(ISD::ADD, NativeVT, Legal);
1740 setOperationAction(ISD::SUB, NativeVT, Legal);
1741 setOperationAction(ISD::MUL, NativeVT, Legal);
1742 setOperationAction(ISD::AND, NativeVT, Legal);
1743 setOperationAction(ISD::OR, NativeVT, Legal);
1744 setOperationAction(ISD::XOR, NativeVT, Legal);
1745
1746 if (NativeVT.getVectorElementType() != MVT::i1) {
1750 }
1751 }
1752
1753 for (MVT VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32}) {
1758 }
1759
1760 // Custom lower unaligned loads.
1761 // Also, for both loads and stores, verify the alignment of the address
1762 // in case it is a compile-time constant. This is a usability feature to
1763 // provide a meaningful error message to users.
1764 for (MVT VT : {MVT::i16, MVT::i32, MVT::v4i8, MVT::i64, MVT::v8i8,
1765 MVT::v2i16, MVT::v4i16, MVT::v2i32}) {
1768 }
1769
1770 // Custom-lower load/stores of boolean vectors.
1771 for (MVT VT : {MVT::v2i1, MVT::v4i1, MVT::v8i1}) {
1774 }
1775
1776 // Normalize integer compares to EQ/GT/UGT
1777 for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v8i8, MVT::v2i32, MVT::v4i16,
1778 MVT::v2i32}) {
1786 }
1787
1788 // Normalize boolean compares to [U]LE/[U]LT
1789 for (MVT VT : {MVT::i1, MVT::v2i1, MVT::v4i1, MVT::v8i1}) {
1794 }
1795
1796 // Custom-lower bitcasts from i8 to v8i1.
1798 setOperationAction(ISD::SETCC, MVT::v2i16, Custom);
1804
1805 // V5+.
1811
1814
1827
1828 // Special handling for half-precision floating point conversions.
1829 // Lower half float conversions into library calls.
1837
1838 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
1839 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
1840 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::bf16, Expand);
1841 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::bf16, Expand);
1842
1843 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
1844 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
1845
1846 // Handling of indexed loads/stores: default is "expand".
1847 //
1848 for (MVT VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64, MVT::f32, MVT::f64,
1849 MVT::v2i16, MVT::v2i32, MVT::v4i8, MVT::v4i16, MVT::v8i8}) {
1852 }
1853
1854 // Subtarget-specific operation actions.
1855 //
1856 if (Subtarget.hasV60Ops()) {
1861 }
1862 if (Subtarget.hasV66Ops()) {
1865 }
1866 if (Subtarget.hasV67Ops()) {
1870 }
1871
1875
1876 if (Subtarget.useHVXOps())
1877 initializeHVXLowering();
1878
1880}
1881
1882bool
1883HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
1884 const SDLoc &dl, SelectionDAG &DAG) const {
1885 auto *CA = dyn_cast<ConstantSDNode>(Ptr);
1886 if (!CA)
1887 return true;
1888 unsigned Addr = CA->getZExtValue();
1889 Align HaveAlign =
1890 Addr != 0 ? Align(1ull << llvm::countr_zero(Addr)) : NeedAlign;
1891 if (HaveAlign >= NeedAlign)
1892 return true;
1893
1894 static int DK_MisalignedTrap = llvm::getNextAvailablePluginDiagnosticKind();
1895
1896 struct DiagnosticInfoMisalignedTrap : public DiagnosticInfo {
1897 DiagnosticInfoMisalignedTrap(StringRef M)
1898 : DiagnosticInfo(DK_MisalignedTrap, DS_Remark), Msg(M) {}
1899 void print(DiagnosticPrinter &DP) const override {
1900 DP << Msg;
1901 }
1902 static bool classof(const DiagnosticInfo *DI) {
1903 return DI->getKind() == DK_MisalignedTrap;
1904 }
1905 StringRef Msg;
1906 };
1907
1908 std::string ErrMsg;
1909 raw_string_ostream O(ErrMsg);
1910 O << "Misaligned constant address: " << format_hex(Addr, 10)
1911 << " has alignment " << HaveAlign.value()
1912 << ", but the memory access requires " << NeedAlign.value();
1913 if (DebugLoc DL = dl.getDebugLoc())
1914 DL.print(O << ", at ");
1915 O << ". The instruction has been replaced with a trap.";
1916
1917 DAG.getContext()->diagnose(DiagnosticInfoMisalignedTrap(O.str()));
1918 return false;
1919}
1920
1921SDValue
1922HexagonTargetLowering::replaceMemWithUndef(SDValue Op, SelectionDAG &DAG)
1923 const {
1924 const SDLoc &dl(Op);
1925 auto *LS = cast<LSBaseSDNode>(Op.getNode());
1926 assert(!LS->isIndexed() && "Not expecting indexed ops on constant address");
1927
1928 SDValue Chain = LS->getChain();
1929 SDValue Trap = DAG.getNode(ISD::TRAP, dl, MVT::Other, Chain);
1930 if (LS->getOpcode() == ISD::LOAD)
1931 return DAG.getMergeValues({DAG.getUNDEF(ty(Op)), Trap}, dl);
1932 return Trap;
1933}
1934
1935// Bit-reverse Load Intrinsic: Check if the instruction is a bit reverse load
1936// intrinsic.
1937static bool isBrevLdIntrinsic(const Value *Inst) {
1938 unsigned ID = cast<IntrinsicInst>(Inst)->getIntrinsicID();
1939 return (ID == Intrinsic::hexagon_L2_loadrd_pbr ||
1940 ID == Intrinsic::hexagon_L2_loadri_pbr ||
1941 ID == Intrinsic::hexagon_L2_loadrh_pbr ||
1942 ID == Intrinsic::hexagon_L2_loadruh_pbr ||
1943 ID == Intrinsic::hexagon_L2_loadrb_pbr ||
1944 ID == Intrinsic::hexagon_L2_loadrub_pbr);
1945}
1946
1947// Bit-reverse Load Intrinsic :Crawl up and figure out the object from previous
1948// instruction. So far we only handle bitcast, extract value and bit reverse
1949// load intrinsic instructions. Should we handle CGEP ?
1951 if (Operator::getOpcode(V) == Instruction::ExtractValue ||
1952 Operator::getOpcode(V) == Instruction::BitCast)
1953 V = cast<Operator>(V)->getOperand(0);
1954 else if (isa<IntrinsicInst>(V) && isBrevLdIntrinsic(V))
1955 V = cast<Instruction>(V)->getOperand(0);
1956 return V;
1957}
1958
1959// Bit-reverse Load Intrinsic: For a PHI Node return either an incoming edge or
1960// a back edge. If the back edge comes from the intrinsic itself, the incoming
1961// edge is returned.
1962static Value *returnEdge(const PHINode *PN, Value *IntrBaseVal) {
1963 const BasicBlock *Parent = PN->getParent();
1964 int Idx = -1;
1965 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
1966 BasicBlock *Blk = PN->getIncomingBlock(i);
1967 // Determine if the back edge is originated from intrinsic.
1968 if (Blk == Parent) {
1969 Value *BackEdgeVal = PN->getIncomingValue(i);
1970 Value *BaseVal;
1971 // Loop over till we return the same Value or we hit the IntrBaseVal.
1972 do {
1973 BaseVal = BackEdgeVal;
1974 BackEdgeVal = getBrevLdObject(BackEdgeVal);
1975 } while ((BaseVal != BackEdgeVal) && (IntrBaseVal != BackEdgeVal));
1976 // If the getBrevLdObject returns IntrBaseVal, we should return the
1977 // incoming edge.
1978 if (IntrBaseVal == BackEdgeVal)
1979 continue;
1980 Idx = i;
1981 break;
1982 } else // Set the node to incoming edge.
1983 Idx = i;
1984 }
1985 assert(Idx >= 0 && "Unexpected index to incoming argument in PHI");
1986 return PN->getIncomingValue(Idx);
1987}
1988
1989// Bit-reverse Load Intrinsic: Figure out the underlying object the base
1990// pointer points to, for the bit-reverse load intrinsic. Setting this to
1991// memoperand might help alias analysis to figure out the dependencies.
1993 Value *IntrBaseVal = V;
1994 Value *BaseVal;
1995 // Loop over till we return the same Value, implies we either figure out
1996 // the object or we hit a PHI
1997 do {
1998 BaseVal = V;
1999 V = getBrevLdObject(V);
2000 } while (BaseVal != V);
2001
2002 // Identify the object from PHINode.
2003 if (const PHINode *PN = dyn_cast<PHINode>(V))
2004 return returnEdge(PN, IntrBaseVal);
2005 // For non PHI nodes, the object is the last value returned by getBrevLdObject
2006 else
2007 return V;
2008}
2009
2010/// Given an intrinsic, checks if on the target the intrinsic will need to map
2011/// to a MemIntrinsicNode (touches memory). If this is the case, it stores
2012/// the intrinsic information into the Infos vector.
2015 MachineFunction &MF, unsigned Intrinsic) const {
2016 IntrinsicInfo Info;
2017 switch (Intrinsic) {
2018 case Intrinsic::hexagon_L2_loadrd_pbr:
2019 case Intrinsic::hexagon_L2_loadri_pbr:
2020 case Intrinsic::hexagon_L2_loadrh_pbr:
2021 case Intrinsic::hexagon_L2_loadruh_pbr:
2022 case Intrinsic::hexagon_L2_loadrb_pbr:
2023 case Intrinsic::hexagon_L2_loadrub_pbr: {
2024 Info.opc = ISD::INTRINSIC_W_CHAIN;
2025 auto &DL = I.getDataLayout();
2026 auto &Cont = I.getCalledFunction()->getParent()->getContext();
2027 // The intrinsic function call is of the form { ElTy, i8* }
2028 // @llvm.hexagon.L2.loadXX.pbr(i8*, i32). The pointer and memory access type
2029 // should be derived from ElTy.
2030 Type *ElTy = I.getCalledFunction()->getReturnType()->getStructElementType(0);
2031 Info.memVT = MVT::getVT(ElTy);
2032 llvm::Value *BasePtrVal = I.getOperand(0);
2033 Info.ptrVal = getUnderLyingObjectForBrevLdIntr(BasePtrVal);
2034 // The offset value comes through Modifier register. For now, assume the
2035 // offset is 0.
2036 Info.offset = 0;
2037 Info.align = DL.getABITypeAlign(Info.memVT.getTypeForEVT(Cont));
2038 Info.flags = MachineMemOperand::MOLoad;
2039 Infos.push_back(Info);
2040 return;
2041 }
2042 case Intrinsic::hexagon_V6_vgathermw:
2043 case Intrinsic::hexagon_V6_vgathermw_128B:
2044 case Intrinsic::hexagon_V6_vgathermh:
2045 case Intrinsic::hexagon_V6_vgathermh_128B:
2046 case Intrinsic::hexagon_V6_vgathermhw:
2047 case Intrinsic::hexagon_V6_vgathermhw_128B:
2048 case Intrinsic::hexagon_V6_vgathermwq:
2049 case Intrinsic::hexagon_V6_vgathermwq_128B:
2050 case Intrinsic::hexagon_V6_vgathermhq:
2051 case Intrinsic::hexagon_V6_vgathermhq_128B:
2052 case Intrinsic::hexagon_V6_vgathermhwq:
2053 case Intrinsic::hexagon_V6_vgathermhwq_128B:
2054 case Intrinsic::hexagon_V6_vgather_vscattermh:
2055 case Intrinsic::hexagon_V6_vgather_vscattermh_128B: {
2056 const Module &M = *I.getParent()->getParent()->getParent();
2057 Info.opc = ISD::INTRINSIC_W_CHAIN;
2058 Type *VecTy = I.getArgOperand(I.arg_size() - 1)->getType();
2059 assert(VecTy->isVectorTy() && "Expected vector operand for vgather");
2060 Info.memVT = MVT::getVT(VecTy);
2061 Info.ptrVal = I.getArgOperand(0);
2062 Info.offset = 0;
2063 Info.align =
2064 MaybeAlign(M.getDataLayout().getTypeAllocSizeInBits(VecTy) / 8);
2067 Infos.push_back(Info);
2068 return;
2069 }
2070 default:
2071 break;
2072 }
2073}
2074
2076 return X.getValueType().isScalarInteger(); // 'tstbit'
2077}
2078
2080 return isTruncateFree(EVT::getEVT(Ty1), EVT::getEVT(Ty2));
2081}
2082
2084 if (!VT1.isSimple() || !VT2.isSimple())
2085 return false;
2086 return VT1.getSimpleVT() == MVT::i64 && VT2.getSimpleVT() == MVT::i32;
2087}
2088
2093
2094// Should we expand the build vector with shuffles?
2096 unsigned DefinedValues) const {
2097 return false;
2098}
2099
2101 unsigned Index) const {
2103 if (!ResVT.isSimple() || !SrcVT.isSimple())
2104 return false;
2105
2106 MVT ResTy = ResVT.getSimpleVT(), SrcTy = SrcVT.getSimpleVT();
2107 if (ResTy.getVectorElementType() != MVT::i1)
2108 return true;
2109
2110 // Non-HVX bool vectors are relatively cheap.
2111 return SrcTy.getVectorNumElements() <= 8;
2112}
2113
2118
2120 EVT VT) const {
2121 return true;
2122}
2123
2126 unsigned VecLen = VT.getVectorMinNumElements();
2127 MVT ElemTy = VT.getVectorElementType();
2128
2129 if (VecLen == 1 || VT.isScalableVector())
2131
2132 if (Subtarget.useHVXOps()) {
2133 unsigned Action = getPreferredHvxVectorAction(VT);
2134 if (Action != ~0u)
2135 return static_cast<TargetLoweringBase::LegalizeTypeAction>(Action);
2136 }
2137
2138 // Always widen (remaining) vectors of i1.
2139 if (ElemTy == MVT::i1)
2141 // Widen non-power-of-2 vectors. Such types cannot be split right now,
2142 // and computeRegisterProperties will override "split" with "widen",
2143 // which can cause other issues.
2144 if (!isPowerOf2_32(VecLen))
2146
2148}
2149
2152 if (Subtarget.useHVXOps()) {
2153 unsigned Action = getCustomHvxOperationAction(Op);
2154 if (Action != ~0u)
2155 return static_cast<TargetLoweringBase::LegalizeAction>(Action);
2156 }
2158}
2159
2160std::pair<SDValue, int>
2161HexagonTargetLowering::getBaseAndOffset(SDValue Addr) const {
2162 if (Addr.getOpcode() == ISD::ADD) {
2163 SDValue Op1 = Addr.getOperand(1);
2164 if (auto *CN = dyn_cast<const ConstantSDNode>(Op1.getNode()))
2165 return { Addr.getOperand(0), CN->getSExtValue() };
2166 }
2167 return { Addr, 0 };
2168}
2169
2170// Lower a vector shuffle (V1, V2, V3). V1 and V2 are the two vectors
2171// to select data from, V3 is the permutation.
2172SDValue
2174 const {
2175 const auto *SVN = cast<ShuffleVectorSDNode>(Op);
2176 ArrayRef<int> AM = SVN->getMask();
2177 assert(AM.size() <= 8 && "Unexpected shuffle mask");
2178 unsigned VecLen = AM.size();
2179
2180 MVT VecTy = ty(Op);
2181 assert(!Subtarget.isHVXVectorType(VecTy, true) &&
2182 "HVX shuffles should be legal");
2183 assert(VecTy.getSizeInBits() <= 64 && "Unexpected vector length");
2184
2185 SDValue Op0 = Op.getOperand(0);
2186 SDValue Op1 = Op.getOperand(1);
2187 const SDLoc &dl(Op);
2188
2189 // If the inputs are not the same as the output, bail. This is not an
2190 // error situation, but complicates the handling and the default expansion
2191 // (into BUILD_VECTOR) should be adequate.
2192 if (ty(Op0) != VecTy || ty(Op1) != VecTy)
2193 return SDValue();
2194
2195 // Normalize the mask so that the first non-negative index comes from
2196 // the first operand.
2197 SmallVector<int, 8> Mask(AM);
2198 unsigned F = llvm::find_if(AM, [](int M) { return M >= 0; }) - AM.data();
2199 if (F == AM.size())
2200 return DAG.getUNDEF(VecTy);
2201 if (AM[F] >= int(VecLen)) {
2203 std::swap(Op0, Op1);
2204 }
2205
2206 // Express the shuffle mask in terms of bytes.
2207 SmallVector<int,8> ByteMask;
2208 unsigned ElemBytes = VecTy.getVectorElementType().getSizeInBits() / 8;
2209 for (int M : Mask) {
2210 if (M < 0) {
2211 for (unsigned j = 0; j != ElemBytes; ++j)
2212 ByteMask.push_back(-1);
2213 } else {
2214 for (unsigned j = 0; j != ElemBytes; ++j)
2215 ByteMask.push_back(M*ElemBytes + j);
2216 }
2217 }
2218 assert(ByteMask.size() <= 8);
2219
2220 // All non-undef (non-negative) indexes are well within [0..127], so they
2221 // fit in a single byte. Build two 64-bit words:
2222 // - MaskIdx where each byte is the corresponding index (for non-negative
2223 // indexes), and 0xFF for negative indexes, and
2224 // - MaskUnd that has 0xFF for each negative index.
2225 uint64_t MaskIdx = 0;
2226 uint64_t MaskUnd = 0;
2227 for (unsigned i = 0, e = ByteMask.size(); i != e; ++i) {
2228 unsigned S = 8*i;
2229 uint64_t M = ByteMask[i] & 0xFF;
2230 if (M == 0xFF)
2231 MaskUnd |= M << S;
2232 MaskIdx |= M << S;
2233 }
2234
2235 if (ByteMask.size() == 4) {
2236 // Identity.
2237 if (MaskIdx == (0x03020100 | MaskUnd))
2238 return Op0;
2239 // Byte swap.
2240 if (MaskIdx == (0x00010203 | MaskUnd)) {
2241 SDValue T0 = DAG.getBitcast(MVT::i32, Op0);
2242 SDValue T1 = DAG.getNode(ISD::BSWAP, dl, MVT::i32, T0);
2243 return DAG.getBitcast(VecTy, T1);
2244 }
2245
2246 // Byte packs.
2247 SDValue Concat10 =
2248 getCombine(Op1, Op0, dl, typeJoin({ty(Op1), ty(Op0)}), DAG);
2249 if (MaskIdx == (0x06040200 | MaskUnd))
2250 return getInstr(Hexagon::S2_vtrunehb, dl, VecTy, {Concat10}, DAG);
2251 if (MaskIdx == (0x07050301 | MaskUnd))
2252 return getInstr(Hexagon::S2_vtrunohb, dl, VecTy, {Concat10}, DAG);
2253
2254 SDValue Concat01 =
2255 getCombine(Op0, Op1, dl, typeJoin({ty(Op0), ty(Op1)}), DAG);
2256 if (MaskIdx == (0x02000604 | MaskUnd))
2257 return getInstr(Hexagon::S2_vtrunehb, dl, VecTy, {Concat01}, DAG);
2258 if (MaskIdx == (0x03010705 | MaskUnd))
2259 return getInstr(Hexagon::S2_vtrunohb, dl, VecTy, {Concat01}, DAG);
2260 }
2261
2262 if (ByteMask.size() == 8) {
2263 // Identity.
2264 if (MaskIdx == (0x0706050403020100ull | MaskUnd))
2265 return Op0;
2266 // Byte swap.
2267 if (MaskIdx == (0x0001020304050607ull | MaskUnd)) {
2268 SDValue T0 = DAG.getBitcast(MVT::i64, Op0);
2269 SDValue T1 = DAG.getNode(ISD::BSWAP, dl, MVT::i64, T0);
2270 return DAG.getBitcast(VecTy, T1);
2271 }
2272
2273 // Halfword picks.
2274 if (MaskIdx == (0x0d0c050409080100ull | MaskUnd))
2275 return getInstr(Hexagon::S2_shuffeh, dl, VecTy, {Op1, Op0}, DAG);
2276 if (MaskIdx == (0x0f0e07060b0a0302ull | MaskUnd))
2277 return getInstr(Hexagon::S2_shuffoh, dl, VecTy, {Op1, Op0}, DAG);
2278 if (MaskIdx == (0x0d0c090805040100ull | MaskUnd))
2279 return getInstr(Hexagon::S2_vtrunewh, dl, VecTy, {Op1, Op0}, DAG);
2280 if (MaskIdx == (0x0f0e0b0a07060302ull | MaskUnd))
2281 return getInstr(Hexagon::S2_vtrunowh, dl, VecTy, {Op1, Op0}, DAG);
2282 if (MaskIdx == (0x0706030205040100ull | MaskUnd)) {
2283 VectorPair P = opSplit(Op0, dl, DAG);
2284 return getInstr(Hexagon::S2_packhl, dl, VecTy, {P.second, P.first}, DAG);
2285 }
2286
2287 // Byte packs.
2288 if (MaskIdx == (0x0e060c040a020800ull | MaskUnd))
2289 return getInstr(Hexagon::S2_shuffeb, dl, VecTy, {Op1, Op0}, DAG);
2290 if (MaskIdx == (0x0f070d050b030901ull | MaskUnd))
2291 return getInstr(Hexagon::S2_shuffob, dl, VecTy, {Op1, Op0}, DAG);
2292 }
2293
2294 return SDValue();
2295}
2296
2297SDValue
2298HexagonTargetLowering::getSplatValue(SDValue Op, SelectionDAG &DAG) const {
2299 switch (Op.getOpcode()) {
2300 case ISD::BUILD_VECTOR:
2302 return S;
2303 break;
2304 case ISD::SPLAT_VECTOR:
2305 return Op.getOperand(0);
2306 }
2307 return SDValue();
2308}
2309
2310// Create a Hexagon-specific node for shifting a vector by an integer.
2311SDValue
2312HexagonTargetLowering::getVectorShiftByInt(SDValue Op, SelectionDAG &DAG)
2313 const {
2314 unsigned NewOpc;
2315 switch (Op.getOpcode()) {
2316 case ISD::SHL:
2317 NewOpc = HexagonISD::VASL;
2318 break;
2319 case ISD::SRA:
2320 NewOpc = HexagonISD::VASR;
2321 break;
2322 case ISD::SRL:
2323 NewOpc = HexagonISD::VLSR;
2324 break;
2325 default:
2326 llvm_unreachable("Unexpected shift opcode");
2327 }
2328 if (SDValue Sp = getSplatValue(Op.getOperand(1), DAG)) {
2329 const SDLoc dl(Op);
2330 // Canonicalize shift amount to i32 as required.
2331 SDValue Sh = Sp;
2332 if (Sh.getValueType() != MVT::i32)
2333 Sh = DAG.getZExtOrTrunc(Sh, dl, MVT::i32);
2334
2335 assert(Sh.getValueType() == MVT::i32 &&
2336 "Hexagon vector shift-by-int must use i32 shift operand");
2337 return DAG.getNode(NewOpc, dl, ty(Op), Op.getOperand(0), Sh);
2338 }
2339
2340 return SDValue();
2341}
2342
2343SDValue
2345 const SDLoc &dl(Op);
2346
2347 // First try to convert the shift (by vector) to a shift by a scalar.
2348 // If we first split the shift, the shift amount will become 'extract
2349 // subvector', and will no longer be recognized as scalar.
2350 SDValue Res = Op;
2351 if (SDValue S = getVectorShiftByInt(Op, DAG))
2352 Res = S;
2353
2354 unsigned Opc = Res.getOpcode();
2355 switch (Opc) {
2356 case HexagonISD::VASR:
2357 case HexagonISD::VLSR:
2358 case HexagonISD::VASL:
2359 break;
2360 default:
2361 // No instructions for shifts by non-scalars.
2362 return SDValue();
2363 }
2364
2365 MVT ResTy = ty(Res);
2366 if (ResTy.getVectorElementType() != MVT::i8)
2367 return Res;
2368
2369 // For shifts of i8, extend the inputs to i16, then truncate back to i8.
2370 assert(ResTy.getVectorElementType() == MVT::i8);
2371 SDValue Val = Res.getOperand(0), Amt = Res.getOperand(1);
2372
2373 auto ShiftPartI8 = [&dl, &DAG, this](unsigned Opc, SDValue V, SDValue A) {
2374 MVT Ty = ty(V);
2375 MVT ExtTy = MVT::getVectorVT(MVT::i16, Ty.getVectorNumElements());
2376 SDValue ExtV = Opc == HexagonISD::VASR ? DAG.getSExtOrTrunc(V, dl, ExtTy)
2377 : DAG.getZExtOrTrunc(V, dl, ExtTy);
2378 SDValue ExtS = DAG.getNode(Opc, dl, ExtTy, {ExtV, A});
2379 return DAG.getZExtOrTrunc(ExtS, dl, Ty);
2380 };
2381
2382 if (ResTy.getSizeInBits() == 32)
2383 return ShiftPartI8(Opc, Val, Amt);
2384
2385 auto [LoV, HiV] = opSplit(Val, dl, DAG);
2386 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResTy,
2387 {ShiftPartI8(Opc, LoV, Amt), ShiftPartI8(Opc, HiV, Amt)});
2388}
2389
2390SDValue
2392 if (isa<ConstantSDNode>(Op.getOperand(1).getNode()))
2393 return Op;
2394 return SDValue();
2395}
2396
2397SDValue
2399 MVT ResTy = ty(Op);
2400 SDValue InpV = Op.getOperand(0);
2401 MVT InpTy = ty(InpV);
2402 assert(ResTy.getSizeInBits() == InpTy.getSizeInBits());
2403 const SDLoc &dl(Op);
2404
2405 // Handle conversion from i8 to v8i1.
2406 if (InpTy == MVT::i8) {
2407 if (ResTy == MVT::v8i1) {
2408 SDValue Sc = DAG.getBitcast(tyScalar(InpTy), InpV);
2409 SDValue Ext = DAG.getZExtOrTrunc(Sc, dl, MVT::i32);
2410 return getInstr(Hexagon::C2_tfrrp, dl, ResTy, Ext, DAG);
2411 }
2412 return SDValue();
2413 }
2414
2415 return Op;
2416}
2417
2418bool
2419HexagonTargetLowering::getBuildVectorConstInts(ArrayRef<SDValue> Values,
2420 MVT VecTy, SelectionDAG &DAG,
2421 MutableArrayRef<ConstantInt*> Consts) const {
2422 MVT ElemTy = VecTy.getVectorElementType();
2423 unsigned ElemWidth = ElemTy.getSizeInBits();
2424 IntegerType *IntTy = IntegerType::get(*DAG.getContext(), ElemWidth);
2425 bool AllConst = true;
2426
2427 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
2428 SDValue V = Values[i];
2429 if (V.isUndef()) {
2430 Consts[i] = ConstantInt::get(IntTy, 0);
2431 continue;
2432 }
2433 // Make sure to always cast to IntTy.
2434 if (auto *CN = dyn_cast<ConstantSDNode>(V.getNode())) {
2435 const ConstantInt *CI = CN->getConstantIntValue();
2436 Consts[i] = cast<ConstantInt>(
2437 ConstantInt::get(IntTy, CI->getValue().trunc(ElemWidth)));
2438 } else if (auto *CN = dyn_cast<ConstantFPSDNode>(V.getNode())) {
2439 const ConstantFP *CF = CN->getConstantFPValue();
2440 APInt A = CF->getValueAPF().bitcastToAPInt();
2441 Consts[i] = ConstantInt::get(IntTy, A.getZExtValue());
2442 } else {
2443 AllConst = false;
2444 }
2445 }
2446 return AllConst;
2447}
2448
2449SDValue
2450HexagonTargetLowering::buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl,
2451 MVT VecTy, SelectionDAG &DAG) const {
2452 MVT ElemTy = VecTy.getVectorElementType();
2453 assert(VecTy.getVectorNumElements() == Elem.size());
2454
2455 SmallVector<ConstantInt*,4> Consts(Elem.size());
2456 bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
2457
2458 unsigned First, Num = Elem.size();
2459 for (First = 0; First != Num; ++First) {
2460 if (!isUndef(Elem[First]))
2461 break;
2462 }
2463 if (First == Num)
2464 return DAG.getUNDEF(VecTy);
2465
2466 if (AllConst &&
2467 llvm::all_of(Consts, [](ConstantInt *CI) { return CI->isZero(); }))
2468 return getZero(dl, VecTy, DAG);
2469
2470 if (ElemTy == MVT::i16 || ElemTy == MVT::f16) {
2471 assert(Elem.size() == 2);
2472 if (AllConst) {
2473 // The 'Consts' array will have all values as integers regardless
2474 // of the vector element type.
2475 uint32_t V = (Consts[0]->getZExtValue() & 0xFFFF) |
2476 Consts[1]->getZExtValue() << 16;
2477 return DAG.getBitcast(VecTy, DAG.getConstant(V, dl, MVT::i32));
2478 }
2479 SDValue E0, E1;
2480 if (ElemTy == MVT::f16) {
2481 E0 = DAG.getZExtOrTrunc(DAG.getBitcast(MVT::i16, Elem[0]), dl, MVT::i32);
2482 E1 = DAG.getZExtOrTrunc(DAG.getBitcast(MVT::i16, Elem[1]), dl, MVT::i32);
2483 } else {
2484 E0 = Elem[0];
2485 E1 = Elem[1];
2486 }
2487 SDValue N = getInstr(Hexagon::A2_combine_ll, dl, MVT::i32, {E1, E0}, DAG);
2488 return DAG.getBitcast(VecTy, N);
2489 }
2490
2491 if (ElemTy == MVT::i8) {
2492 // First try generating a constant.
2493 if (AllConst) {
2494 uint32_t V = (Consts[0]->getZExtValue() & 0xFF) |
2495 (Consts[1]->getZExtValue() & 0xFF) << 8 |
2496 (Consts[2]->getZExtValue() & 0xFF) << 16 |
2497 Consts[3]->getZExtValue() << 24;
2498 return DAG.getBitcast(MVT::v4i8, DAG.getConstant(V, dl, MVT::i32));
2499 }
2500
2501 // Then try splat.
2502 bool IsSplat = true;
2503 for (unsigned i = First+1; i != Num; ++i) {
2504 if (Elem[i] == Elem[First] || isUndef(Elem[i]))
2505 continue;
2506 IsSplat = false;
2507 break;
2508 }
2509 if (IsSplat) {
2510 // Legalize the operand of SPLAT_VECTOR.
2511 SDValue Ext = DAG.getZExtOrTrunc(Elem[First], dl, MVT::i32);
2512 return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext);
2513 }
2514
2515 // Generate
2516 // (zxtb(Elem[0]) | (zxtb(Elem[1]) << 8)) |
2517 // (zxtb(Elem[2]) | (zxtb(Elem[3]) << 8)) << 16
2518 assert(Elem.size() == 4);
2519 SDValue Vs[4];
2520 for (unsigned i = 0; i != 4; ++i) {
2521 Vs[i] = DAG.getZExtOrTrunc(Elem[i], dl, MVT::i32);
2522 Vs[i] = DAG.getZeroExtendInReg(Vs[i], dl, MVT::i8);
2523 }
2524 SDValue S8 = DAG.getConstant(8, dl, MVT::i32);
2525 SDValue T0 = DAG.getNode(ISD::SHL, dl, MVT::i32, {Vs[1], S8});
2526 SDValue T1 = DAG.getNode(ISD::SHL, dl, MVT::i32, {Vs[3], S8});
2527 SDValue B0 = DAG.getNode(ISD::OR, dl, MVT::i32, {Vs[0], T0});
2528 SDValue B1 = DAG.getNode(ISD::OR, dl, MVT::i32, {Vs[2], T1});
2529
2530 SDValue R = getInstr(Hexagon::A2_combine_ll, dl, MVT::i32, {B1, B0}, DAG);
2531 return DAG.getBitcast(MVT::v4i8, R);
2532 }
2533
2534#ifndef NDEBUG
2535 dbgs() << "VecTy: " << VecTy << '\n';
2536#endif
2537 llvm_unreachable("Unexpected vector element type");
2538}
2539
2540SDValue
2541HexagonTargetLowering::buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl,
2542 MVT VecTy, SelectionDAG &DAG) const {
2543 MVT ElemTy = VecTy.getVectorElementType();
2544 assert(VecTy.getVectorNumElements() == Elem.size());
2545
2546 SmallVector<ConstantInt*,8> Consts(Elem.size());
2547 bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
2548
2549 unsigned First, Num = Elem.size();
2550 for (First = 0; First != Num; ++First) {
2551 if (!isUndef(Elem[First]))
2552 break;
2553 }
2554 if (First == Num)
2555 return DAG.getUNDEF(VecTy);
2556
2557 if (AllConst &&
2558 llvm::all_of(Consts, [](ConstantInt *CI) { return CI->isZero(); }))
2559 return getZero(dl, VecTy, DAG);
2560
2561 // First try splat if possible.
2562 if (ElemTy == MVT::i16 || ElemTy == MVT::f16) {
2563 bool IsSplat = true;
2564 for (unsigned i = First+1; i != Num; ++i) {
2565 if (Elem[i] == Elem[First] || isUndef(Elem[i]))
2566 continue;
2567 IsSplat = false;
2568 break;
2569 }
2570 if (IsSplat) {
2571 // Legalize the operand of SPLAT_VECTOR
2572 SDValue S = ElemTy == MVT::f16 ? DAG.getBitcast(MVT::i16, Elem[First])
2573 : Elem[First];
2574 SDValue Ext = DAG.getZExtOrTrunc(S, dl, MVT::i32);
2575 return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext);
2576 }
2577 }
2578
2579 // Then try constant.
2580 if (AllConst) {
2581 uint64_t Val = 0;
2582 unsigned W = ElemTy.getSizeInBits();
2583 uint64_t Mask = (1ull << W) - 1;
2584 for (unsigned i = 0; i != Num; ++i)
2585 Val = (Val << W) | (Consts[Num-1-i]->getZExtValue() & Mask);
2586 SDValue V0 = DAG.getConstant(Val, dl, MVT::i64);
2587 return DAG.getBitcast(VecTy, V0);
2588 }
2589
2590 // Build two 32-bit vectors and concatenate.
2591 MVT HalfTy = MVT::getVectorVT(ElemTy, Num/2);
2592 SDValue L = (ElemTy == MVT::i32)
2593 ? Elem[0]
2594 : buildVector32(Elem.take_front(Num/2), dl, HalfTy, DAG);
2595 SDValue H = (ElemTy == MVT::i32)
2596 ? Elem[1]
2597 : buildVector32(Elem.drop_front(Num/2), dl, HalfTy, DAG);
2598 return getCombine(H, L, dl, VecTy, DAG);
2599}
2600
2601SDValue
2602HexagonTargetLowering::extractVector(SDValue VecV, SDValue IdxV,
2603 const SDLoc &dl, MVT ValTy, MVT ResTy,
2604 SelectionDAG &DAG) const {
2605 MVT VecTy = ty(VecV);
2606 assert(!ValTy.isVector() ||
2607 VecTy.getVectorElementType() == ValTy.getVectorElementType());
2608 if (VecTy.getVectorElementType() == MVT::i1)
2609 return extractVectorPred(VecV, IdxV, dl, ValTy, ResTy, DAG);
2610
2611 unsigned VecWidth = VecTy.getSizeInBits();
2612 unsigned ValWidth = ValTy.getSizeInBits();
2613 unsigned ElemWidth = VecTy.getVectorElementType().getSizeInBits();
2614 assert((VecWidth % ElemWidth) == 0);
2615 assert(VecWidth == 32 || VecWidth == 64);
2616
2617 // Cast everything to scalar integer types.
2618 MVT ScalarTy = tyScalar(VecTy);
2619 VecV = DAG.getBitcast(ScalarTy, VecV);
2620
2621 SDValue WidthV = DAG.getConstant(ValWidth, dl, MVT::i32);
2622 SDValue ExtV;
2623
2624 if (auto *IdxN = dyn_cast<ConstantSDNode>(IdxV)) {
2625 unsigned Off = IdxN->getZExtValue() * ElemWidth;
2626 if (VecWidth == 64 && ValWidth == 32) {
2627 assert(Off == 0 || Off == 32);
2628 ExtV = Off == 0 ? LoHalf(VecV, DAG) : HiHalf(VecV, DAG);
2629 } else if (Off == 0 && (ValWidth % 8) == 0) {
2630 ExtV = DAG.getZeroExtendInReg(VecV, dl, tyScalar(ValTy));
2631 } else {
2632 SDValue OffV = DAG.getConstant(Off, dl, MVT::i32);
2633 // The return type of EXTRACTU must be the same as the type of the
2634 // input vector.
2635 ExtV = DAG.getNode(HexagonISD::EXTRACTU, dl, ScalarTy,
2636 {VecV, WidthV, OffV});
2637 }
2638 } else {
2639 if (ty(IdxV) != MVT::i32)
2640 IdxV = DAG.getZExtOrTrunc(IdxV, dl, MVT::i32);
2641 SDValue OffV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
2642 DAG.getConstant(ElemWidth, dl, MVT::i32));
2643 ExtV = DAG.getNode(HexagonISD::EXTRACTU, dl, ScalarTy,
2644 {VecV, WidthV, OffV});
2645 }
2646
2647 // Cast ExtV to the requested result type.
2648 ExtV = DAG.getZExtOrTrunc(ExtV, dl, tyScalar(ResTy));
2649 ExtV = DAG.getBitcast(ResTy, ExtV);
2650 return ExtV;
2651}
2652
2653SDValue
2654HexagonTargetLowering::extractVectorPred(SDValue VecV, SDValue IdxV,
2655 const SDLoc &dl, MVT ValTy, MVT ResTy,
2656 SelectionDAG &DAG) const {
2657 // Special case for v{8,4,2}i1 (the only boolean vectors legal in Hexagon
2658 // without any coprocessors).
2659 MVT VecTy = ty(VecV);
2660 unsigned VecWidth = VecTy.getSizeInBits();
2661 unsigned ValWidth = ValTy.getSizeInBits();
2662 assert(VecWidth == VecTy.getVectorNumElements() &&
2663 "Vector elements should equal vector width size");
2664 assert(VecWidth == 8 || VecWidth == 4 || VecWidth == 2);
2665
2666 // Check if this is an extract of the lowest bit.
2667 if (isNullConstant(IdxV) && ValTy.getSizeInBits() == 1) {
2668 // Extracting the lowest bit is a no-op, but it changes the type,
2669 // so it must be kept as an operation to avoid errors related to
2670 // type mismatches.
2671 return DAG.getNode(HexagonISD::TYPECAST, dl, MVT::i1, VecV);
2672 }
2673
2674 // If the value extracted is a single bit, use tstbit.
2675 if (ValWidth == 1) {
2676 SDValue A0 = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {VecV}, DAG);
2677 SDValue M0 = DAG.getConstant(8 / VecWidth, dl, MVT::i32);
2678 SDValue I0 = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, M0);
2679 return DAG.getNode(HexagonISD::TSTBIT, dl, MVT::i1, A0, I0);
2680 }
2681
2682 // Each bool vector (v2i1, v4i1, v8i1) always occupies 8 bits in
2683 // a predicate register. The elements of the vector are repeated
2684 // in the register (if necessary) so that the total number is 8.
2685 // The extracted subvector will need to be expanded in such a way.
2686 unsigned Scale = VecWidth / ValWidth;
2687
2688 // Generate (p2d VecV) >> 8*Idx to move the interesting bytes to
2689 // position 0.
2690 assert(ty(IdxV) == MVT::i32);
2691 unsigned VecRep = 8 / VecWidth;
2692 SDValue S0 = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
2693 DAG.getConstant(8*VecRep, dl, MVT::i32));
2694 SDValue T0 = DAG.getNode(HexagonISD::P2D, dl, MVT::i64, VecV);
2695 SDValue T1 = DAG.getNode(ISD::SRL, dl, MVT::i64, T0, S0);
2696 while (Scale > 1) {
2697 // The longest possible subvector is at most 32 bits, so it is always
2698 // contained in the low subregister.
2699 T1 = LoHalf(T1, DAG);
2700 T1 = expandPredicate(T1, dl, DAG);
2701 Scale /= 2;
2702 }
2703
2704 return DAG.getNode(HexagonISD::D2P, dl, ResTy, T1);
2705}
2706
2707SDValue
2708HexagonTargetLowering::insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
2709 const SDLoc &dl, MVT ValTy,
2710 SelectionDAG &DAG) const {
2711 MVT VecTy = ty(VecV);
2712 if (VecTy.getVectorElementType() == MVT::i1)
2713 return insertVectorPred(VecV, ValV, IdxV, dl, ValTy, DAG);
2714
2715 unsigned VecWidth = VecTy.getSizeInBits();
2716 unsigned ValWidth = ValTy.getSizeInBits();
2717 assert(VecWidth == 32 || VecWidth == 64);
2718 assert((VecWidth % ValWidth) == 0);
2719
2720 // Cast everything to scalar integer types.
2721 MVT ScalarTy = MVT::getIntegerVT(VecWidth);
2722 // The actual type of ValV may be different than ValTy (which is related
2723 // to the vector type).
2724 unsigned VW = ty(ValV).getSizeInBits();
2725 ValV = DAG.getBitcast(MVT::getIntegerVT(VW), ValV);
2726 VecV = DAG.getBitcast(ScalarTy, VecV);
2727 if (VW != VecWidth)
2728 ValV = DAG.getAnyExtOrTrunc(ValV, dl, ScalarTy);
2729
2730 SDValue WidthV = DAG.getConstant(ValWidth, dl, MVT::i32);
2731 SDValue InsV;
2732
2733 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(IdxV)) {
2734 unsigned W = C->getZExtValue() * ValWidth;
2735 SDValue OffV = DAG.getConstant(W, dl, MVT::i32);
2736 InsV = DAG.getNode(HexagonISD::INSERT, dl, ScalarTy,
2737 {VecV, ValV, WidthV, OffV});
2738 } else {
2739 if (ty(IdxV) != MVT::i32)
2740 IdxV = DAG.getZExtOrTrunc(IdxV, dl, MVT::i32);
2741 SDValue OffV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, WidthV);
2742 InsV = DAG.getNode(HexagonISD::INSERT, dl, ScalarTy,
2743 {VecV, ValV, WidthV, OffV});
2744 }
2745
2746 return DAG.getNode(ISD::BITCAST, dl, VecTy, InsV);
2747}
2748
2749SDValue
2750HexagonTargetLowering::insertVectorPred(SDValue VecV, SDValue ValV,
2751 SDValue IdxV, const SDLoc &dl,
2752 MVT ValTy, SelectionDAG &DAG) const {
2753 MVT VecTy = ty(VecV);
2754 unsigned VecLen = VecTy.getVectorNumElements();
2755
2756 if (ValTy == MVT::i1) {
2757 SDValue ToReg = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {VecV}, DAG);
2758 SDValue Ext = DAG.getSExtOrTrunc(ValV, dl, MVT::i32);
2759 SDValue Width = DAG.getConstant(8 / VecLen, dl, MVT::i32);
2760 SDValue Idx = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, Width);
2761 SDValue Ins =
2762 DAG.getNode(HexagonISD::INSERT, dl, MVT::i32, {ToReg, Ext, Width, Idx});
2763 return getInstr(Hexagon::C2_tfrrp, dl, VecTy, {Ins}, DAG);
2764 }
2765
2766 assert(ValTy.getVectorElementType() == MVT::i1);
2767 SDValue ValR = ValTy.isVector()
2768 ? DAG.getNode(HexagonISD::P2D, dl, MVT::i64, ValV)
2769 : DAG.getSExtOrTrunc(ValV, dl, MVT::i64);
2770
2771 unsigned Scale = VecLen / ValTy.getVectorNumElements();
2772 assert(Scale > 1);
2773
2774 for (unsigned R = Scale; R > 1; R /= 2) {
2775 ValR = contractPredicate(ValR, dl, DAG);
2776 ValR = getCombine(DAG.getUNDEF(MVT::i32), ValR, dl, MVT::i64, DAG);
2777 }
2778
2779 SDValue Width = DAG.getConstant(64 / Scale, dl, MVT::i32);
2780 SDValue Idx = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, Width);
2781 SDValue VecR = DAG.getNode(HexagonISD::P2D, dl, MVT::i64, VecV);
2782 SDValue Ins =
2783 DAG.getNode(HexagonISD::INSERT, dl, MVT::i64, {VecR, ValR, Width, Idx});
2784 return DAG.getNode(HexagonISD::D2P, dl, VecTy, Ins);
2785}
2786
2787SDValue
2788HexagonTargetLowering::expandPredicate(SDValue Vec32, const SDLoc &dl,
2789 SelectionDAG &DAG) const {
2790 assert(ty(Vec32).getSizeInBits() == 32);
2791 if (isUndef(Vec32))
2792 return DAG.getUNDEF(MVT::i64);
2793 SDValue P = DAG.getBitcast(MVT::v4i8, Vec32);
2794 SDValue X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i16, P);
2795 return DAG.getBitcast(MVT::i64, X);
2796}
2797
2798SDValue
2799HexagonTargetLowering::contractPredicate(SDValue Vec64, const SDLoc &dl,
2800 SelectionDAG &DAG) const {
2801 assert(ty(Vec64).getSizeInBits() == 64);
2802 if (isUndef(Vec64))
2803 return DAG.getUNDEF(MVT::i32);
2804 // Collect even bytes:
2805 SDValue A = DAG.getBitcast(MVT::v8i8, Vec64);
2806 SDValue S = DAG.getVectorShuffle(MVT::v8i8, dl, A, DAG.getUNDEF(MVT::v8i8),
2807 {0, 2, 4, 6, 1, 3, 5, 7});
2808 return extractVector(S, DAG.getConstant(0, dl, MVT::i32), dl, MVT::v4i8,
2809 MVT::i32, DAG);
2810}
2811
2812SDValue
2813HexagonTargetLowering::getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG)
2814 const {
2815 if (Ty.isVector()) {
2816 unsigned W = Ty.getSizeInBits();
2817 if (W <= 64)
2818 return DAG.getBitcast(Ty, DAG.getConstant(0, dl, MVT::getIntegerVT(W)));
2819 return DAG.getNode(ISD::SPLAT_VECTOR, dl, Ty, getZero(dl, MVT::i32, DAG));
2820 }
2821
2822 if (Ty.isInteger())
2823 return DAG.getConstant(0, dl, Ty);
2824 if (Ty.isFloatingPoint())
2825 return DAG.getConstantFP(0.0, dl, Ty);
2826 llvm_unreachable("Invalid type for zero");
2827}
2828
2829SDValue
2830HexagonTargetLowering::appendUndef(SDValue Val, MVT ResTy, SelectionDAG &DAG)
2831 const {
2832 MVT ValTy = ty(Val);
2834
2835 unsigned ValLen = ValTy.getVectorNumElements();
2836 unsigned ResLen = ResTy.getVectorNumElements();
2837 if (ValLen == ResLen)
2838 return Val;
2839
2840 const SDLoc &dl(Val);
2841 assert(ValLen < ResLen);
2842 assert(ResLen % ValLen == 0);
2843
2844 SmallVector<SDValue, 4> Concats = {Val};
2845 for (unsigned i = 1, e = ResLen / ValLen; i < e; ++i)
2846 Concats.push_back(DAG.getUNDEF(ValTy));
2847
2848 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResTy, Concats);
2849}
2850
2851SDValue
2852HexagonTargetLowering::getCombine(SDValue Hi, SDValue Lo, const SDLoc &dl,
2853 MVT ResTy, SelectionDAG &DAG) const {
2854 MVT ElemTy = ty(Hi);
2855 assert(ElemTy == ty(Lo));
2856
2857 if (!ElemTy.isVector()) {
2858 assert(ElemTy.isScalarInteger());
2859 MVT PairTy = MVT::getIntegerVT(2 * ElemTy.getSizeInBits());
2860 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, PairTy, Lo, Hi);
2861 return DAG.getBitcast(ResTy, Pair);
2862 }
2863
2864 unsigned Width = ElemTy.getSizeInBits();
2865 MVT IntTy = MVT::getIntegerVT(Width);
2866 MVT PairTy = MVT::getIntegerVT(2 * Width);
2867 SDValue Pair =
2869 {DAG.getBitcast(IntTy, Lo), DAG.getBitcast(IntTy, Hi)});
2870 return DAG.getBitcast(ResTy, Pair);
2871}
2872
2873SDValue
2875 MVT VecTy = ty(Op);
2876 unsigned BW = VecTy.getSizeInBits();
2877 const SDLoc &dl(Op);
2879 for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i)
2880 Ops.push_back(Op.getOperand(i));
2881
2882 if (BW == 32)
2883 return buildVector32(Ops, dl, VecTy, DAG);
2884 if (BW == 64)
2885 return buildVector64(Ops, dl, VecTy, DAG);
2886
2887 if (VecTy == MVT::v8i1 || VecTy == MVT::v4i1 || VecTy == MVT::v2i1) {
2888 // Check if this is a special case or all-0 or all-1.
2889 bool All0 = true, All1 = true;
2890 for (SDValue P : Ops) {
2891 auto *CN = dyn_cast<ConstantSDNode>(P.getNode());
2892 if (CN == nullptr) {
2893 All0 = All1 = false;
2894 break;
2895 }
2896 uint32_t C = CN->getZExtValue();
2897 All0 &= (C == 0);
2898 All1 &= (C == 1);
2899 }
2900 if (All0)
2901 return DAG.getNode(HexagonISD::PFALSE, dl, VecTy);
2902 if (All1)
2903 return DAG.getNode(HexagonISD::PTRUE, dl, VecTy);
2904
2905 // For each i1 element in the resulting predicate register, put 1
2906 // shifted by the index of the element into a general-purpose register,
2907 // then or them together and transfer it back into a predicate register.
2908 SDValue Rs[8];
2909 SDValue Z = getZero(dl, MVT::i32, DAG);
2910 // Always produce 8 bits, repeat inputs if necessary.
2911 unsigned Rep = 8 / VecTy.getVectorNumElements();
2912 for (unsigned i = 0; i != 8; ++i) {
2913 SDValue S = DAG.getConstant(1ull << i, dl, MVT::i32);
2914 Rs[i] = DAG.getSelect(dl, MVT::i32, Ops[i/Rep], S, Z);
2915 }
2916 for (ArrayRef<SDValue> A(Rs); A.size() != 1; A = A.drop_back(A.size()/2)) {
2917 for (unsigned i = 0, e = A.size()/2; i != e; ++i)
2918 Rs[i] = DAG.getNode(ISD::OR, dl, MVT::i32, Rs[2*i], Rs[2*i+1]);
2919 }
2920 // Move the value directly to a predicate register.
2921 return getInstr(Hexagon::C2_tfrrp, dl, VecTy, {Rs[0]}, DAG);
2922 }
2923
2924 return SDValue();
2925}
2926
2927SDValue
2929 SelectionDAG &DAG) const {
2930 MVT VecTy = ty(Op);
2931 const SDLoc &dl(Op);
2932 if (VecTy.getSizeInBits() == 64) {
2933 assert(Op.getNumOperands() == 2);
2934 return getCombine(Op.getOperand(1), Op.getOperand(0), dl, VecTy, DAG);
2935 }
2936
2937 MVT ElemTy = VecTy.getVectorElementType();
2938 if (ElemTy == MVT::i1) {
2939 assert(VecTy == MVT::v2i1 || VecTy == MVT::v4i1 || VecTy == MVT::v8i1);
2940 MVT OpTy = ty(Op.getOperand(0));
2941 // Scale is how many times the operands need to be contracted to match
2942 // the representation in the target register.
2943 unsigned Scale = VecTy.getVectorNumElements() / OpTy.getVectorNumElements();
2944 assert(Scale == Op.getNumOperands() && Scale > 1);
2945
2946 // First, convert all bool vectors to integers, then generate pairwise
2947 // inserts to form values of doubled length. Up until there are only
2948 // two values left to concatenate, all of these values will fit in a
2949 // 32-bit integer, so keep them as i32 to use 32-bit inserts.
2950 SmallVector<SDValue,4> Words[2];
2951 unsigned IdxW = 0;
2952
2953 for (SDValue P : Op.getNode()->op_values()) {
2954 SDValue W = DAG.getNode(HexagonISD::P2D, dl, MVT::i64, P);
2955 for (unsigned R = Scale; R > 1; R /= 2) {
2956 W = contractPredicate(W, dl, DAG);
2957 W = getCombine(DAG.getUNDEF(MVT::i32), W, dl, MVT::i64, DAG);
2958 }
2959 W = LoHalf(W, DAG);
2960 Words[IdxW].push_back(W);
2961 }
2962
2963 while (Scale > 2) {
2964 SDValue WidthV = DAG.getConstant(64 / Scale, dl, MVT::i32);
2965 Words[IdxW ^ 1].clear();
2966
2967 for (unsigned i = 0, e = Words[IdxW].size(); i != e; i += 2) {
2968 SDValue W0 = Words[IdxW][i], W1 = Words[IdxW][i+1];
2969 // Insert W1 into W0 right next to the significant bits of W0.
2970 SDValue T = DAG.getNode(HexagonISD::INSERT, dl, MVT::i32,
2971 {W0, W1, WidthV, WidthV});
2972 Words[IdxW ^ 1].push_back(T);
2973 }
2974 IdxW ^= 1;
2975 Scale /= 2;
2976 }
2977
2978 // At this point there should only be two words left, and Scale should be 2.
2979 assert(Scale == 2 && Words[IdxW].size() == 2);
2980
2981 SDValue WW = getCombine(Words[IdxW][1], Words[IdxW][0], dl, MVT::i64, DAG);
2982 return DAG.getNode(HexagonISD::D2P, dl, VecTy, WW);
2983 }
2984
2985 return SDValue();
2986}
2987
2988SDValue
2990 SelectionDAG &DAG) const {
2991 SDValue Vec = Op.getOperand(0);
2992 MVT ElemTy = ty(Vec).getVectorElementType();
2993 return extractVector(Vec, Op.getOperand(1), SDLoc(Op), ElemTy, ty(Op), DAG);
2994}
2995
2996SDValue
2998 SelectionDAG &DAG) const {
2999 return extractVector(Op.getOperand(0), Op.getOperand(1), SDLoc(Op),
3000 ty(Op), ty(Op), DAG);
3001}
3002
3003SDValue
3005 SelectionDAG &DAG) const {
3006 return insertVector(Op.getOperand(0), Op.getOperand(1), Op.getOperand(2),
3007 SDLoc(Op), ty(Op).getVectorElementType(), DAG);
3008}
3009
3010SDValue
3012 SelectionDAG &DAG) const {
3013 SDValue ValV = Op.getOperand(1);
3014 return insertVector(Op.getOperand(0), ValV, Op.getOperand(2),
3015 SDLoc(Op), ty(ValV), DAG);
3016}
3017
3018bool
3020 // Assuming the caller does not have either a signext or zeroext modifier, and
3021 // only one value is accepted, any reasonable truncation is allowed.
3022 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
3023 return false;
3024
3025 // FIXME: in principle up to 64-bit could be made safe, but it would be very
3026 // fragile at the moment: any support for multiple value returns would be
3027 // liable to disallow tail calls involving i64 -> iN truncation in many cases.
3028 return Ty1->getPrimitiveSizeInBits() <= 32;
3029}
3030
3031SDValue
3033 MVT Ty = ty(Op);
3034 const SDLoc &dl(Op);
3035 LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
3036 MVT MemTy = LN->getMemoryVT().getSimpleVT();
3038
3039 bool LoadPred = MemTy == MVT::v2i1 || MemTy == MVT::v4i1 || MemTy == MVT::v8i1;
3040 if (LoadPred) {
3041 SDValue NL = DAG.getLoad(
3042 LN->getAddressingMode(), ISD::ZEXTLOAD, MVT::i32, dl, LN->getChain(),
3043 LN->getBasePtr(), LN->getOffset(), LN->getPointerInfo(),
3044 /*MemoryVT*/ MVT::i8, LN->getAlign(), LN->getMemOperand()->getFlags(),
3045 LN->getAAInfo(), LN->getRanges());
3046 LN = cast<LoadSDNode>(NL.getNode());
3047 }
3048
3049 Align ClaimAlign = LN->getAlign();
3050 if (!validateConstPtrAlignment(LN->getBasePtr(), ClaimAlign, dl, DAG))
3051 return replaceMemWithUndef(Op, DAG);
3052
3053 // Call LowerUnalignedLoad for all loads, it recognizes loads that
3054 // don't need extra aligning.
3055 SDValue LU = LowerUnalignedLoad(SDValue(LN, 0), DAG);
3056 if (LoadPred) {
3057 SDValue TP = getInstr(Hexagon::C2_tfrrp, dl, MemTy, {LU}, DAG);
3058 if (ET == ISD::SEXTLOAD) {
3059 TP = DAG.getSExtOrTrunc(TP, dl, Ty);
3060 } else if (ET != ISD::NON_EXTLOAD) {
3061 TP = DAG.getZExtOrTrunc(TP, dl, Ty);
3062 }
3063 SDValue Ch = cast<LoadSDNode>(LU.getNode())->getChain();
3064 return DAG.getMergeValues({TP, Ch}, dl);
3065 }
3066 return LU;
3067}
3068
3069SDValue
3071 const SDLoc &dl(Op);
3072 StoreSDNode *SN = cast<StoreSDNode>(Op.getNode());
3073 SDValue Val = SN->getValue();
3074 MVT Ty = ty(Val);
3075
3076 if (Ty == MVT::v2i1 || Ty == MVT::v4i1 || Ty == MVT::v8i1) {
3077 // Store the exact predicate (all bits).
3078 SDValue TR = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {Val}, DAG);
3079 SDValue NS = DAG.getTruncStore(SN->getChain(), dl, TR, SN->getBasePtr(),
3080 MVT::i8, SN->getMemOperand());
3081 if (SN->isIndexed()) {
3082 NS = DAG.getIndexedStore(NS, dl, SN->getBasePtr(), SN->getOffset(),
3083 SN->getAddressingMode());
3084 }
3085 SN = cast<StoreSDNode>(NS.getNode());
3086 }
3087
3088 Align ClaimAlign = SN->getAlign();
3089 if (!validateConstPtrAlignment(SN->getBasePtr(), ClaimAlign, dl, DAG))
3090 return replaceMemWithUndef(Op, DAG);
3091
3092 MVT StoreTy = SN->getMemoryVT().getSimpleVT();
3093 Align NeedAlign = Subtarget.getTypeAlignment(StoreTy);
3094 if (ClaimAlign < NeedAlign)
3095 return expandUnalignedStore(SN, DAG);
3096 return SDValue(SN, 0);
3097}
3098
3099SDValue
3101 const {
3102 LoadSDNode *LN = cast<LoadSDNode>(Op.getNode());
3103 MVT LoadTy = ty(Op);
3104 unsigned NeedAlign = Subtarget.getTypeAlignment(LoadTy).value();
3105 unsigned HaveAlign = LN->getAlign().value();
3106 if (HaveAlign >= NeedAlign)
3107 return Op;
3108
3109 const SDLoc &dl(Op);
3110 const DataLayout &DL = DAG.getDataLayout();
3111 LLVMContext &Ctx = *DAG.getContext();
3112
3113 // If the load aligning is disabled or the load can be broken up into two
3114 // smaller legal loads, do the default (target-independent) expansion.
3115 bool DoDefault = false;
3116 // Handle it in the default way if this is an indexed load.
3117 if (!LN->isUnindexed())
3118 DoDefault = true;
3119
3120 if (!AlignLoads) {
3122 *LN->getMemOperand()))
3123 return Op;
3124 DoDefault = true;
3125 }
3126 if (!DoDefault && (2 * HaveAlign) == NeedAlign) {
3127 // The PartTy is the equivalent of "getLoadableTypeOfSize(HaveAlign)".
3128 MVT PartTy = HaveAlign <= 8 ? MVT::getIntegerVT(8 * HaveAlign)
3129 : MVT::getVectorVT(MVT::i8, HaveAlign);
3130 DoDefault =
3131 allowsMemoryAccessForAlignment(Ctx, DL, PartTy, *LN->getMemOperand());
3132 }
3133 if (DoDefault) {
3134 std::pair<SDValue, SDValue> P = expandUnalignedLoad(LN, DAG);
3135 return DAG.getMergeValues({P.first, P.second}, dl);
3136 }
3137
3138 // The code below generates two loads, both aligned as NeedAlign, and
3139 // with the distance of NeedAlign between them. For that to cover the
3140 // bits that need to be loaded (and without overlapping), the size of
3141 // the loads should be equal to NeedAlign. This is true for all loadable
3142 // types, but add an assertion in case something changes in the future.
3143 assert(LoadTy.getSizeInBits() == 8*NeedAlign);
3144
3145 unsigned LoadLen = NeedAlign;
3146 SDValue Base = LN->getBasePtr();
3147 SDValue Chain = LN->getChain();
3148 auto BO = getBaseAndOffset(Base);
3149 unsigned BaseOpc = BO.first.getOpcode();
3150 if (BaseOpc == HexagonISD::VALIGNADDR && BO.second % LoadLen == 0)
3151 return Op;
3152
3153 if (BO.second % LoadLen != 0) {
3154 BO.first = DAG.getNode(ISD::ADD, dl, MVT::i32, BO.first,
3155 DAG.getConstant(BO.second % LoadLen, dl, MVT::i32));
3156 BO.second -= BO.second % LoadLen;
3157 }
3158 SDValue BaseNoOff = (BaseOpc != HexagonISD::VALIGNADDR)
3159 ? DAG.getNode(HexagonISD::VALIGNADDR, dl, MVT::i32, BO.first,
3160 DAG.getConstant(NeedAlign, dl, MVT::i32))
3161 : BO.first;
3162 SDValue Base0 =
3163 DAG.getMemBasePlusOffset(BaseNoOff, TypeSize::getFixed(BO.second), dl);
3164 SDValue Base1 = DAG.getMemBasePlusOffset(
3165 BaseNoOff, TypeSize::getFixed(BO.second + LoadLen), dl);
3166
3167 MachineMemOperand *WideMMO = nullptr;
3168 if (MachineMemOperand *MMO = LN->getMemOperand()) {
3170 WideMMO = MF.getMachineMemOperand(
3171 MMO->getPointerInfo(), MMO->getFlags(), 2 * LoadLen, Align(LoadLen),
3172 MMO->getAAInfo(), MMO->getRanges(), MMO->getSyncScopeID(),
3173 MMO->getSuccessOrdering(), MMO->getFailureOrdering());
3174 }
3175
3176 SDValue Load0 = DAG.getLoad(LoadTy, dl, Chain, Base0, WideMMO);
3177 SDValue Load1 = DAG.getLoad(LoadTy, dl, Chain, Base1, WideMMO);
3178
3179 SDValue Aligned = DAG.getNode(HexagonISD::VALIGN, dl, LoadTy,
3180 {Load1, Load0, BaseNoOff.getOperand(0)});
3181 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
3182 Load0.getValue(1), Load1.getValue(1));
3183 SDValue M = DAG.getMergeValues({Aligned, NewChain}, dl);
3184 return M;
3185}
3186
3187SDValue
3189 SDValue X = Op.getOperand(0), Y = Op.getOperand(1);
3190 auto *CY = dyn_cast<ConstantSDNode>(Y);
3191 if (!CY)
3192 return SDValue();
3193
3194 const SDLoc &dl(Op);
3195 SDVTList VTs = Op.getNode()->getVTList();
3196 assert(VTs.NumVTs == 2);
3197 assert(VTs.VTs[1] == MVT::i1);
3198 unsigned Opc = Op.getOpcode();
3199
3200 if (CY) {
3201 uint64_t VY = CY->getZExtValue();
3202 assert(VY != 0 && "This should have been folded");
3203 // X +/- 1
3204 if (VY != 1)
3205 return SDValue();
3206
3207 if (Opc == ISD::UADDO) {
3208 SDValue Op = DAG.getNode(ISD::ADD, dl, VTs.VTs[0], {X, Y});
3209 SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op, getZero(dl, ty(Op), DAG),
3210 ISD::SETEQ);
3211 return DAG.getMergeValues({Op, Ov}, dl);
3212 }
3213 if (Opc == ISD::USUBO) {
3214 SDValue Op = DAG.getNode(ISD::SUB, dl, VTs.VTs[0], {X, Y});
3215 SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op,
3216 DAG.getAllOnesConstant(dl, ty(Op)), ISD::SETEQ);
3217 return DAG.getMergeValues({Op, Ov}, dl);
3218 }
3219 }
3220
3221 return SDValue();
3222}
3223
3225 SelectionDAG &DAG) const {
3226 const SDLoc &dl(Op);
3227 unsigned Opc = Op.getOpcode();
3228 SDValue X = Op.getOperand(0), Y = Op.getOperand(1), C = Op.getOperand(2);
3229
3230 if (Opc == ISD::UADDO_CARRY)
3231 return DAG.getNode(HexagonISD::ADDC, dl, Op.getNode()->getVTList(),
3232 { X, Y, C });
3233
3234 EVT CarryTy = C.getValueType();
3235 SDValue SubC = DAG.getNode(HexagonISD::SUBC, dl, Op.getNode()->getVTList(),
3236 { X, Y, DAG.getLogicalNOT(dl, C, CarryTy) });
3237 SDValue Out[] = { SubC.getValue(0),
3238 DAG.getLogicalNOT(dl, SubC.getValue(1), CarryTy) };
3239 return DAG.getMergeValues(Out, dl);
3240}
3241
3242SDValue
3244 SDValue Chain = Op.getOperand(0);
3245 SDValue Offset = Op.getOperand(1);
3246 SDValue Handler = Op.getOperand(2);
3247 SDLoc dl(Op);
3248 auto PtrVT = getPointerTy(DAG.getDataLayout());
3249
3250 // Mark function as containing a call to EH_RETURN.
3251 HexagonMachineFunctionInfo *FuncInfo =
3253 FuncInfo->setHasEHReturn();
3254
3255 unsigned OffsetReg = Hexagon::R28;
3256
3257 SDValue StoreAddr =
3258 DAG.getNode(ISD::ADD, dl, PtrVT, DAG.getRegister(Hexagon::R30, PtrVT),
3259 DAG.getIntPtrConstant(4, dl));
3260 Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo());
3261 Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset);
3262
3263 // Not needed we already use it as explicit input to EH_RETURN.
3264 // MF.getRegInfo().addLiveOut(OffsetReg);
3265
3266 return DAG.getNode(HexagonISD::EH_RETURN, dl, MVT::Other, Chain);
3267}
3268
3269SDValue
3271 unsigned Opc = Op.getOpcode();
3272 // Handle INLINEASM first.
3274 return LowerINLINEASM(Op, DAG);
3275
3276 if (isHvxOperation(Op.getNode(), DAG)) {
3277 // If HVX lowering returns nothing, try the default lowering.
3278 if (SDValue V = LowerHvxOperation(Op, DAG))
3279 return V;
3280 }
3281
3282 switch (Opc) {
3283 default:
3284#ifndef NDEBUG
3285 Op.getNode()->dumpr(&DAG);
3286#endif
3287 llvm_unreachable("Should not custom lower this!");
3288
3289 case ISD::FDIV:
3290 return LowerFDIV(Op, DAG);
3291 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
3296 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
3297 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
3298 case ISD::BITCAST: return LowerBITCAST(Op, DAG);
3299 case ISD::LOAD: return LowerLoad(Op, DAG);
3300 case ISD::STORE: return LowerStore(Op, DAG);
3301 case ISD::UADDO:
3302 case ISD::USUBO: return LowerUAddSubO(Op, DAG);
3303 case ISD::UADDO_CARRY:
3304 case ISD::USUBO_CARRY: return LowerUAddSubOCarry(Op, DAG);
3305 case ISD::SRA:
3306 case ISD::SHL:
3307 case ISD::SRL: return LowerVECTOR_SHIFT(Op, DAG);
3308 case ISD::ROTL: return LowerROTL(Op, DAG);
3309 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
3310 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
3311 case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
3312 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
3313 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
3315 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
3316 case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
3317 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
3319 case ISD::VACOPY: return LowerVACOPY(Op, DAG);
3320 case ISD::VASTART: return LowerVASTART(Op, DAG);
3322 case ISD::SETCC: return LowerSETCC(Op, DAG);
3323 case ISD::VSELECT: return LowerVSELECT(Op, DAG);
3325 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG);
3326 case ISD::PREFETCH:
3327 return LowerPREFETCH(Op, DAG);
3328 break;
3329 }
3330
3331 return SDValue();
3332}
3333
3334void
3337 SelectionDAG &DAG) const {
3338 if (isHvxOperation(N, DAG)) {
3339 LowerHvxOperationWrapper(N, Results, DAG);
3340 if (!Results.empty())
3341 return;
3342 }
3343
3344 SDValue Op(N, 0);
3345 unsigned Opc = N->getOpcode();
3346
3347 switch (Opc) {
3348 case HexagonISD::SSAT:
3349 case HexagonISD::USAT:
3350 Results.push_back(opJoin(SplitVectorOp(Op, DAG), SDLoc(Op), DAG));
3351 break;
3352 case ISD::STORE:
3353 // We are only custom-lowering stores to verify the alignment of the
3354 // address if it is a compile-time constant. Since a store can be
3355 // modified during type-legalization (the value being stored may need
3356 // legalization), return empty Results here to indicate that we don't
3357 // really make any changes in the custom lowering.
3358 return;
3359 default:
3361 break;
3362 }
3363}
3364
3365void
3368 SelectionDAG &DAG) const {
3369 if (isHvxOperation(N, DAG)) {
3370 ReplaceHvxNodeResults(N, Results, DAG);
3371 if (!Results.empty())
3372 return;
3373 }
3374
3375 const SDLoc &dl(N);
3376 switch (N->getOpcode()) {
3377 case ISD::SRL:
3378 case ISD::SRA:
3379 case ISD::SHL:
3380 return;
3381 case ISD::BITCAST:
3382 // Handle a bitcast from v8i1 to i8.
3383 if (N->getValueType(0) == MVT::i8) {
3384 if (N->getOperand(0).getValueType() == MVT::v8i1) {
3385 SDValue P = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32,
3386 N->getOperand(0), DAG);
3387 SDValue T = DAG.getAnyExtOrTrunc(P, dl, MVT::i8);
3388 Results.push_back(T);
3389 }
3390 }
3391 break;
3392 }
3393}
3394
3395SDValue
3397 DAGCombinerInfo &DCI) const {
3398 SDValue Op(N, 0);
3399 const SDLoc &dl(Op);
3400 unsigned Opc = Op.getOpcode();
3401
3402 // Combining transformations applicable for arbitrary vector sizes.
3403 if (DCI.isBeforeLegalizeOps()) {
3404 switch (Opc) {
3405 case ISD::VECREDUCE_ADD:
3406 if (SDValue V = splitVecReduceAdd(N, DCI.DAG))
3407 return V;
3408 if (SDValue V = expandVecReduceAdd(N, DCI.DAG))
3409 return V;
3410 return SDValue();
3414 if (SDValue V = splitExtendingPartialReduceMLA(N, DCI.DAG))
3415 return V;
3416 return SDValue();
3417 }
3418 } else {
3419 switch (Opc) {
3420 case ISD::VSELECT: {
3421 // (vselect (xor x, ptrue), v0, v1) -> (vselect x, v1, v0)
3422 SDValue Cond = Op.getOperand(0);
3423 if (Cond->getOpcode() == ISD::XOR) {
3424 SDValue C0 = Cond.getOperand(0), C1 = Cond.getOperand(1);
3425 if (C1->getOpcode() == HexagonISD::PTRUE) {
3426 SDValue VSel = DCI.DAG.getNode(ISD::VSELECT, dl, ty(Op), C0,
3427 Op.getOperand(2), Op.getOperand(1));
3428 return VSel;
3429 }
3430 }
3431 return SDValue();
3432 }
3433 }
3434 }
3435
3436 if (isHvxOperation(N, DCI.DAG)) {
3437 if (SDValue V = PerformHvxDAGCombine(N, DCI))
3438 return V;
3439 return SDValue();
3440 }
3441
3442 if (Opc == ISD::TRUNCATE) {
3443 SDValue Op0 = Op.getOperand(0);
3444 // fold (truncate (build pair x, y)) -> (truncate x) or x
3445 if (Op0.getOpcode() == ISD::BUILD_PAIR) {
3446 EVT TruncTy = Op.getValueType();
3447 SDValue Elem0 = Op0.getOperand(0);
3448 // if we match the low element of the pair, just return it.
3449 if (Elem0.getValueType() == TruncTy)
3450 return Elem0;
3451 // otherwise, if the low part is still too large, apply the truncate.
3452 if (Elem0.getValueType().bitsGT(TruncTy))
3453 return DCI.DAG.getNode(ISD::TRUNCATE, dl, TruncTy, Elem0);
3454 }
3455 }
3456
3457 if (DCI.isBeforeLegalizeOps())
3458 return SDValue();
3459
3460 switch (Opc) {
3461 case HexagonISD::P2D: {
3462 SDValue P = Op.getOperand(0);
3463 switch (P.getOpcode()) {
3464 case HexagonISD::PTRUE:
3465 return DCI.DAG.getAllOnesConstant(dl, ty(Op));
3466 case HexagonISD::PFALSE:
3467 return getZero(dl, ty(Op), DCI.DAG);
3468 default:
3469 break;
3470 }
3471 break;
3472 }
3473 case ISD::TRUNCATE: {
3474 SDValue Op0 = Op.getOperand(0);
3475 // fold (truncate (build pair x, y)) -> (truncate x) or x
3476 if (Op0.getOpcode() == ISD::BUILD_PAIR) {
3477 MVT TruncTy = ty(Op);
3478 SDValue Elem0 = Op0.getOperand(0);
3479 // if we match the low element of the pair, just return it.
3480 if (ty(Elem0) == TruncTy)
3481 return Elem0;
3482 // otherwise, if the low part is still too large, apply the truncate.
3483 if (ty(Elem0).bitsGT(TruncTy))
3484 return DCI.DAG.getNode(ISD::TRUNCATE, dl, TruncTy, Elem0);
3485 }
3486 break;
3487 }
3488 case ISD::OR: {
3489 // fold (or (shl xx, s), (zext y)) -> (COMBINE (shl xx, s-32), y)
3490 // if s >= 32
3491 auto fold0 = [&, this](SDValue Op) {
3492 if (ty(Op) != MVT::i64)
3493 return SDValue();
3494 SDValue Shl = Op.getOperand(0);
3495 SDValue Zxt = Op.getOperand(1);
3496 if (Shl.getOpcode() != ISD::SHL)
3497 std::swap(Shl, Zxt);
3498
3499 if (Shl.getOpcode() != ISD::SHL || Zxt.getOpcode() != ISD::ZERO_EXTEND)
3500 return SDValue();
3501
3502 SDValue Z = Zxt.getOperand(0);
3503 auto *Amt = dyn_cast<ConstantSDNode>(Shl.getOperand(1));
3504 if (Amt && Amt->getZExtValue() >= 32 && ty(Z).getSizeInBits() <= 32) {
3505 unsigned A = Amt->getZExtValue();
3506 SDValue S = Shl.getOperand(0);
3507 SDValue T0 = DCI.DAG.getNode(ISD::SHL, dl, ty(S), S,
3508 DCI.DAG.getConstant(A - 32, dl, MVT::i32));
3509 SDValue T1 = DCI.DAG.getZExtOrTrunc(T0, dl, MVT::i32);
3510 SDValue T2 = DCI.DAG.getZExtOrTrunc(Z, dl, MVT::i32);
3511 return DCI.DAG.getNode(HexagonISD::COMBINE, dl, MVT::i64, {T1, T2});
3512 }
3513 return SDValue();
3514 };
3515
3516 if (SDValue R = fold0(Op))
3517 return R;
3518 break;
3519 }
3520 }
3521
3522 return SDValue();
3523}
3524
3525/// Returns relocation base for the given PIC jumptable.
3526SDValue
3528 SelectionDAG &DAG) const {
3529 int Idx = cast<JumpTableSDNode>(Table)->getIndex();
3530 EVT VT = Table.getValueType();
3532 return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Table), VT, T);
3533}
3534
3535//===----------------------------------------------------------------------===//
3536// Inline Assembly Support
3537//===----------------------------------------------------------------------===//
3538
3541 if (Constraint.size() == 1) {
3542 switch (Constraint[0]) {
3543 case 'q':
3544 case 'v':
3545 if (Subtarget.useHVXOps())
3546 return C_RegisterClass;
3547 break;
3548 case 'a':
3549 return C_RegisterClass;
3550 default:
3551 break;
3552 }
3553 }
3554 return TargetLowering::getConstraintType(Constraint);
3555}
3556
3557std::pair<unsigned, const TargetRegisterClass*>
3559 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
3560
3561 if (Constraint.size() == 1) {
3562 switch (Constraint[0]) {
3563 case 'r': // R0-R31
3564 switch (VT.SimpleTy) {
3565 default:
3566 return {0u, nullptr};
3567 case MVT::i1:
3568 case MVT::i8:
3569 case MVT::i16:
3570 case MVT::i32:
3571 case MVT::f32:
3572 return {0u, &Hexagon::IntRegsRegClass};
3573 case MVT::i64:
3574 case MVT::f64:
3575 return {0u, &Hexagon::DoubleRegsRegClass};
3576 }
3577 break;
3578 case 'a': // M0-M1
3579 if (VT != MVT::i32)
3580 return {0u, nullptr};
3581 return {0u, &Hexagon::ModRegsRegClass};
3582 case 'q': // q0-q3
3583 switch (VT.getSizeInBits()) {
3584 default:
3585 return {0u, nullptr};
3586 case 64:
3587 case 128:
3588 return {0u, &Hexagon::HvxQRRegClass};
3589 }
3590 break;
3591 case 'v': // V0-V31
3592 switch (VT.getSizeInBits()) {
3593 default:
3594 return {0u, nullptr};
3595 case 512:
3596 return {0u, &Hexagon::HvxVRRegClass};
3597 case 1024:
3598 if (Subtarget.hasV60Ops() && Subtarget.useHVX128BOps())
3599 return {0u, &Hexagon::HvxVRRegClass};
3600 return {0u, &Hexagon::HvxWRRegClass};
3601 case 2048:
3602 return {0u, &Hexagon::HvxWRRegClass};
3603 }
3604 break;
3605 default:
3606 return {0u, nullptr};
3607 }
3608 }
3609
3610 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3611}
3612
3613/// isFPImmLegal - Returns true if the target can instruction select the
3614/// specified FP immediate natively. If false, the legalizer will
3615/// materialize the FP immediate as a load from a constant pool.
3617 bool ForCodeSize) const {
3618 return true;
3619}
3620
3621/// Returns true if it is beneficial to convert a load of a constant
3622/// to just the constant itself.
3624 Type *Ty) const {
3625 if (!ConstantLoadsToImm)
3626 return false;
3627
3628 assert(Ty->isIntegerTy());
3629 unsigned BitSize = Ty->getPrimitiveSizeInBits();
3630 return (BitSize > 0 && BitSize <= 64);
3631}
3632
3633/// isLegalAddressingMode - Return true if the addressing mode represented by
3634/// AM is legal for this target, for a load/store of the specified type.
3636 const AddrMode &AM, Type *Ty,
3637 unsigned AS, Instruction *I) const {
3638 if (Ty->isSized()) {
3639 // When LSR detects uses of the same base address to access different
3640 // types (e.g. unions), it will assume a conservative type for these
3641 // uses:
3642 // LSR Use: Kind=Address of void in addrspace(4294967295), ...
3643 // The type Ty passed here would then be "void". Skip the alignment
3644 // checks, but do not return false right away, since that confuses
3645 // LSR into crashing.
3646 Align A = DL.getABITypeAlign(Ty);
3647 // The base offset must be a multiple of the alignment.
3648 if (!isAligned(A, AM.BaseOffs))
3649 return false;
3650 // The shifted offset must fit in 11 bits.
3651 if (!isInt<11>(AM.BaseOffs >> Log2(A)))
3652 return false;
3653 }
3654
3655 // No global is ever allowed as a base.
3656 if (AM.BaseGV)
3657 return false;
3658
3659 int Scale = AM.Scale;
3660 if (Scale < 0)
3661 Scale = -Scale;
3662 switch (Scale) {
3663 case 0: // No scale reg, "r+i", "r", or just "i".
3664 break;
3665 default: // No scaled addressing mode.
3666 return false;
3667 }
3668 return true;
3669}
3670
3671/// Return true if folding a constant offset with the given GlobalAddress is
3672/// legal. It is frequently not legal in PIC relocation models.
3674 const {
3675 return HTM.getRelocationModel() == Reloc::Static;
3676}
3677
3678/// isLegalICmpImmediate - Return true if the specified immediate is legal
3679/// icmp immediate, that is the target has icmp instructions which can compare
3680/// a register against the immediate without having to materialize the
3681/// immediate into a register.
3683 return Imm >= -512 && Imm <= 511;
3684}
3685
3686/// IsEligibleForTailCallOptimization - Check whether the call is eligible
3687/// for tail call optimization. Targets which want to do tail call
3688/// optimization should implement this function.
3690 SDValue Callee,
3691 CallingConv::ID CalleeCC,
3692 bool IsVarArg,
3693 bool IsCalleeStructRet,
3694 bool IsCallerStructRet,
3696 const SmallVectorImpl<SDValue> &OutVals,
3698 SelectionDAG& DAG) const {
3699 const Function &CallerF = DAG.getMachineFunction().getFunction();
3700 CallingConv::ID CallerCC = CallerF.getCallingConv();
3701 bool CCMatch = CallerCC == CalleeCC;
3702
3703 // ***************************************************************************
3704 // Look for obvious safe cases to perform tail call optimization that do not
3705 // require ABI changes.
3706 // ***************************************************************************
3707
3708 // If this is a tail call via a function pointer, then don't do it!
3709 if (!isa<GlobalAddressSDNode>(Callee) &&
3710 !isa<ExternalSymbolSDNode>(Callee)) {
3711 return false;
3712 }
3713
3714 // Do not optimize if the calling conventions do not match and the conventions
3715 // used are not C or Fast.
3716 if (!CCMatch) {
3717 bool R = (CallerCC == CallingConv::C || CallerCC == CallingConv::Fast);
3718 bool E = (CalleeCC == CallingConv::C || CalleeCC == CallingConv::Fast);
3719 // If R & E, then ok.
3720 if (!R || !E)
3721 return false;
3722 }
3723
3724 // Do not tail call optimize vararg calls.
3725 if (IsVarArg)
3726 return false;
3727
3728 // Also avoid tail call optimization if either caller or callee uses struct
3729 // return semantics.
3730 if (IsCalleeStructRet || IsCallerStructRet)
3731 return false;
3732
3733 // In addition to the cases above, we also disable Tail Call Optimization if
3734 // the calling convention code that at least one outgoing argument needs to
3735 // go on the stack. We cannot check that here because at this point that
3736 // information is not available.
3737 return true;
3738}
3739
3740/// Returns the target specific optimal type for load and store operations as
3741/// a result of memset, memcpy, and memmove lowering.
3742///
3743/// If DstAlign is zero that means it's safe to destination alignment can
3744/// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
3745/// a need to check it against alignment requirement, probably because the
3746/// source does not need to be loaded. If 'IsMemset' is true, that means it's
3747/// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of
3748/// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
3749/// does not need to be loaded. It returns EVT::Other if the type should be
3750/// determined using generic target-independent logic.
3752 LLVMContext &Context, const MemOp &Op,
3753 const AttributeList &FuncAttributes) const {
3754 if (Op.size() >= 8 && Op.isAligned(Align(8)))
3755 return MVT::i64;
3756 if (Op.size() >= 4 && Op.isAligned(Align(4)))
3757 return MVT::i32;
3758 if (Op.size() >= 2 && Op.isAligned(Align(2)))
3759 return MVT::i16;
3760 return MVT::Other;
3761}
3762
3763// The helpers below are versions of llvm::getShuffleReduction and
3764// llvm::getOrderedReduction, adapted to use during DAG passes and simplified as
3765// follows:
3766// - ICmp and FCmp are not handled;
3767// - in every step in getShuffleReduction, the input is split into halves (not
3768// pairwise).
3769
3771 SelectionDAG &DAG) {
3772 assert(Op != Instruction::ICmp && Op != Instruction::FCmp);
3773
3774 EVT VT = Vec.getValueType();
3775 EVT EltT = VT.getVectorElementType();
3776 unsigned VF = VT.getVectorNumElements();
3777 assert(VF > 0 &&
3778 "Reduction emission only supported for non-zero length vectors!");
3779
3780 SDLoc DL(Vec);
3781 SDValue Result = DAG.getExtractVectorElt(DL, EltT, Vec, 0);
3782 for (unsigned ExtractIdx = 1; ExtractIdx < VF; ++ExtractIdx) {
3783 SDValue Ext = DAG.getExtractVectorElt(DL, EltT, Vec, ExtractIdx);
3784 Result = DAG.getNode(Op, DL, EltT, {Result, Ext});
3785 }
3786
3787 return Result;
3788}
3789
3791 SelectionDAG &DAG) {
3792 assert(Op != Instruction::ICmp && Op != Instruction::FCmp);
3793
3794 EVT VT = Vec.getValueType();
3795 unsigned VF = VT.getVectorNumElements();
3796 if (VF == 0)
3797 llvm_unreachable("Vector must be non-zero length");
3798 // VF is a power of 2 so we can emit the reduction using log2(VF) shuffles
3799 // and vector ops, reducing the set of values being computed by half each
3800 // round.
3801 assert(isPowerOf2_32(VF) &&
3802 "Reduction emission only supported for pow2 vectors!");
3803
3804 SDLoc DL(Vec);
3805 // TODO: Is it correct to create double-vector shuffle and fill 3/4 of it with
3806 // undefs?
3807 SmallVector<int, 32> ShuffleMask(VF);
3808 for (unsigned i = VF; i > 1; i >>= 1) {
3809 // Move the upper half of the vector to the lower half.
3810 for (unsigned j = 0; j != i / 2; ++j)
3811 ShuffleMask[j] = i / 2 + j;
3812 // Fill the rest of the mask with undef.
3813 std::fill(&ShuffleMask[i / 2], ShuffleMask.end(), -1);
3814
3815 SDValue Shuf =
3816 DAG.getVectorShuffle(VT, DL, Vec, DAG.getUNDEF(VT), ShuffleMask);
3817
3818 Vec = DAG.getNode(Op, DL, VT, {Vec, Shuf});
3819 }
3820 // The result is in the first element of the vector.
3821 return DAG.getExtractVectorElt(DL, VT.getVectorElementType(), Vec, 0);
3822}
3823
3824SDValue HexagonTargetLowering::expandVecReduceAdd(SDNode *N,
3825 SelectionDAG &DAG) const {
3826 // Since we disabled automatic reduction expansion, generate log2 ladder code
3827 // if the vector is of a power-of-two length.
3828 SDValue Input = N->getOperand(0);
3830 return getShuffleReduction(Input, ISD::ADD, DAG);
3831 // Otherwise, reduction will be scalarized.
3832 return getOrderedReduction(Input, ISD::ADD, DAG);
3833}
3834
3836 LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace,
3837 Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const {
3838 if (!VT.isSimple())
3839 return false;
3840 MVT SVT = VT.getSimpleVT();
3841 if (Subtarget.isHVXVectorType(SVT, true))
3842 return allowsHvxMemoryAccess(SVT, Flags, Fast);
3844 Context, DL, VT, AddrSpace, Alignment, Flags, Fast);
3845}
3846
3848 EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags,
3849 unsigned *Fast) const {
3850 if (!VT.isSimple())
3851 return false;
3852 MVT SVT = VT.getSimpleVT();
3853 if (Subtarget.isHVXVectorType(SVT, true))
3854 return allowsHvxMisalignedMemoryAccesses(SVT, Flags, Fast);
3855 if (Fast)
3856 *Fast = 0;
3857 return false;
3858}
3859
3860std::pair<const TargetRegisterClass*, uint8_t>
3861HexagonTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
3862 MVT VT) const {
3863 if (Subtarget.isHVXVectorType(VT, true)) {
3864 unsigned BitWidth = VT.getSizeInBits();
3865 unsigned VecWidth = Subtarget.getVectorLength() * 8;
3866
3867 if (VT.getVectorElementType() == MVT::i1)
3868 return std::make_pair(&Hexagon::HvxQRRegClass, 1);
3869 if (BitWidth == VecWidth)
3870 return std::make_pair(&Hexagon::HvxVRRegClass, 1);
3871 assert(BitWidth == 2 * VecWidth);
3872 return std::make_pair(&Hexagon::HvxWRRegClass, 1);
3873 }
3874
3876}
3877
3879 SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
3880 std::optional<unsigned> ByteOffset) const {
3881 // TODO: This may be worth removing. Check regression tests for diffs.
3882 if (!TargetLoweringBase::shouldReduceLoadWidth(Load, ExtTy, NewVT,
3883 ByteOffset))
3884 return false;
3885
3886 auto *L = cast<LoadSDNode>(Load);
3887 std::pair<SDValue, int> BO = getBaseAndOffset(L->getBasePtr());
3888 // Small-data object, do not shrink.
3889 if (BO.first.getOpcode() == HexagonISD::CONST32_GP)
3890 return false;
3892 auto &HTM = static_cast<const HexagonTargetMachine &>(getTargetMachine());
3893 const auto *GO = dyn_cast_or_null<const GlobalObject>(GA->getGlobal());
3894 return !GO || !HTM.getObjFileLowering()->isGlobalInSmallSection(GO, HTM);
3895 }
3896 return true;
3897}
3898
3900 SDNode *Node) const {
3901 AdjustHvxInstrPostInstrSelection(MI, Node);
3902}
3903
3905 Type *ValueTy, Value *Addr,
3906 AtomicOrdering Ord) const {
3907 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
3908 assert((SZ == 32 || SZ == 64) && "Only 32/64-bit atomic loads supported");
3909 Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_L2_loadw_locked
3910 : Intrinsic::hexagon_L4_loadd_locked;
3911
3912 Value *Call =
3913 Builder.CreateIntrinsic(IntID, Addr, /*FMFSource=*/nullptr, "larx");
3914
3915 return Builder.CreateBitCast(Call, ValueTy);
3916}
3917
3918/// Perform a store-conditional operation to Addr. Return the status of the
3919/// store. This should be 0 if the store succeeded, non-zero otherwise.
3921 Value *Val, Value *Addr,
3922 AtomicOrdering Ord) const {
3923 BasicBlock *BB = Builder.GetInsertBlock();
3924 Module *M = BB->getParent()->getParent();
3925 Type *Ty = Val->getType();
3926 unsigned SZ = Ty->getPrimitiveSizeInBits();
3927
3928 Type *CastTy = Builder.getIntNTy(SZ);
3929 assert((SZ == 32 || SZ == 64) && "Only 32/64-bit atomic stores supported");
3930 Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_S2_storew_locked
3931 : Intrinsic::hexagon_S4_stored_locked;
3932
3933 Val = Builder.CreateBitCast(Val, CastTy);
3934
3935 Value *Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
3936 /*FMFSource=*/nullptr, "stcx");
3937 Value *Cmp = Builder.CreateICmpEQ(Call, Builder.getInt32(0), "");
3938 Value *Ext = Builder.CreateZExt(Cmp, Type::getInt32Ty(M->getContext()));
3939 return Ext;
3940}
3941
3944 // Do not expand loads and stores that don't exceed 64 bits.
3945 return LI->getType()->getPrimitiveSizeInBits() > 64
3948}
3949
3952 // Do not expand loads and stores that don't exceed 64 bits.
3953 return SI->getValueOperand()->getType()->getPrimitiveSizeInBits() > 64
3956}
3957
3963
3965 MachineInstr &MI, MachineBasicBlock *BB) const {
3966 switch (MI.getOpcode()) {
3967 case TargetOpcode::PATCHABLE_EVENT_CALL:
3968 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
3969 // These are lowered in the AsmPrinter.
3970 return BB;
3971 default:
3972 llvm_unreachable("Unexpected instruction with custom inserter");
3973 }
3974}
3975
3979 const TargetInstrInfo *TII) const {
3980 assert(MBBI->isCall() && MBBI->getCFIType() &&
3981 "Invalid call instruction for a KCFI check");
3982
3983 switch (MBBI->getOpcode()) {
3984 case Hexagon::J2_callr:
3985 case Hexagon::PS_callr_nr:
3986 break;
3987 default:
3988 llvm_unreachable("Unexpected CFI call opcode");
3989 }
3990
3991 MachineOperand &Target = MBBI->getOperand(0);
3992 assert(Target.isReg() && "Invalid target operand for an indirect call");
3993 Target.setIsRenamable(false);
3994
3995 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Hexagon::KCFI_CHECK))
3996 .addReg(Target.getReg())
3997 .addImm(MBBI->getCFIType())
3998 .getInstr();
3999}
4000
4002 const Instruction &AndI) const {
4003 // Only sink 'and' mask to cmp use block if it is masking a single bit since
4004 // this will fold the and/cmp/br into a single tstbit instruction.
4006 if (!Mask)
4007 return false;
4008 return Mask->getValue().isPowerOf2();
4009}
4010
4011// Check if the result of the node is only used as a return value, as
4012// otherwise we can't perform a tail-call.
4014 SDValue &Chain) const {
4015 if (N->getNumValues() != 1)
4016 return false;
4017 if (!N->hasNUsesOfValue(1, 0))
4018 return false;
4019
4020 SDNode *Copy = *N->user_begin();
4021
4022 if (Copy->getOpcode() == ISD::BITCAST) {
4023 return isUsedByReturnOnly(Copy, Chain);
4024 }
4025
4026 if (Copy->getOpcode() != ISD::CopyToReg) {
4027 return false;
4028 }
4029
4030 // If the ISD::CopyToReg has a glue operand, we conservatively assume it
4031 // isn't safe to perform a tail call.
4032 if (Copy->getOperand(Copy->getNumOperands() - 1).getValueType() == MVT::Glue)
4033 return false;
4034
4035 // The copy must be used by a HexagonISD::RET_GLUE, and nothing else.
4036 bool HasRet = false;
4037 for (SDNode *Node : Copy->users()) {
4038 if (Node->getOpcode() != HexagonISD::RET_GLUE)
4039 return false;
4040 HasRet = true;
4041 }
4042 if (!HasRet)
4043 return false;
4044
4045 Chain = Copy->getOperand(0);
4046 return true;
4047}
4048
4050 const MachineFunction &MF) const {
4051 if (MF.getFunction().hasFnAttribute("probe-stack"))
4052 return MF.getFunction().getFnAttribute("probe-stack").getValueAsString() ==
4053 "inline-asm";
4054 return false;
4055}
4056
4058 Align StackAlign) const {
4059 const Function &Fn = MF.getFunction();
4060 unsigned StackProbeSize =
4061 Fn.getFnAttributeAsParsedInteger("stack-probe-size", 4096);
4062 // Round down to the stack alignment.
4063 StackProbeSize = alignDown(StackProbeSize, StackAlign.value());
4064 return StackProbeSize ? StackProbeSize : StackAlign.value();
4065}
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 & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis Results
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
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:1436
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_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
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:1088
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
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
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:688
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:758
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
Definition Function.cpp:770
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:669
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
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:459
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
MachineInstr * EmitKCFICheck(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MBBI, const TargetInstrInfo *TII) const override
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...
unsigned getStackProbeSize(const MachineFunction &MF, Align StackAlign) const
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
bool hasInlineStackProbe(const MachineFunction &MF) const override
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:467
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2848
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:348
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
Instructions::iterator instr_iterator
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...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
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,.
MachineOperand class - Representation of each machine instruction operand.
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.
void setCFIType(uint32_t Type)
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)
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
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...
Target - Wrapper for Target specific information.
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:827
@ 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:787
@ 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:861
@ 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:888
@ 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...
@ 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:852
@ 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:804
@ 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:858
@ 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:819
@ 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:896
@ 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:813
@ 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:934
@ 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:864
@ 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:841
@ 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:573
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:1739
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:1669
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
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
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:546
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:156
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:1772
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