LLVM 24.0.0git
BPFISelLowering.cpp
Go to the documentation of this file.
1//===-- BPFISelLowering.cpp - BPF 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 defines the interfaces that BPF uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "BPFISelLowering.h"
15#include "BPF.h"
16#include "BPFSubtarget.h"
25#include "llvm/IR/DIBuilder.h"
28#include "llvm/IR/Module.h"
29#include "llvm/Support/Debug.h"
33
34using namespace llvm;
35
36#define DEBUG_TYPE "bpf-lower"
37
38static cl::opt<bool> BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order",
39 cl::Hidden, cl::init(false),
40 cl::desc("Expand memcpy into load/store pairs in order"));
41
43 "bpf-min-jump-table-entries", cl::init(13), cl::Hidden,
44 cl::desc("Set minimum number of entries to use a jump table on BPF"));
45
47 "bpf-allows-libcalls", cl::Hidden, cl::init(false),
48 cl::desc("Allow libcalls instead of rejecting unsupported built-in "
49 "functions"));
50
51static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg,
52 SDValue Val = {}) {
53 std::string Str;
54 if (Val) {
55 raw_string_ostream OS(Str);
56 Val->print(OS);
57 OS << ' ';
58 }
61 MF.getFunction(), Twine(Str).concat(Msg), DL.getDebugLoc()));
62}
63
65 const BPFSubtarget &STI)
66 : TargetLowering(TM, STI) {
67
68 // Set up the register classes.
69 addRegisterClass(MVT::i64, &BPF::GPRRegClass);
70 if (STI.getHasAlu32())
71 addRegisterClass(MVT::i32, &BPF::GPR32RegClass);
72
73 // Compute derived properties from the register classes
75
77
79 setOperationAction(ISD::BR_JT, MVT::Other, STI.hasGotox() ? Custom : Expand);
81
82 if (!STI.hasGotox())
84
86
88 if (STI.hasGotox())
90
94
95 // Set unsupported atomic operations as Custom so
96 // we can emit better error messages than fatal error
97 // from selectiondag.
98 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
99 if (VT == MVT::i32) {
100 if (STI.getHasAlu32())
101 continue;
102 } else {
104 }
105
111 }
112
113 for (auto VT : {MVT::i32, MVT::i64}) {
116 }
117
119
120 for (auto VT : { MVT::i32, MVT::i64 }) {
121 if (VT == MVT::i32 && !STI.getHasAlu32())
122 continue;
123
126 if (!STI.hasSdivSmod()) {
129 }
130 if (VT == MVT::i32 || !STI.hasHmul()) {
133 }
146
150 }
151
152 if (STI.getHasAlu32()) {
155 STI.getHasJmp32() ? Custom : Promote);
156 }
157
159 if (!STI.hasMovsx()) {
163 }
164
165 // Extended load operations for i1 types must be promoted
166 for (MVT VT : MVT::integer_valuetypes()) {
170
171 if (!STI.hasLdsx()) {
173 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
174 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
175 }
176 }
177
180 // AtomicExpand turns operations on 8 and 16 bits into cmpxchg of the word
181 // that they are in. Its loops start with a relaxed atomic load.
182 if (STI.hasLoadAcqStoreRel())
185
186 // Function alignments
189
191 // LLVM generic code will try to expand memcpy into load/store pairs at this
192 // stage which is before quite a few IR optimization passes, therefore the
193 // loads and stores could potentially be moved apart from each other which
194 // will cause trouble to memcpy pattern matcher inside kernel eBPF JIT
195 // compilers.
196 //
197 // When -bpf-expand-memcpy-in-order specified, we want to defer the expand
198 // of memcpy to later stage in IR optimization pipeline so those load/store
199 // pairs won't be touched and could be kept in order. Hence, we set
200 // MaxStoresPerMem* to zero to disable the generic getMemcpyLoadsAndStores
201 // code path, and ask LLVM to use target expander EmitTargetCodeForMemcpy.
206 } else {
207 // inline memcpy() for kernel to see explicit copy
208 unsigned CommonMaxStores =
210
215 }
216
217 // CPU/Feature control
218 HasAlu32 = STI.getHasAlu32();
219 HasJmp32 = STI.getHasJmp32();
220 HasJmpExt = STI.getHasJmpExt();
221 HasMovsx = STI.hasMovsx();
222 HasLoadAcqStoreRel = STI.hasLoadAcqStoreRel();
223
224 AllowsMisalignedMemAccess = STI.getAllowsMisalignedMemAccess();
225}
226
229 unsigned *Fast) const {
230 // allows-misaligned-mem-access is disabled
231 if (!AllowsMisalignedMemAccess)
232 return false;
233
234 // only allow misalignment for simple value types
235 if (!VT.isSimple())
236 return false;
237
238 // always assume fast mode when misalignment is allowed
239 if (Fast)
240 *Fast = true;
241
242 return true;
243}
244
246 return false;
247}
248
249bool BPFTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const {
250 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
251 return false;
252 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
253 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
254 return NumBits1 > NumBits2;
255}
256
257bool BPFTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
258 if (!VT1.isInteger() || !VT2.isInteger())
259 return false;
260 unsigned NumBits1 = VT1.getSizeInBits();
261 unsigned NumBits2 = VT2.getSizeInBits();
262 return NumBits1 > NumBits2;
263}
264
265bool BPFTargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
266 if (!getHasAlu32() || !Ty1->isIntegerTy() || !Ty2->isIntegerTy())
267 return false;
268 unsigned NumBits1 = Ty1->getPrimitiveSizeInBits();
269 unsigned NumBits2 = Ty2->getPrimitiveSizeInBits();
270 return NumBits1 == 32 && NumBits2 == 64;
271}
272
273bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
274 if (!getHasAlu32() || !VT1.isInteger() || !VT2.isInteger())
275 return false;
276 unsigned NumBits1 = VT1.getSizeInBits();
277 unsigned NumBits2 = VT2.getSizeInBits();
278 return NumBits1 == 32 && NumBits2 == 64;
279}
280
281bool BPFTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
282 EVT VT1 = Val.getValueType();
283 if (Val.getOpcode() == ISD::LOAD && VT1.isSimple() && VT2.isSimple()) {
284 MVT MT1 = VT1.getSimpleVT().SimpleTy;
285 MVT MT2 = VT2.getSimpleVT().SimpleTy;
286 if ((MT1 == MVT::i8 || MT1 == MVT::i16 || MT1 == MVT::i32) &&
287 (MT2 == MVT::i32 || MT2 == MVT::i64))
288 return true;
289 }
290 return TargetLoweringBase::isZExtFree(Val, VT2);
291}
292
296
299 if (Constraint.size() == 1) {
300 switch (Constraint[0]) {
301 default:
302 break;
303 case 'w':
304 return C_RegisterClass;
305 }
306 }
307
308 return TargetLowering::getConstraintType(Constraint);
309}
310
311std::pair<unsigned, const TargetRegisterClass *>
313 StringRef Constraint,
314 MVT VT) const {
315 if (Constraint.size() == 1) {
316 // GCC Constraint Letters
317 switch (Constraint[0]) {
318 case 'r': // GENERAL_REGS
319 return std::make_pair(0U, &BPF::GPRRegClass);
320 case 'w':
321 if (HasAlu32)
322 return std::make_pair(0U, &BPF::GPR32RegClass);
323 break;
324 default:
325 break;
326 }
327 }
328
330}
331
332void BPFTargetLowering::ReplaceNodeResults(
334 const char *Msg;
335 uint32_t Opcode = N->getOpcode();
336 switch (Opcode) {
337 default:
338 report_fatal_error("unhandled custom legalization: " + Twine(Opcode));
343 case ISD::ATOMIC_SWAP:
345 if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD)
346 Msg = "unsupported atomic operation, please use 32/64 bit version";
347 else
348 Msg = "unsupported atomic operation, please use 64 bit version";
349 break;
350 case ISD::ATOMIC_LOAD:
352 return;
353 }
354
355 SDLoc DL(N);
356 // We'll still produce a fatal error downstream, but this diagnostic is more
357 // user-friendly.
358 fail(DL, DAG, Msg);
359}
360
362 switch (Op.getOpcode()) {
363 default:
364 report_fatal_error("unimplemented opcode: " + Twine(Op.getOpcode()));
365 case ISD::BR_CC:
366 return LowerBR_CC(Op, DAG);
367 case ISD::JumpTable:
368 return LowerJumpTable(Op, DAG);
369 case ISD::BR_JT:
370 return LowerBR_JT(Op, DAG);
372 return LowerGlobalAddress(Op, DAG);
374 return LowerConstantPool(Op, DAG);
376 return LowerBlockAddress(Op, DAG);
377 case ISD::SELECT_CC:
378 return LowerSELECT_CC(Op, DAG);
379 case ISD::SDIV:
380 case ISD::SREM:
381 return LowerSDIVSREM(Op, DAG);
382 case ISD::SHL_PARTS:
383 case ISD::SRL_PARTS:
384 case ISD::SRA_PARTS:
385 return LowerShiftParts(Op, DAG);
387 return LowerDYNAMIC_STACKALLOC(Op, DAG);
388 case ISD::ATOMIC_LOAD:
390 return LowerATOMIC_LOAD_STORE(Op, DAG);
392 return LowerATOMIC_FENCE(Op, DAG);
393 case ISD::TRAP:
394 return LowerTRAP(Op, DAG);
395 }
396}
397
398// Calling Convention Implementation
399#define GET_CALLING_CONV_IMPL
400#include "BPFGenCallingConv.inc"
401
402// Apply AssertSext/AssertZext and truncate based on VA's LocInfo.
404 const CCValAssign &VA, EVT RegVT,
405 SDValue ArgValue) {
406 if (VA.getLocInfo() == CCValAssign::SExt)
407 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
408 DAG.getValueType(VA.getValVT()));
409 else if (VA.getLocInfo() == CCValAssign::ZExt)
410 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
411 DAG.getValueType(VA.getValVT()));
412 if (VA.getLocInfo() != CCValAssign::Full)
413 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
414 return ArgValue;
415}
416
417SDValue BPFTargetLowering::LowerFormalArguments(
418 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
419 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
420 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
421 switch (CallConv) {
422 default:
423 report_fatal_error("unimplemented calling convention: " + Twine(CallConv));
424 case CallingConv::C:
426 break;
427 }
428
430 MachineRegisterInfo &RegInfo = MF.getRegInfo();
431
432 // Assign locations to all of the incoming arguments.
434 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
435 CCInfo.AnalyzeFormalArguments(Ins, getHasAlu32() ? CC_BPF32 : CC_BPF64);
436
437 for (size_t I = 0; I < ArgLocs.size(); ++I) {
438 auto &VA = ArgLocs[I];
439 EVT RegVT = VA.getLocVT();
440
441 if (VA.isRegLoc()) {
442 // Arguments passed in registers
443 MVT::SimpleValueType SimpleTy = RegVT.getSimpleVT().SimpleTy;
444 switch (SimpleTy) {
445 default: {
446 std::string Str;
447 {
448 raw_string_ostream OS(Str);
449 RegVT.print(OS);
450 }
451 report_fatal_error("unhandled argument type: " + Twine(Str));
452 }
453 case MVT::i32:
454 case MVT::i64:
455 Register VReg = RegInfo.createVirtualRegister(
456 SimpleTy == MVT::i64 ? &BPF::GPRRegClass : &BPF::GPR32RegClass);
457 RegInfo.addLiveIn(VA.getLocReg(), VReg);
458 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
459 InVals.push_back(convertLocValType(DAG, DL, VA, RegVT, ArgValue));
460 break;
461 }
462 continue;
463 }
464
465 if (VA.isMemLoc()) {
466 // For example, two stack arguments,
467 // arg1: Off = 8
468 // arg2: off = 16
469 int Off = VA.getLocMemOffset() + 8;
470 if (Off > INT16_MAX) {
471 fail(DL, DAG, "extra parameter stack depth exceeded limit");
472 break;
473 }
474
475 // Physical extra argument slot is always 64-bit.
476 SDValue StackVal = DAG.getNode(BPFISD::LOAD_STACK_ARG, DL,
477 DAG.getVTList(MVT::i64, MVT::Other), Chain,
478 DAG.getConstant(Off, DL, MVT::i64));
479 SDValue ArgValue = StackVal.getValue(0);
480 Chain = StackVal.getValue(1);
481 InVals.push_back(convertLocValType(DAG, DL, VA, MVT::i64, ArgValue));
482 continue;
483 }
484 }
485
486 if (IsVarArg)
487 fail(DL, DAG, "variadic functions are not supported");
488 return Chain;
489}
490
491static void resetRegMaskBit(const TargetRegisterInfo *TRI, uint32_t *RegMask,
492 MCRegister Reg) {
493 for (MCPhysReg SubReg : TRI->subregs_inclusive(Reg))
494 RegMask[SubReg / 32] &= ~(1u << (SubReg % 32));
495}
496
498 MachineFunction &MF,
499 const uint32_t *BaseRegMask) {
500 uint32_t *RegMask = MF.allocateRegMask();
501 unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
502 memcpy(RegMask, BaseRegMask, sizeof(RegMask[0]) * RegMaskSize);
503 return RegMask;
504}
505
506SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
507 SmallVectorImpl<SDValue> &InVals) const {
508 SelectionDAG &DAG = CLI.DAG;
509 auto &Outs = CLI.Outs;
510 auto &OutVals = CLI.OutVals;
511 auto &Ins = CLI.Ins;
512 SDValue Chain = CLI.Chain;
513 SDValue Callee = CLI.Callee;
514 bool &IsTailCall = CLI.IsTailCall;
515 CallingConv::ID CallConv = CLI.CallConv;
516 bool IsVarArg = CLI.IsVarArg;
518
519 // BPF target does not support tail call optimization.
520 IsTailCall = false;
521
522 switch (CallConv) {
523 default:
524 report_fatal_error("unsupported calling convention: " + Twine(CallConv));
526 case CallingConv::C:
527 break;
528 }
529
530 // Analyze operands of the call, assigning locations to each operand.
532 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
533
534 CCInfo.AnalyzeCallOperands(Outs, getHasAlu32() ? CC_BPF32 : CC_BPF64);
535
536 unsigned NumBytes = CCInfo.getStackSize();
537
538 for (auto &Arg : Outs) {
539 ISD::ArgFlagsTy Flags = Arg.Flags;
540 if (!Flags.isByVal())
541 continue;
542 fail(CLI.DL, DAG, "pass by value not supported", Callee);
543 break;
544 }
545
546 auto PtrVT = getPointerTy(MF.getDataLayout());
547 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
548
550
551 // Walk arg assignments
552 for (size_t i = 0; i < OutVals.size(); ++i) {
553 CCValAssign &VA = ArgLocs[i];
554 SDValue &Arg = OutVals[i];
555
556 // Promote the value if needed.
557 switch (VA.getLocInfo()) {
558 default:
559 report_fatal_error("unhandled location info: " + Twine(VA.getLocInfo()));
561 break;
563 Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg);
564 break;
566 Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg);
567 break;
569 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg);
570 break;
571 }
572
573 // Push arguments into RegsToPass vector
574 if (VA.isRegLoc()) {
575 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
576 continue;
577 }
578
579 if (VA.isMemLoc()) {
580 int Off = -8 - VA.getLocMemOffset();
581 if (Off < INT16_MIN) {
582 fail(CLI.DL, DAG, "extra parameter stack depth exceeded limit");
583 break;
584 }
585
586 // STORE_STACK_ARG requires i64 operands. With ALU32 mode, the CC
587 // promotion may only extend to i32, so extend to i64 if needed.
588 if (Arg.getValueType() != MVT::i64)
589 Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, MVT::i64, Arg);
590
591 SDValue OffVal = DAG.getConstant(Off, CLI.DL, MVT::i64);
592 Chain = DAG.getNode(BPFISD::STORE_STACK_ARG, CLI.DL, MVT::Other, Chain,
593 OffVal, Arg);
594 continue;
595 }
596
597 report_fatal_error("unhandled argument location");
598 }
599
600 SDValue InGlue;
601
602 // Build a sequence of copy-to-reg nodes chained together with token chain and
603 // flag operands which copy the outgoing args into registers. The InGlue in
604 // necessary since all emitted instructions must be stuck together.
605 for (auto &Reg : RegsToPass) {
606 Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InGlue);
607 InGlue = Chain.getValue(1);
608 }
609
610 // If the callee is a GlobalAddress node (quite common, every direct call is)
611 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
612 // Likewise ExternalSymbol -> TargetExternalSymbol.
613 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
614 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
615 G->getOffset(), 0);
616 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
617 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
618 StringRef Sym = E->getSymbol();
619 if (!BPFAllowsLibcalls && Sym != BPF_TRAP && Sym != "__multi3" &&
620 Sym != "__divti3" && Sym != "__modti3" && Sym != "__udivti3" &&
621 Sym != "__umodti3" && Sym != "memcpy" && Sym != "memset" &&
622 Sym != "memmove")
623 fail(
624 CLI.DL, DAG,
625 Twine("A call to built-in function '" + Sym + "' is not supported."));
626 }
627
628 // Returns a chain & a flag for retval copy to use.
629 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
631 Ops.push_back(Chain);
632 Ops.push_back(Callee);
633
634 // Add argument registers to the end of the list so that they are
635 // known live into the call.
636 for (auto &Reg : RegsToPass)
637 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
638
639 bool HasFastCall =
640 (CLI.CB && isa<CallInst>(CLI.CB) && CLI.CB->hasFnAttr("bpf_fastcall"));
641 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
642 if (HasFastCall) {
643 uint32_t *RegMask = regMaskFromTemplate(
644 TRI, MF, TRI->getCallPreservedMask(MF, CallingConv::PreserveAll));
645 for (auto const &RegPair : RegsToPass)
646 resetRegMaskBit(TRI, RegMask, RegPair.first);
647 if (!CLI.CB->getType()->isVoidTy())
648 resetRegMaskBit(TRI, RegMask, BPF::R0);
649 Ops.push_back(DAG.getRegisterMask(RegMask));
650 } else {
651 Ops.push_back(
652 DAG.getRegisterMask(TRI->getCallPreservedMask(MF, CLI.CallConv)));
653 }
654
655 if (InGlue.getNode())
656 Ops.push_back(InGlue);
657
658 Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
659 InGlue = Chain.getValue(1);
660
661 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
662
663 // Create the CALLSEQ_END node.
664 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, CLI.DL);
665 InGlue = Chain.getValue(1);
666
667 // Handle result values, copying them out of physregs into vregs that we
668 // return.
669 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, CLI.DL, DAG,
670 InVals);
671}
672
674BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
675 bool IsVarArg,
677 const SmallVectorImpl<SDValue> &OutVals,
678 const SDLoc &DL, SelectionDAG &DAG) const {
679 unsigned Opc = BPFISD::RET_GLUE;
680
681 // CCValAssign - represent the assignment of the return value to a location
684
685 // CCState - Info about the registers and stack slot.
686 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
687
688 // Analize return values.
689 CCInfo.AnalyzeReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
690
691 SDValue Glue;
692 SmallVector<SDValue, 4> RetOps(1, Chain);
693
694 // Copy the result values into the output registers.
695 for (size_t i = 0; i != RVLocs.size(); ++i) {
696 CCValAssign &VA = RVLocs[i];
697 if (!VA.isRegLoc())
698 report_fatal_error("stack return values are not supported");
699
700 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
701
702 // Guarantee that all emitted copies are stuck together,
703 // avoiding something bad.
704 Glue = Chain.getValue(1);
705 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
706 }
707
708 RetOps[0] = Chain; // Update chain.
709
710 // Add the glue if we have it.
711 if (Glue.getNode())
712 RetOps.push_back(Glue);
713
714 return DAG.getNode(Opc, DL, MVT::Other, RetOps);
715}
716
717SDValue BPFTargetLowering::LowerCallResult(
718 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
719 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
720 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
721
723 // Assign locations to each value returned by this call.
725 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
726
727 CCInfo.AnalyzeCallResult(Ins, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
728
729 // Copy all of the result registers out of their specified physreg.
730 for (auto &Val : RVLocs) {
731 Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(),
732 Val.getValVT(), InGlue).getValue(1);
733 InGlue = Chain.getValue(2);
734 InVals.push_back(Chain.getValue(0));
735 }
736
737 return Chain;
738}
739
741 switch (CC) {
742 default:
743 break;
744 case ISD::SETULT:
745 case ISD::SETULE:
746 case ISD::SETLT:
747 case ISD::SETLE:
749 std::swap(LHS, RHS);
750 break;
751 }
752}
753
754SDValue BPFTargetLowering::LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const {
755 SDLoc DL(Op);
756 fail(DL, DAG,
757 "unsupported signed division, please convert to unsigned div/mod.");
758 return DAG.getUNDEF(Op->getValueType(0));
759}
760
761SDValue BPFTargetLowering::LowerShiftParts(SDValue Op,
762 SelectionDAG &DAG) const {
763 SDValue Lo, Hi;
764 expandShiftParts(Op.getNode(), Lo, Hi, DAG);
765 return DAG.getMergeValues({Lo, Hi}, SDLoc(Op));
766}
767
768SDValue BPFTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
769 SelectionDAG &DAG) const {
770 SDLoc DL(Op);
771 fail(DL, DAG, "unsupported dynamic stack allocation");
772 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
773 return DAG.getMergeValues(Ops, SDLoc());
774}
775
776SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
777 SDValue Chain = Op.getOperand(0);
778 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
779 SDValue LHS = Op.getOperand(2);
780 SDValue RHS = Op.getOperand(3);
781 SDValue Dest = Op.getOperand(4);
782 SDLoc DL(Op);
783
784 if (!getHasJmpExt())
785 NegateCC(LHS, RHS, CC);
786
787 return DAG.getNode(BPFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
788 DAG.getConstant(CC, DL, LHS.getValueType()), Dest);
789}
790
791SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
792 SDValue LHS = Op.getOperand(0);
793 SDValue RHS = Op.getOperand(1);
794 SDValue TrueV = Op.getOperand(2);
795 SDValue FalseV = Op.getOperand(3);
796 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
797 SDLoc DL(Op);
798
799 if (!getHasJmpExt())
800 NegateCC(LHS, RHS, CC);
801
802 SDValue TargetCC = DAG.getConstant(CC, DL, LHS.getValueType());
803 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
804
805 return DAG.getNode(BPFISD::SELECT_CC, DL, Op.getValueType(), Ops);
806}
807
808SDValue BPFTargetLowering::LowerATOMIC_LOAD_STORE(SDValue Op,
809 SelectionDAG &DAG) const {
810 SDNode *N = Op.getNode();
811 SDLoc DL(N);
812
813 // A seq_cst store is xchg by now, see shouldExpandAtomicStoreInIR(), which
814 // makes load acquire enough for a seq_cst load.
815 if (cast<AtomicSDNode>(N)->getMergedOrdering() ==
817 (N->getOpcode() == ISD::ATOMIC_STORE || !HasLoadAcqStoreRel))
818 fail(DL, DAG,
819 "sequentially consistent (seq_cst) "
820 "atomic load/store is not supported");
821
822 return Op;
823}
824
827 if (!HasLoadAcqStoreRel)
829
830 switch (AI->getOperation()) {
837 // There are insns for 32 and 64 bits.
838 if (AI->getDataLayout().getTypeSizeInBits(AI->getType()) >= 32)
840 [[fallthrough]];
841 default:
843 }
844}
845
848 // Store release is not ordered with a later load. xchg is fully ordered.
849 if (HasLoadAcqStoreRel &&
853}
854
855SDValue BPFTargetLowering::LowerATOMIC_FENCE(SDValue Op,
856 SelectionDAG &DAG) const {
857 SDLoc DL(Op);
858 SyncScope::ID FenceSSID =
859 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
860
861 if (FenceSSID == SyncScope::SingleThread)
862 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
863 return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
864
865 // There is no insn for that. An atomic insn that returns the old value is
866 // fully ordered: add zero to a slot in the stack. Without alu32 that is
867 // 'lock *(u64 *)(r10 - 8) += r1', which is not ordered.
868 if (!HasAlu32)
869 report_fatal_error("Runtime fence is not supported at the moment");
870
872 SDValue Slot = DAG.CreateStackTemporary(MVT::i64);
874 MF, cast<FrameIndexSDNode>(Slot)->getIndex());
875 SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
876 SDValue Chain = DAG.getStore(Op.getOperand(0), DL, Zero, Slot, PtrInfo);
881 return DAG
882 .getAtomic(ISD::ATOMIC_LOAD_ADD, DL, MVT::i64, Chain, Slot, Zero, MMO)
883 .getValue(1);
884}
885
887 if (auto *Fn = M->getFunction(BPF_TRAP))
888 return Fn;
889
890 FunctionType *FT = FunctionType::get(Type::getVoidTy(M->getContext()), false);
891 Function *NewF =
893 NewF->setDSOLocal(true);
895 NewF->setSection(".ksyms");
896
897 if (M->debug_compile_units().empty())
898 return NewF;
899
900 DIBuilder DBuilder(*M);
901 DITypeArray ParamTypes =
902 DBuilder.getOrCreateTypeArray({nullptr /*void return*/});
903 DISubroutineType *FuncType = DBuilder.createSubroutineType(ParamTypes);
904 DICompileUnit *CU = *M->debug_compile_units_begin();
905 DISubprogram *SP =
906 DBuilder.createFunction(CU, BPF_TRAP, BPF_TRAP, nullptr, 0, FuncType, 0,
907 DINode::FlagZero, DISubprogram::SPFlagZero);
908 NewF->setSubprogram(SP);
909 return NewF;
910}
911
912SDValue BPFTargetLowering::LowerTRAP(SDValue Op, SelectionDAG &DAG) const {
914 TargetLowering::CallLoweringInfo CLI(DAG);
916 SDNode *N = Op.getNode();
917 SDLoc DL(N);
918
920 auto PtrVT = getPointerTy(MF.getDataLayout());
921 CLI.Callee = DAG.getTargetGlobalAddress(Fn, DL, PtrVT);
922 CLI.Chain = N->getOperand(0);
923 CLI.IsTailCall = false;
925 CLI.IsVarArg = false;
926 CLI.DL = std::move(DL);
927 CLI.NoMerge = false;
928 CLI.DoesNotReturn = true;
929 return LowerCall(CLI, InVals);
930}
931
932/// The verifier wants to see that the load from the table is within it. The
933/// range check in front of it doesn't always show that: it can be done on
934/// another copy of the value, e.g. 'w1 = w7; w1 &= 255; if w1 > 24 goto' and
935/// then 'r1 = r7; r1 &= 255' for the index. Make the size of the table a power
936/// of two and mask the index.
937SDValue BPFTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
938 SDLoc DL(Op);
939 SDValue Chain = Op.getOperand(0);
940 unsigned JTI = cast<JumpTableSDNode>(Op.getOperand(1))->getIndex();
941 SDValue Index = Op.getOperand(2);
943 MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
944 std::vector<MachineBasicBlock *> MBBs = MJTI->getJumpTables()[JTI].MBBs;
945 uint64_t Size = PowerOf2Ceil(MBBs.size());
946
947 if (Size != MBBs.size()) {
948 // An index that gets there is out of range: any block of the table will do.
949 MBBs.resize(Size, MBBs.back());
950 MJTI->RemoveJumpTable(JTI);
951 JTI = MJTI->createJumpTableIndex(MBBs);
952 }
953
954 Index = DAG.getNode(ISD::AND, DL, MVT::i64, Index,
955 DAG.getConstant(Size - 1, DL, MVT::i64));
956 Index = DAG.getNode(ISD::SHL, DL, MVT::i64, Index,
957 DAG.getConstant(3, DL, MVT::i64));
958 SDValue Addr = DAG.getNode(ISD::ADD, DL, MVT::i64,
959 DAG.getJumpTable(JTI, MVT::i64), Index);
960 SDValue Load = DAG.getLoad(MVT::i64, DL, Chain, Addr,
962 return DAG.getNode(ISD::BRIND, DL, MVT::Other, Load.getValue(1), Load);
963}
964
965SDValue BPFTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
966 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
967 return getAddr(N, DAG);
968}
969
971 SelectionDAG &DAG, unsigned Flags) {
972 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
973 N->getOffset(), Flags);
974}
975
977 SelectionDAG &DAG, unsigned Flags) {
978 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
979}
980
981template <class NodeTy>
982SDValue BPFTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
983 unsigned Flags) const {
984 SDLoc DL(N);
985
986 SDValue GA = getTargetNode(N, DL, MVT::i64, DAG, Flags);
987
988 return DAG.getNode(BPFISD::Wrapper, DL, MVT::i64, GA);
989}
990
991SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
992 SelectionDAG &DAG) const {
993 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
994 if (N->getOffset() != 0)
995 report_fatal_error("invalid offset for global address: " +
996 Twine(N->getOffset()));
997
998 const GlobalValue *GVal = N->getGlobal();
999 SDLoc DL(Op);
1000
1001 // Wrap it in a TargetGlobalAddress
1002 SDValue Addr = DAG.getTargetGlobalAddress(GVal, DL, MVT::i64);
1003
1004 // Emit pseudo instruction
1005 return SDValue(DAG.getMachineNode(BPF::LDIMM64, DL, MVT::i64, Addr), 0);
1006}
1007
1008SDValue BPFTargetLowering::LowerConstantPool(SDValue Op,
1009 SelectionDAG &DAG) const {
1010 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1011
1012 return getAddr(N, DAG);
1013}
1014
1015SDValue BPFTargetLowering::LowerBlockAddress(SDValue Op,
1016 SelectionDAG &DAG) const {
1017 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1018 SDLoc DL(Op);
1019
1020 // Wrap it in a TargetBlockAddress
1021 SDValue Addr = DAG.getTargetBlockAddress(BA, MVT::i64);
1022
1023 // Emit pseudo instruction
1024 return SDValue(DAG.getMachineNode(BPF::LDIMM64, DL, MVT::i64, Addr), 0);
1025}
1026
1027unsigned
1028BPFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
1029 unsigned Reg, bool isSigned) const {
1030 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
1031 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
1032 int RShiftOp = isSigned ? BPF::SRA_ri : BPF::SRL_ri;
1033 MachineFunction *F = BB->getParent();
1034 DebugLoc DL = MI.getDebugLoc();
1035
1036 MachineRegisterInfo &RegInfo = F->getRegInfo();
1037
1038 if (!isSigned) {
1039 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
1040 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
1041 return PromotedReg0;
1042 }
1043 Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
1044 Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
1045 Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
1046 if (HasMovsx) {
1047 BuildMI(BB, DL, TII.get(BPF::MOVSX_rr_32), PromotedReg0).addReg(Reg);
1048 } else {
1049 BuildMI(BB, DL, TII.get(BPF::MOV_32_64), PromotedReg0).addReg(Reg);
1050 BuildMI(BB, DL, TII.get(BPF::SLL_ri), PromotedReg1)
1051 .addReg(PromotedReg0).addImm(32);
1052 BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
1053 .addReg(PromotedReg1).addImm(32);
1054 }
1055
1056 return PromotedReg2;
1057}
1058
1060BPFTargetLowering::EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
1062 const {
1063 MachineFunction *MF = MI.getParent()->getParent();
1064 MachineRegisterInfo &MRI = MF->getRegInfo();
1065 MachineInstrBuilder MIB(*MF, MI);
1066 unsigned ScratchReg;
1067
1068 // This function does custom insertion during lowering BPFISD::MEMCPY which
1069 // only has two register operands from memcpy semantics, the copy source
1070 // address and the copy destination address.
1071 //
1072 // Because we will expand BPFISD::MEMCPY into load/store pairs, we will need
1073 // a third scratch register to serve as the destination register of load and
1074 // source register of store.
1075 //
1076 // The scratch register here is with the Define | Dead | EarlyClobber flags.
1077 // The EarlyClobber flag has the semantic property that the operand it is
1078 // attached to is clobbered before the rest of the inputs are read. Hence it
1079 // must be unique among the operands to the instruction. The Define flag is
1080 // needed to coerce the machine verifier that an Undef value isn't a problem
1081 // as we anyway is loading memory into it. The Dead flag is needed as the
1082 // value in scratch isn't supposed to be used by any other instruction.
1083 ScratchReg = MRI.createVirtualRegister(&BPF::GPRRegClass);
1084 MIB.addReg(ScratchReg,
1086
1087 return BB;
1088}
1089
1090MachineBasicBlock *BPFTargetLowering::EmitInstrWithCustomInserterLDimm64(
1091 MachineInstr &MI, MachineBasicBlock *BB) const {
1092 MachineFunction *MF = BB->getParent();
1093 const BPFInstrInfo *TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
1094 const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
1095 MachineRegisterInfo &RegInfo = MF->getRegInfo();
1096 DebugLoc DL = MI.getDebugLoc();
1097
1098 // Build address taken map for Global Varaibles and BlockAddresses
1099 DenseMap<const BasicBlock *, MachineBasicBlock *> AddressTakenBBs;
1100 for (MachineBasicBlock &MBB : *MF) {
1101 if (const BasicBlock *BB = MBB.getBasicBlock())
1102 if (BB->hasAddressTaken())
1103 AddressTakenBBs[BB] = &MBB;
1104 }
1105
1106 MachineOperand &MO = MI.getOperand(1);
1107 assert(MO.isBlockAddress() || MO.isGlobal());
1108
1109 Register ResultReg = MI.getOperand(0).getReg();
1110 Register TmpReg = RegInfo.createVirtualRegister(RC);
1111
1112 std::vector<MachineBasicBlock *> Targets;
1113 unsigned JTI;
1114
1115 if (MO.isBlockAddress()) {
1116 auto *BA = MO.getBlockAddress();
1117 MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock()];
1118 assert(TgtMBB);
1119
1120 Targets.push_back(TgtMBB);
1121 JTI = MF->getOrCreateJumpTableInfo(getJumpTableEncoding())
1122 ->createJumpTableIndex(Targets);
1123
1124 BuildMI(*BB, MI, DL, TII->get(BPF::LD_imm64), TmpReg)
1125 .addJumpTableIndex(JTI);
1126 BuildMI(*BB, MI, DL, TII->get(BPF::LDD), ResultReg)
1127 .addReg(TmpReg)
1128 .addImm(0);
1129 MI.eraseFromParent();
1130 return BB;
1131 }
1132
1133 // Helper: emit LD_imm64 with operand GlobalAddress or JumpTable
1134 auto emitLDImm64 = [&](const GlobalValue *GV = nullptr, unsigned JTI = -1) {
1135 auto MIB = BuildMI(*BB, MI, DL, TII->get(BPF::LD_imm64), ResultReg);
1136 if (GV)
1137 MIB.addGlobalAddress(GV);
1138 else
1139 MIB.addJumpTableIndex(JTI);
1140 MI.eraseFromParent();
1141 return BB;
1142 };
1143
1144 // Must be a global at this point
1145 const GlobalValue *GVal = MO.getGlobal();
1146 const auto *GV = dyn_cast<GlobalVariable>(GVal);
1147
1148 if (!GV || GV->getLinkage() != GlobalValue::PrivateLinkage ||
1149 !GV->isConstant() || !GV->hasInitializer())
1150 return emitLDImm64(GVal);
1151
1152 const auto *CA = dyn_cast<ConstantArray>(GV->getInitializer());
1153 if (!CA)
1154 return emitLDImm64(GVal);
1155
1156 for (const Use &Op : CA->operands()) {
1157 if (!isa<BlockAddress>(Op))
1158 return emitLDImm64(GVal);
1159 auto *BA = cast<BlockAddress>(Op);
1160 MachineBasicBlock *TgtMBB = AddressTakenBBs[BA->getBasicBlock()];
1161 assert(TgtMBB);
1162 Targets.push_back(TgtMBB);
1163 }
1164
1165 JTI = MF->getOrCreateJumpTableInfo(getJumpTableEncoding())
1166 ->createJumpTableIndex(Targets);
1167 return emitLDImm64(nullptr, JTI);
1168}
1169
1172 MachineBasicBlock *BB) const {
1174 DebugLoc DL = MI.getDebugLoc();
1175 unsigned Opc = MI.getOpcode();
1176 bool isSelectRROp = (Opc == BPF::Select ||
1177 Opc == BPF::Select_64_32 ||
1178 Opc == BPF::Select_32 ||
1179 Opc == BPF::Select_32_64);
1180
1181 bool isMemcpyOp = Opc == BPF::MEMCPY;
1182 bool isLDimm64Op = Opc == BPF::LDIMM64;
1183
1184#ifndef NDEBUG
1185 bool isSelectRIOp = (Opc == BPF::Select_Ri ||
1186 Opc == BPF::Select_Ri_64_32 ||
1187 Opc == BPF::Select_Ri_32 ||
1188 Opc == BPF::Select_Ri_32_64);
1189
1190 if (!(isSelectRROp || isSelectRIOp || isMemcpyOp || isLDimm64Op))
1191 report_fatal_error("unhandled instruction type: " + Twine(Opc));
1192#endif
1193
1194 if (isMemcpyOp)
1195 return EmitInstrWithCustomInserterMemcpy(MI, BB);
1196
1197 if (isLDimm64Op)
1198 return EmitInstrWithCustomInserterLDimm64(MI, BB);
1199
1200 bool is32BitCmp = (Opc == BPF::Select_32 ||
1201 Opc == BPF::Select_32_64 ||
1202 Opc == BPF::Select_Ri_32 ||
1203 Opc == BPF::Select_Ri_32_64);
1204
1205 // To "insert" a SELECT instruction, we actually have to insert the diamond
1206 // control-flow pattern. The incoming instruction knows the destination vreg
1207 // to set, the condition code register to branch on, the true/false values to
1208 // select between, and a branch opcode to use.
1209 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1211
1212 // ThisMBB:
1213 // ...
1214 // TrueVal = ...
1215 // jmp_XX r1, r2 goto Copy1MBB
1216 // fallthrough --> Copy0MBB
1217 MachineBasicBlock *ThisMBB = BB;
1218 MachineFunction *F = BB->getParent();
1219 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1220 MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1221
1222 F->insert(I, Copy0MBB);
1223 F->insert(I, Copy1MBB);
1224
1225 // Set the call frame size on entry to the new basic blocks.
1226 unsigned CallFrameSize = TII.getCallFrameSizeAt(MI);
1227 Copy0MBB->setCallFrameSize(CallFrameSize);
1228 Copy1MBB->setCallFrameSize(CallFrameSize);
1229
1230 // Update machine-CFG edges by transferring all successors of the current
1231 // block to the new block which will contain the Phi node for the select.
1232 Copy1MBB->splice(Copy1MBB->begin(), BB,
1233 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1234 Copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1235 // Next, add the true and fallthrough blocks as its successors.
1236 BB->addSuccessor(Copy0MBB);
1237 BB->addSuccessor(Copy1MBB);
1238
1239 // Insert Branch if Flag
1240 int CC = MI.getOperand(3).getImm();
1241 int NewCC;
1242 switch (CC) {
1243#define SET_NEWCC(X, Y) \
1244 case ISD::X: \
1245 if (is32BitCmp && HasJmp32) \
1246 NewCC = isSelectRROp ? BPF::Y##_rr_32 : BPF::Y##_ri_32; \
1247 else \
1248 NewCC = isSelectRROp ? BPF::Y##_rr : BPF::Y##_ri; \
1249 break
1250 SET_NEWCC(SETGT, JSGT);
1251 SET_NEWCC(SETUGT, JUGT);
1252 SET_NEWCC(SETGE, JSGE);
1253 SET_NEWCC(SETUGE, JUGE);
1254 SET_NEWCC(SETEQ, JEQ);
1255 SET_NEWCC(SETNE, JNE);
1256 SET_NEWCC(SETLT, JSLT);
1257 SET_NEWCC(SETULT, JULT);
1258 SET_NEWCC(SETLE, JSLE);
1259 SET_NEWCC(SETULE, JULE);
1260 default:
1261 report_fatal_error("unimplemented select CondCode " + Twine(CC));
1262 }
1263
1264 Register LHS = MI.getOperand(1).getReg();
1265 bool isSignedCmp = (CC == ISD::SETGT ||
1266 CC == ISD::SETGE ||
1267 CC == ISD::SETLT ||
1268 CC == ISD::SETLE);
1269
1270 // eBPF at the moment only has 64-bit comparison. Any 32-bit comparison need
1271 // to be promoted, however if the 32-bit comparison operands are destination
1272 // registers then they are implicitly zero-extended already, there is no
1273 // need of explicit zero-extend sequence for them.
1274 //
1275 // We simply do extension for all situations in this method, but we will
1276 // try to remove those unnecessary in BPFMIPeephole pass.
1277 if (is32BitCmp && !HasJmp32)
1278 LHS = EmitSubregExt(MI, BB, LHS, isSignedCmp);
1279
1280 if (isSelectRROp) {
1281 Register RHS = MI.getOperand(2).getReg();
1282
1283 if (is32BitCmp && !HasJmp32)
1284 RHS = EmitSubregExt(MI, BB, RHS, isSignedCmp);
1285
1286 BuildMI(BB, DL, TII.get(NewCC)).addReg(LHS).addReg(RHS).addMBB(Copy1MBB);
1287 } else {
1288 int64_t imm32 = MI.getOperand(2).getImm();
1289 // Check before we build J*_ri instruction.
1290 if (!isInt<32>(imm32))
1291 report_fatal_error("immediate overflows 32 bits: " + Twine(imm32));
1292 BuildMI(BB, DL, TII.get(NewCC))
1293 .addReg(LHS).addImm(imm32).addMBB(Copy1MBB);
1294 }
1295
1296 // Copy0MBB:
1297 // %FalseValue = ...
1298 // # fallthrough to Copy1MBB
1299 BB = Copy0MBB;
1300
1301 // Update machine-CFG edges
1302 BB->addSuccessor(Copy1MBB);
1303
1304 // Copy1MBB:
1305 // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
1306 // ...
1307 BB = Copy1MBB;
1308 BuildMI(*BB, BB->begin(), DL, TII.get(BPF::PHI), MI.getOperand(0).getReg())
1309 .addReg(MI.getOperand(5).getReg())
1310 .addMBB(Copy0MBB)
1311 .addReg(MI.getOperand(4).getReg())
1312 .addMBB(ThisMBB);
1313
1314 MI.eraseFromParent(); // The pseudo instruction is gone now.
1315 return BB;
1316}
1317
1319 EVT VT) const {
1320 return getHasAlu32() ? MVT::i32 : MVT::i64;
1321}
1322
1324 EVT VT) const {
1325 return (getHasAlu32() && VT == MVT::i32) ? MVT::i32 : MVT::i64;
1326}
1327
1328bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
1329 const AddrMode &AM, Type *Ty,
1330 unsigned AS,
1331 Instruction *I) const {
1332 // No global is ever allowed as a base.
1333 if (AM.BaseGV)
1334 return false;
1335
1336 switch (AM.Scale) {
1337 case 0: // "r+i" or just "i", depending on HasBaseReg.
1338 break;
1339 case 1:
1340 if (!AM.HasBaseReg) // allow "r+i".
1341 break;
1342 return false; // disallow "r+r" or "r+r+i".
1343 default:
1344 return false;
1345 }
1346
1347 return true;
1348}
1349
1350bool BPFTargetLowering::CanLowerReturn(
1351 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
1353 const Type *RetTy) const {
1355 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
1356 return CCInfo.CheckReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
1357}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static uint32_t * regMaskFromTemplate(const TargetRegisterInfo *TRI, MachineFunction &MF, const uint32_t *BaseRegMask)
static Function * createBPFUnreachable(Module *M)
static cl::opt< bool > BPFAllowsLibcalls("bpf-allows-libcalls", cl::Hidden, cl::init(false), cl::desc("Allow libcalls instead of rejecting unsupported built-in " "functions"))
static SDValue getTargetNode(ConstantPoolSDNode *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flags)
static cl::opt< bool > BPFExpandMemcpyInOrder("bpf-expand-memcpy-in-order", cl::Hidden, cl::init(false), cl::desc("Expand memcpy into load/store pairs in order"))
static SDValue convertLocValType(SelectionDAG &DAG, const SDLoc &DL, const CCValAssign &VA, EVT RegVT, SDValue ArgValue)
static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, SDValue Val={})
static cl::opt< unsigned > BPFMinimumJumpTableEntries("bpf-min-jump-table-entries", cl::init(13), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on BPF"))
static void resetRegMaskBit(const TargetRegisterInfo *TRI, uint32_t *RegMask, MCRegister Reg)
static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC)
#define SET_NEWCC(X, Y)
#define BPF_TRAP
Definition BPF.h:29
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isSigned(unsigned Opcode)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
const char * Msg
Value * RHS
Value * LHS
an instruction that atomically reads a memory location, combines it with another value,...
@ Add
*p = old + v
@ Sub
*p = old - v
@ And
*p = old & v
@ Xor
*p = old ^ v
BinOp getOperation() const
unsigned getCommonMaxStoresPerMemFunc() const
bool hasHmul() const
bool hasLoadAcqStoreRel() const
bool hasSdivSmod() const
bool getAllowsMisalignedMemAccess() const
bool getHasJmpExt() const
const BPFSelectionDAGInfo * getSelectionDAGInfo() const override
bool hasLdsx() const
bool hasGotox() const
bool hasMovsx() const
bool getHasJmp32() const
const BPFRegisterInfo * getRegisterInfo() const override
bool getHasAlu32() const
BPFTargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *) const override
Determine if the target supports unaligned memory accesses.
AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be expanded by the IR-level AtomicExpand pass into.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI)
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...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
Return the type to use for a scalar shift opcode, given the shifted amount type.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
BasicBlock * getBasicBlock() const
Definition Constants.h:1125
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
LLVM_ABI DISubroutineType * createSubroutineType(DITypeArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
LLVM_ABI DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags=DINode::FlagZero, DISubprogram::DISPFlags SPFlags=DISubprogram::SPFlagZero, DITemplateParameterArray TParams=nullptr, DISubprogram *Decl=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName="", bool UseKeyInstructions=false)
Create a new descriptor for the specified subprogram.
LLVM_ABI DITypeArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeArray, create one if required.
Subprogram description. Uses SubclassData1.
Type array for a subprogram.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition DataLayout.h:791
A debug info location.
Definition DebugLoc.h:126
Diagnostic information for unsupported feature in backend.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
void setCallingConv(CallingConv::ID CC)
Definition Function.h:277
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
Definition Globals.cpp:348
LinkageTypes getLinkage() const
Module * getParent()
Get the module that this global value is contained inside of...
void setDSOLocal(bool Local)
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
uint32_t * allocateRegMask()
Allocate and initialize a register mask with NumRegister bits.
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.
BasicBlockListType::iterator iterator
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
void RemoveJumpTable(unsigned Idx)
RemoveJumpTable - Mark the specific index as being dead.
LLVM_ABI unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
const std::vector< MachineJumpTableEntry > & getJumpTables() const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
const GlobalValue * getGlobal() const
const BlockAddress * getBlockAddress() const
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
const SDValue & getOperand(unsigned Num) const
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.
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getJumpTable(int JTI, EVT VT, bool isTarget=false, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
TargetInstrInfo - Interface to description of machine instruction set.
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...
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.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
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.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
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....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
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...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
void expandShiftParts(SDNode *N, SDValue &Lo, SDValue &Hi, SelectionDAG &DAG) const
Expand shift-by-parts.
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
self_iterator getIterator()
Definition ilist_node.h:123
A raw_ostream that writes to an std::string.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ 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
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:845
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ GlobalAddress
Definition ISDOpcodes.h:90
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:814
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TRAP
TRAP - Trapping instruction.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:813
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:859
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:63
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:66
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Dead
Unused definition.
@ EarlyClobber
Register definition happens before uses.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1167
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:380
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
@ Fast
Assign the register banks as fast as possible (default).
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
LLVM_ABI void print(raw_ostream &OS) const
Implement operator<<.
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
LLVM IR metadata carried by a MachineMemOperand.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs