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