LLVM  13.0.0git
InlineAsmLowering.cpp
Go to the documentation of this file.
1 //===-- lib/CodeGen/GlobalISel/InlineAsmLowering.cpp ----------------------===//
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 /// \file
10 /// This file implements the lowering from LLVM IR inline asm to MIR INLINEASM
11 ///
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/CodeGen/Analysis.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 
26 #define DEBUG_TYPE "inline-asm-lowering"
27 
28 using namespace llvm;
29 
30 void InlineAsmLowering::anchor() {}
31 
32 namespace {
33 
34 /// GISelAsmOperandInfo - This contains information for each constraint that we
35 /// are lowering.
36 class GISelAsmOperandInfo : public TargetLowering::AsmOperandInfo {
37 public:
38  /// Regs - If this is a register or register class operand, this
39  /// contains the set of assigned registers corresponding to the operand.
41 
42  explicit GISelAsmOperandInfo(const TargetLowering::AsmOperandInfo &Info)
43  : TargetLowering::AsmOperandInfo(Info) {}
44 };
45 
46 using GISelAsmOperandInfoVector = SmallVector<GISelAsmOperandInfo, 16>;
47 
48 class ExtraFlags {
49  unsigned Flags = 0;
50 
51 public:
52  explicit ExtraFlags(const CallBase &CB) {
53  const InlineAsm *IA = cast<InlineAsm>(CB.getCalledOperand());
54  if (IA->hasSideEffects())
56  if (IA->isAlignStack())
58  if (CB.isConvergent())
60  Flags |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
61  }
62 
63  void update(const TargetLowering::AsmOperandInfo &OpInfo) {
64  // Ideally, we would only check against memory constraints. However, the
65  // meaning of an Other constraint can be target-specific and we can't easily
66  // reason about it. Therefore, be conservative and set MayLoad/MayStore
67  // for Other constraints as well.
70  if (OpInfo.Type == InlineAsm::isInput)
71  Flags |= InlineAsm::Extra_MayLoad;
72  else if (OpInfo.Type == InlineAsm::isOutput)
74  else if (OpInfo.Type == InlineAsm::isClobber)
76  }
77  }
78 
79  unsigned get() const { return Flags; }
80 };
81 
82 } // namespace
83 
84 /// Assign virtual/physical registers for the specified register operand.
86  MachineIRBuilder &MIRBuilder,
87  GISelAsmOperandInfo &OpInfo,
88  GISelAsmOperandInfo &RefOpInfo) {
89 
90  const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
92 
93  // No work to do for memory operations.
94  if (OpInfo.ConstraintType == TargetLowering::C_Memory)
95  return;
96 
97  // If this is a constraint for a single physreg, or a constraint for a
98  // register class, find it.
99  Register AssignedReg;
100  const TargetRegisterClass *RC;
101  std::tie(AssignedReg, RC) = TLI.getRegForInlineAsmConstraint(
102  &TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT);
103  // RC is unset only on failure. Return immediately.
104  if (!RC)
105  return;
106 
107  // No need to allocate a matching input constraint since the constraint it's
108  // matching to has already been allocated.
109  if (OpInfo.isMatchingInputConstraint())
110  return;
111 
112  // Initialize NumRegs.
113  unsigned NumRegs = 1;
114  if (OpInfo.ConstraintVT != MVT::Other)
115  NumRegs =
116  TLI.getNumRegisters(MF.getFunction().getContext(), OpInfo.ConstraintVT);
117 
118  // If this is a constraint for a specific physical register, but the type of
119  // the operand requires more than one register to be passed, we allocate the
120  // required amount of physical registers, starting from the selected physical
121  // register.
122  // For this, first retrieve a register iterator for the given register class
124  MachineRegisterInfo &RegInfo = MF.getRegInfo();
125 
126  // Advance the iterator to the assigned register (if set)
127  if (AssignedReg) {
128  for (; *I != AssignedReg; ++I)
129  assert(I != RC->end() && "AssignedReg should be a member of provided RC");
130  }
131 
132  // Finally, assign the registers. If the AssignedReg isn't set, create virtual
133  // registers with the provided register class
134  for (; NumRegs; --NumRegs, ++I) {
135  assert(I != RC->end() && "Ran out of registers to allocate!");
136  Register R = AssignedReg ? Register(*I) : RegInfo.createVirtualRegister(RC);
137  OpInfo.Regs.push_back(R);
138  }
139 }
140 
141 /// Return an integer indicating how general CT is.
143  switch (CT) {
147  return 0;
149  return 1;
151  return 2;
153  return 3;
154  }
155  llvm_unreachable("Invalid constraint type");
156 }
157 
159  const TargetLowering *TLI) {
160  assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options");
161  unsigned BestIdx = 0;
163  int BestGenerality = -1;
164 
165  // Loop over the options, keeping track of the most general one.
166  for (unsigned i = 0, e = OpInfo.Codes.size(); i != e; ++i) {
168  TLI->getConstraintType(OpInfo.Codes[i]);
169 
170  // Indirect 'other' or 'immediate' constraints are not allowed.
171  if (OpInfo.isIndirect && !(CType == TargetLowering::C_Memory ||
172  CType == TargetLowering::C_Register ||
174  continue;
175 
176  // If this is an 'other' or 'immediate' constraint, see if the operand is
177  // valid for it. For example, on X86 we might have an 'rI' constraint. If
178  // the operand is an integer in the range [0..31] we want to use I (saving a
179  // load of a register), otherwise we must use 'r'.
180  if (CType == TargetLowering::C_Other ||
181  CType == TargetLowering::C_Immediate) {
182  assert(OpInfo.Codes[i].size() == 1 &&
183  "Unhandled multi-letter 'other' constraint");
184  // FIXME: prefer immediate constraints if the target allows it
185  }
186 
187  // Things with matching constraints can only be registers, per gcc
188  // documentation. This mainly affects "g" constraints.
189  if (CType == TargetLowering::C_Memory && OpInfo.hasMatchingInput())
190  continue;
191 
192  // This constraint letter is more general than the previous one, use it.
193  int Generality = getConstraintGenerality(CType);
194  if (Generality > BestGenerality) {
195  BestType = CType;
196  BestIdx = i;
197  BestGenerality = Generality;
198  }
199  }
200 
201  OpInfo.ConstraintCode = OpInfo.Codes[BestIdx];
202  OpInfo.ConstraintType = BestType;
203 }
204 
205 static void computeConstraintToUse(const TargetLowering *TLI,
207  assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
208 
209  // Single-letter constraints ('r') are very common.
210  if (OpInfo.Codes.size() == 1) {
211  OpInfo.ConstraintCode = OpInfo.Codes[0];
212  OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
213  } else {
214  chooseConstraint(OpInfo, TLI);
215  }
216 
217  // 'X' matches anything.
218  if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) {
219  // Labels and constants are handled elsewhere ('X' is the only thing
220  // that matches labels). For Functions, the type here is the type of
221  // the result, which is not what we want to look at; leave them alone.
222  Value *Val = OpInfo.CallOperandVal;
223  if (isa<BasicBlock>(Val) || isa<ConstantInt>(Val) || isa<Function>(Val))
224  return;
225 
226  // Otherwise, try to resolve it to something we know about by looking at
227  // the actual operand type.
228  if (const char *Repl = TLI->LowerXConstraint(OpInfo.ConstraintVT)) {
229  OpInfo.ConstraintCode = Repl;
230  OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
231  }
232  }
233 }
234 
235 static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx) {
236  unsigned Flag = I.getOperand(OpIdx).getImm();
238 }
239 
240 static bool buildAnyextOrCopy(Register Dst, Register Src,
241  MachineIRBuilder &MIRBuilder) {
242  const TargetRegisterInfo *TRI =
243  MIRBuilder.getMF().getSubtarget().getRegisterInfo();
244  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
245 
246  auto SrcTy = MRI->getType(Src);
247  if (!SrcTy.isValid()) {
248  LLVM_DEBUG(dbgs() << "Source type for copy is not valid\n");
249  return false;
250  }
251  unsigned SrcSize = TRI->getRegSizeInBits(Src, *MRI);
252  unsigned DstSize = TRI->getRegSizeInBits(Dst, *MRI);
253 
254  if (DstSize < SrcSize) {
255  LLVM_DEBUG(dbgs() << "Input can't fit in destination reg class\n");
256  return false;
257  }
258 
259  // Attempt to anyext small scalar sources.
260  if (DstSize > SrcSize) {
261  if (!SrcTy.isScalar()) {
262  LLVM_DEBUG(dbgs() << "Can't extend non-scalar input to size of"
263  "destination register class\n");
264  return false;
265  }
266  Src = MIRBuilder.buildAnyExt(LLT::scalar(DstSize), Src).getReg(0);
267  }
268 
269  MIRBuilder.buildCopy(Dst, Src);
270  return true;
271 }
272 
274  MachineIRBuilder &MIRBuilder, const CallBase &Call,
275  std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
276  const {
277  const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
278 
279  /// ConstraintOperands - Information about all of the constraints.
280  GISelAsmOperandInfoVector ConstraintOperands;
281 
282  MachineFunction &MF = MIRBuilder.getMF();
283  const Function &F = MF.getFunction();
284  const DataLayout &DL = F.getParent()->getDataLayout();
286 
287  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
288 
289  TargetLowering::AsmOperandInfoVector TargetConstraints =
290  TLI->ParseConstraints(DL, TRI, Call);
291 
292  ExtraFlags ExtraInfo(Call);
293  unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
294  unsigned ResNo = 0; // ResNo - The result number of the next output.
295  for (auto &T : TargetConstraints) {
296  ConstraintOperands.push_back(GISelAsmOperandInfo(T));
297  GISelAsmOperandInfo &OpInfo = ConstraintOperands.back();
298 
299  // Compute the value type for each operand.
300  if (OpInfo.Type == InlineAsm::isInput ||
301  (OpInfo.Type == InlineAsm::isOutput && OpInfo.isIndirect)) {
302 
303  OpInfo.CallOperandVal = const_cast<Value *>(Call.getArgOperand(ArgNo++));
304 
305  if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
306  LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
307  return false;
308  }
309 
310  Type *OpTy = OpInfo.CallOperandVal->getType();
311 
312  // If this is an indirect operand, the operand is a pointer to the
313  // accessed type.
314  if (OpInfo.isIndirect) {
315  PointerType *PtrTy = dyn_cast<PointerType>(OpTy);
316  if (!PtrTy)
317  report_fatal_error("Indirect operand for inline asm not a pointer!");
318  OpTy = PtrTy->getElementType();
319  }
320 
321  // FIXME: Support aggregate input operands
322  if (!OpTy->isSingleValueType()) {
323  LLVM_DEBUG(
324  dbgs() << "Aggregate input operands are not supported yet\n");
325  return false;
326  }
327 
328  OpInfo.ConstraintVT = TLI->getValueType(DL, OpTy, true).getSimpleVT();
329 
330  } else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
331  assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
332  if (StructType *STy = dyn_cast<StructType>(Call.getType())) {
333  OpInfo.ConstraintVT =
334  TLI->getSimpleValueType(DL, STy->getElementType(ResNo));
335  } else {
336  assert(ResNo == 0 && "Asm only has one result!");
337  OpInfo.ConstraintVT = TLI->getSimpleValueType(DL, Call.getType());
338  }
339  ++ResNo;
340  } else {
341  OpInfo.ConstraintVT = MVT::Other;
342  }
343 
344  // Compute the constraint code and ConstraintType to use.
345  computeConstraintToUse(TLI, OpInfo);
346 
347  // The selected constraint type might expose new sideeffects
348  ExtraInfo.update(OpInfo);
349  }
350 
351  // At this point, all operand types are decided.
352  // Create the MachineInstr, but don't insert it yet since input
353  // operands still need to insert instructions before this one
354  auto Inst = MIRBuilder.buildInstrNoInsert(TargetOpcode::INLINEASM)
355  .addExternalSymbol(IA->getAsmString().c_str())
356  .addImm(ExtraInfo.get());
357 
358  // Starting from this operand: flag followed by register(s) will be added as
359  // operands to Inst for each constraint. Used for matching input constraints.
360  unsigned StartIdx = Inst->getNumOperands();
361 
362  // Collects the output operands for later processing
363  GISelAsmOperandInfoVector OutputOperands;
364 
365  for (auto &OpInfo : ConstraintOperands) {
366  GISelAsmOperandInfo &RefOpInfo =
368  ? ConstraintOperands[OpInfo.getMatchedOperand()]
369  : OpInfo;
370 
371  // Assign registers for register operands
372  getRegistersForValue(MF, MIRBuilder, OpInfo, RefOpInfo);
373 
374  switch (OpInfo.Type) {
375  case InlineAsm::isOutput:
377  unsigned ConstraintID =
379  assert(ConstraintID != InlineAsm::Constraint_Unknown &&
380  "Failed to convert memory constraint code to constraint id.");
381 
382  // Add information to the INLINEASM instruction to know about this
383  // output.
384  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
385  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
386  Inst.addImm(OpFlags);
387  ArrayRef<Register> SourceRegs =
388  GetOrCreateVRegs(*OpInfo.CallOperandVal);
389  assert(
390  SourceRegs.size() == 1 &&
391  "Expected the memory output to fit into a single virtual register");
392  Inst.addReg(SourceRegs[0]);
393  } else {
394  // Otherwise, this outputs to a register (directly for C_Register /
395  // C_RegisterClass. Find a register that we can use.
398 
399  if (OpInfo.Regs.empty()) {
400  LLVM_DEBUG(dbgs()
401  << "Couldn't allocate output register for constraint\n");
402  return false;
403  }
404 
405  // Add information to the INLINEASM instruction to know that this
406  // register is set.
407  unsigned Flag = InlineAsm::getFlagWord(
410  OpInfo.Regs.size());
411  if (OpInfo.Regs.front().isVirtual()) {
412  // Put the register class of the virtual registers in the flag word.
413  // That way, later passes can recompute register class constraints for
414  // inline assembly as well as normal instructions. Don't do this for
415  // tied operands that can use the regclass information from the def.
416  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
418  }
419 
420  Inst.addImm(Flag);
421 
422  for (Register Reg : OpInfo.Regs) {
423  Inst.addReg(Reg,
424  RegState::Define | getImplRegState(Reg.isPhysical()) |
425  (OpInfo.isEarlyClobber ? RegState::EarlyClobber : 0));
426  }
427 
428  // Remember this output operand for later processing
429  OutputOperands.push_back(OpInfo);
430  }
431 
432  break;
433  case InlineAsm::isInput: {
434  if (OpInfo.isMatchingInputConstraint()) {
435  unsigned DefIdx = OpInfo.getMatchedOperand();
436  // Find operand with register def that corresponds to DefIdx.
437  unsigned InstFlagIdx = StartIdx;
438  for (unsigned i = 0; i < DefIdx; ++i)
439  InstFlagIdx += getNumOpRegs(*Inst, InstFlagIdx) + 1;
440  assert(getNumOpRegs(*Inst, InstFlagIdx) == 1 && "Wrong flag");
441 
442  unsigned MatchedOperandFlag = Inst->getOperand(InstFlagIdx).getImm();
443  if (InlineAsm::isMemKind(MatchedOperandFlag)) {
444  LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
445  "supported. This should be target specific.\n");
446  return false;
447  }
448  if (!InlineAsm::isRegDefKind(MatchedOperandFlag) &&
449  !InlineAsm::isRegDefEarlyClobberKind(MatchedOperandFlag)) {
450  LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
451  return false;
452  }
453 
454  // We want to tie input to register in next operand.
455  unsigned DefRegIdx = InstFlagIdx + 1;
456  Register Def = Inst->getOperand(DefRegIdx).getReg();
457 
458  ArrayRef<Register> SrcRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
459  assert(SrcRegs.size() == 1 && "Single register is expected here");
460 
461  // When Def is physreg: use given input.
462  Register In = SrcRegs[0];
463  // When Def is vreg: copy input to new vreg with same reg class as Def.
464  if (Def.isVirtual()) {
466  if (!buildAnyextOrCopy(In, SrcRegs[0], MIRBuilder))
467  return false;
468  }
469 
470  // Add Flag and input register operand (In) to Inst. Tie In to Def.
471  unsigned UseFlag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, 1);
472  unsigned Flag = InlineAsm::getFlagWordForMatchingOp(UseFlag, DefIdx);
473  Inst.addImm(Flag);
474  Inst.addReg(In);
475  Inst->tieOperands(DefRegIdx, Inst->getNumOperands() - 1);
476  break;
477  }
478 
479  if (OpInfo.ConstraintType == TargetLowering::C_Other &&
480  OpInfo.isIndirect) {
481  LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
482  "not supported yet\n");
483  return false;
484  }
485 
488 
489  std::vector<MachineOperand> Ops;
491  OpInfo.ConstraintCode, Ops,
492  MIRBuilder)) {
493  LLVM_DEBUG(dbgs() << "Don't support constraint: "
494  << OpInfo.ConstraintCode << " yet\n");
495  return false;
496  }
497 
498  assert(Ops.size() > 0 &&
499  "Expected constraint to be lowered to at least one operand");
500 
501  // Add information to the INLINEASM node to know about this input.
502  unsigned OpFlags =
504  Inst.addImm(OpFlags);
505  Inst.add(Ops);
506  break;
507  }
508 
510 
511  if (!OpInfo.isIndirect) {
512  LLVM_DEBUG(dbgs()
513  << "Cannot indirectify memory input operands yet\n");
514  return false;
515  }
516 
517  assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
518 
519  unsigned ConstraintID =
521  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
522  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
523  Inst.addImm(OpFlags);
524  ArrayRef<Register> SourceRegs =
525  GetOrCreateVRegs(*OpInfo.CallOperandVal);
526  assert(
527  SourceRegs.size() == 1 &&
528  "Expected the memory input to fit into a single virtual register");
529  Inst.addReg(SourceRegs[0]);
530  break;
531  }
532 
535  "Unknown constraint type!");
536 
537  if (OpInfo.isIndirect) {
538  LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
539  "for constraint '"
540  << OpInfo.ConstraintCode << "'\n");
541  return false;
542  }
543 
544  // Copy the input into the appropriate registers.
545  if (OpInfo.Regs.empty()) {
546  LLVM_DEBUG(
547  dbgs()
548  << "Couldn't allocate input register for register constraint\n");
549  return false;
550  }
551 
552  unsigned NumRegs = OpInfo.Regs.size();
553  ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
554  assert(NumRegs == SourceRegs.size() &&
555  "Expected the number of input registers to match the number of "
556  "source registers");
557 
558  if (NumRegs > 1) {
559  LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
560  "not supported yet\n");
561  return false;
562  }
563 
565  if (OpInfo.Regs.front().isVirtual()) {
566  // Put the register class of the virtual registers in the flag word.
567  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
569  }
570  Inst.addImm(Flag);
571  if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
572  return false;
573  Inst.addReg(OpInfo.Regs[0]);
574  break;
575  }
576 
577  case InlineAsm::isClobber: {
578 
579  unsigned NumRegs = OpInfo.Regs.size();
580  if (NumRegs > 0) {
581  unsigned Flag =
583  Inst.addImm(Flag);
584 
585  for (Register Reg : OpInfo.Regs) {
587  getImplRegState(Reg.isPhysical()));
588  }
589  }
590  break;
591  }
592  }
593  }
594 
595  if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
596  Inst.addMetadata(SrcLoc);
597 
598  // All inputs are handled, insert the instruction now
599  MIRBuilder.insertInstr(Inst);
600 
601  // Finally, copy the output operands into the output registers
602  ArrayRef<Register> ResRegs = GetOrCreateVRegs(Call);
603  if (ResRegs.size() != OutputOperands.size()) {
604  LLVM_DEBUG(dbgs() << "Expected the number of output registers to match the "
605  "number of destination registers\n");
606  return false;
607  }
608  for (unsigned int i = 0, e = ResRegs.size(); i < e; i++) {
609  GISelAsmOperandInfo &OpInfo = OutputOperands[i];
610 
611  if (OpInfo.Regs.empty())
612  continue;
613 
614  switch (OpInfo.ConstraintType) {
617  if (OpInfo.Regs.size() > 1) {
618  LLVM_DEBUG(dbgs() << "Output operands with multiple defining "
619  "registers are not supported yet\n");
620  return false;
621  }
622 
623  Register SrcReg = OpInfo.Regs[0];
624  unsigned SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
625  if (MRI->getType(ResRegs[i]).getSizeInBits() < SrcSize) {
626  // First copy the non-typed virtual register into a generic virtual
627  // register
628  Register Tmp1Reg =
630  MIRBuilder.buildCopy(Tmp1Reg, SrcReg);
631  // Need to truncate the result of the register
632  MIRBuilder.buildTrunc(ResRegs[i], Tmp1Reg);
633  } else {
634  MIRBuilder.buildCopy(ResRegs[i], SrcReg);
635  }
636  break;
637  }
640  LLVM_DEBUG(
641  dbgs() << "Cannot lower target specific output constraints yet\n");
642  return false;
644  break; // Already handled.
646  LLVM_DEBUG(dbgs() << "Unexpected unknown constraint\n");
647  return false;
648  }
649  }
650 
651  return true;
652 }
653 
655  Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
656  MachineIRBuilder &MIRBuilder) const {
657  if (Constraint.size() > 1)
658  return false;
659 
660  char ConstraintLetter = Constraint[0];
661  switch (ConstraintLetter) {
662  default:
663  return false;
664  case 'i': // Simple Integer or Relocatable Constant
665  case 'n': // immediate integer with a known value.
666  if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
667  assert(CI->getBitWidth() <= 64 &&
668  "expected immediate to fit into 64-bits");
669  // Boolean constants should be zero-extended, others are sign-extended
670  bool IsBool = CI->getBitWidth() == 1;
671  int64_t ExtVal = IsBool ? CI->getZExtValue() : CI->getSExtValue();
672  Ops.push_back(MachineOperand::CreateImm(ExtVal));
673  return true;
674  }
675  return false;
676  }
677 }
i
i
Definition: README.txt:29
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:69
llvm
This class represents lattice values for constants.
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
Reg
unsigned Reg
Definition: MachineSink.cpp:1540
llvm::InlineAsm::Extra_HasSideEffects
@ Extra_HasSideEffects
Definition: InlineAsm.h:221
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:111
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:158
llvm::TargetLowering::ConstraintType
ConstraintType
Definition: TargetLowering.h:4103
llvm::InlineAsm::getAsmString
const std::string & getAsmString() const
Definition: InlineAsm.h:81
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::PointerType::getElementType
Type * getElementType() const
Definition: DerivedTypes.h:653
llvm::Function
Definition: Function.h:61
getRegistersForValue
static void getRegistersForValue(MachineFunction &MF, MachineIRBuilder &MIRBuilder, GISelAsmOperandInfo &OpInfo, GISelAsmOperandInfo &RefOpInfo)
Assign virtual/physical registers for the specified register operand.
Definition: InlineAsmLowering.cpp:85
llvm::InlineAsm::isAlignStack
bool isAlignStack() const
Definition: InlineAsm.h:68
llvm::InlineAsm::ConstraintInfo::isIndirect
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:145
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition: MachineIRBuilder.h:288
llvm::InlineAsmLowering::lowerInlineAsm
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
Definition: InlineAsmLowering.cpp:273
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
llvm::TargetLowering::C_Memory
@ C_Memory
Definition: TargetLowering.h:4106
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:300
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
Module.h
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::MachineIRBuilder::buildInstrNoInsert
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
Definition: MachineIRBuilder.cpp:40
chooseConstraint
static void chooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, const TargetLowering *TLI)
Definition: InlineAsmLowering.cpp:158
MachineIRBuilder.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1541
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
F
#define F(x, y, z)
Definition: MD5.cpp:56
MachineRegisterInfo.h
llvm::ISD::INLINEASM
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:936
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
TargetLowering.h
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:77
llvm::Type::isSingleValueType
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition: Type.h:257
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
InlineAsmLowering.h
llvm::TargetLowering::AsmOperandInfo::ConstraintType
TargetLowering::ConstraintType ConstraintType
Information about the constraint code, e.g.
Definition: TargetLowering.h:4137
llvm::MachineOperand::CreateImm
static MachineOperand CreateImm(int64_t Val)
Definition: MachineOperand.h:770
llvm::InlineAsm::hasSideEffects
bool hasSideEffects() const
Definition: InlineAsm.h:67
llvm::InlineAsm::Extra_MayStore
@ Extra_MayStore
Definition: InlineAsm.h:225
llvm::LLT::getSizeInBits
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:109
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3143
llvm::TargetLowering::AsmOperandInfo::CallOperandVal
Value * CallOperandVal
If this is the result output operand or a clobber, this is null, otherwise it is the incoming operand...
Definition: TargetLowering.h:4142
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::InlineAsm::Kind_RegUse
@ Kind_RegUse
Definition: InlineAsm.h:231
Utils.h
llvm::InlineAsm::isInput
@ isInput
Definition: InlineAsm.h:92
llvm::CallBase::isConvergent
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:1856
llvm::InlineAsm::isRegDefKind
static bool isRegDefKind(unsigned Flag)
Definition: InlineAsm.h:276
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition: MachineIRBuilder.h:270
llvm::report_fatal_error
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::TargetLowering::C_Register
@ C_Register
Definition: TargetLowering.h:4104
llvm::TargetLowering::C_Immediate
@ C_Immediate
Definition: TargetLowering.h:4107
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:26
llvm::InlineAsm::getDialect
AsmDialect getDialect() const
Definition: InlineAsm.h:69
llvm::MachineInstrBuilder::addExternalSymbol
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:185
llvm::TargetLowering::C_Unknown
@ C_Unknown
Definition: TargetLowering.h:4109
llvm::MachineInstrBuilder::getReg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Definition: MachineInstrBuilder.h:95
llvm::InlineAsm::isMemKind
static bool isMemKind(unsigned Flag)
Definition: InlineAsm.h:278
getConstraintGenerality
static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT)
Return an integer indicating how general CT is.
Definition: InlineAsmLowering.cpp:142
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::InlineAsm::Kind_Mem
@ Kind_Mem
Definition: InlineAsm.h:236
llvm::InlineAsm
Definition: InlineAsm.h:31
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::TargetLowering::C_Other
@ C_Other
Definition: TargetLowering.h:4108
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:220
llvm::InlineAsm::isRegDefEarlyClobberKind
static bool isRegDefEarlyClobberKind(unsigned Flag)
Definition: InlineAsm.h:279
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:63
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:58
llvm::TargetLowering::ParseConstraints
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
Definition: TargetLowering.cpp:4607
llvm::InlineAsm::Kind_Imm
@ Kind_Imm
Definition: InlineAsm.h:235
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::InlineAsm::ConstraintInfo::isEarlyClobber
bool isEarlyClobber
isEarlyClobber - "&": output operand writes result before inputs are all read.
Definition: InlineAsm.h:125
Analysis.h
llvm::TargetLowering::AsmOperandInfo
This contains information for each constraint that we are lowering.
Definition: TargetLowering.h:4129
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:634
llvm::InlineAsm::Extra_AsmDialect
@ Extra_AsmDialect
Definition: InlineAsm.h:223
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::InlineAsm::ConstraintInfo::Codes
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:149
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:39
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::InlineAsm::ConstraintInfo::Type
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber.
Definition: InlineAsm.h:121
llvm::MachineRegisterInfo::createGenericVirtualRegister
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Definition: MachineRegisterInfo.cpp:188
llvm::MDNode
Metadata node.
Definition: Metadata.h:893
llvm::TargetLowering::AsmOperandInfo::ConstraintCode
std::string ConstraintCode
This contains the actual string for the code, like "m".
Definition: TargetLowering.h:4133
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::InlineAsm::getFlagWordForRegClass
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
getFlagWordForRegClass - Augment an existing flag word returned by getFlagWord with the required regi...
Definition: InlineAsm.h:301
llvm::TargetLoweringBase::getSimpleValueType
MVT getSimpleValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the MVT corresponding to this LLVM type. See getValueType.
Definition: TargetLowering.h:1426
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::TargetLoweringBase::getNumRegisters
unsigned getNumRegisters(LLVMContext &Context, EVT VT) const
Return the number of registers that this ValueType will eventually require.
Definition: TargetLowering.h:1471
DataLayout.h
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:212
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::InlineAsm::Extra_IsAlignStack
@ Extra_IsAlignStack
Definition: InlineAsm.h:222
llvm::MachineIRBuilder::insertInstr
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
Definition: MachineIRBuilder.cpp:45
llvm::InlineAsm::getFlagWord
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
Definition: InlineAsm.h:270
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::InlineAsm::Extra_IsConvergent
@ Extra_IsConvergent
Definition: InlineAsm.h:226
llvm::MachineIRBuilder::buildCopy
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
Definition: MachineIRBuilder.cpp:238
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::TargetLowering::AsmOperandInfo::getMatchedOperand
unsigned getMatchedOperand() const
If this is an input matching constraint, this method returns the output operand it matches.
Definition: TargetLowering.cpp:4596
llvm::InlineAsm::Constraint_Unknown
@ Constraint_Unknown
Definition: InlineAsm.h:242
llvm::TargetLowering::getRegForInlineAsmConstraint
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Definition: TargetLowering.cpp:4545
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::MachineIRBuilder::buildAnyExt
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
Definition: MachineIRBuilder.cpp:416
llvm::TargetLowering::C_RegisterClass
@ C_RegisterClass
Definition: TargetLowering.h:4105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::InlineAsm::getFlagWordForMem
static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint)
Augment an existing flag word returned by getFlagWord with the constraint code for a memory constrain...
Definition: InlineAsm.h:313
llvm::InlineAsm::Kind_RegDef
@ Kind_RegDef
Definition: InlineAsm.h:232
llvm::InlineAsm::getFlagWordForMatchingOp
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
Definition: InlineAsm.h:289
llvm::InlineAsm::Kind_RegDefEarlyClobber
@ Kind_RegDefEarlyClobber
Definition: InlineAsm.h:233
llvm::InlineAsm::Extra_MayLoad
@ Extra_MayLoad
Definition: InlineAsm.h:224
computeConstraintToUse
static void computeConstraintToUse(const TargetLowering *TLI, TargetLowering::AsmOperandInfo &OpInfo)
Definition: InlineAsmLowering.cpp:205
llvm::MachineIRBuilder::buildTrunc
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Definition: MachineIRBuilder.cpp:728
llvm::TargetRegisterClass::begin
iterator begin() const
begin/end - Return all of the registers in this class.
Definition: TargetRegisterInfo.h:73
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:521
llvm::TargetRegisterInfo::getRegSizeInBits
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
Definition: TargetRegisterInfo.h:274
uint16_t
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
llvm::InlineAsm::isClobber
@ isClobber
Definition: InlineAsm.h:94
llvm::TargetLowering::AsmOperandInfo::isMatchingInputConstraint
bool isMatchingInputConstraint() const
Return true of this is an input operand that is a matching constraint like "4".
Definition: TargetLowering.cpp:4589
llvm::TargetLowering::AsmOperandInfo::ConstraintVT
MVT ConstraintVT
The ValueType for the operand value.
Definition: TargetLowering.h:4145
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:45
llvm::CallBase::getCalledOperand
Value * getCalledOperand() const
Definition: InstrTypes.h:1389
llvm::InlineAsm::isOutput
@ isOutput
Definition: InlineAsm.h:93
Instructions.h
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:96
llvm::RegState::EarlyClobber
@ EarlyClobber
Register definition happens before uses.
Definition: MachineInstrBuilder.h:55
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
llvm::InlineAsm::getNumOperandRegisters
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
Definition: InlineAsm.h:337
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:480
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::TargetLowering::getInlineAsmMemConstraint
virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const
Definition: TargetLowering.h:4204
MachineOperand.h
getNumOpRegs
static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx)
Definition: InlineAsmLowering.cpp:235
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1164
llvm::InlineAsm::Kind_Clobber
@ Kind_Clobber
Definition: InlineAsm.h:234
LLVMContext.h
llvm::TargetLoweringBase::getValueType
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
Definition: TargetLowering.h:1386
llvm::InlineAsmLowering::lowerAsmOperandForConstraint
virtual bool lowerAsmOperandForConstraint(Value *Val, StringRef Constraint, std::vector< MachineOperand > &Ops, MachineIRBuilder &MIRBuilder) const
Lower the specified operand into the Ops vector.
Definition: InlineAsmLowering.cpp:654
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:43
llvm::getImplRegState
unsigned getImplRegState(bool B)
Definition: MachineInstrBuilder.h:501
llvm::TargetRegisterClass::end
iterator end() const
Definition: TargetRegisterInfo.h:74
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::TargetLowering::LowerXConstraint
virtual const char * LowerXConstraint(EVT ConstraintVT) const
Try to replace an X constraint, which matches anything, with another that has more specific requireme...
Definition: TargetLowering.cpp:4449
llvm::InlineAsm::ConstraintInfo::hasMatchingInput
bool hasMatchingInput() const
hasMatchingInput - Return true if this is an output constraint that has a matching input constraint.
Definition: InlineAsm.h:135
buildAnyextOrCopy
static bool buildAnyextOrCopy(Register Dst, Register Src, MachineIRBuilder &MIRBuilder)
Definition: InlineAsmLowering.cpp:240
llvm::TargetLowering::getConstraintType
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
Definition: TargetLowering.cpp:4404
llvm::TargetLowering::AsmOperandInfoVector
std::vector< AsmOperandInfo > AsmOperandInfoVector
Definition: TargetLowering.h:4160
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:281