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