LLVM  14.0.0git
AArch64GlobalISelUtils.cpp
Go to the documentation of this file.
1 //===- AArch64GlobalISelUtils.cpp --------------------------------*- C++ -*-==//
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 /// \file Implementations of AArch64-specific helper functions used in the
9 /// GlobalISel pipeline.
10 //===----------------------------------------------------------------------===//
11 #include "AArch64GlobalISelUtils.h"
12 #include "AArch64InstrInfo.h"
15 #include "llvm/IR/InstrTypes.h"
17 
18 using namespace llvm;
19 
22  const MachineRegisterInfo &MRI) {
23  if (auto Splat = getVectorSplat(MI, MRI))
24  return Splat;
25  if (MI.getOpcode() != AArch64::G_DUP)
26  return None;
27  Register Src = MI.getOperand(1).getReg();
28  if (auto ValAndVReg =
29  getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI))
30  return RegOrConstant(ValAndVReg->Value.getSExtValue());
31  return RegOrConstant(Src);
32 }
33 
36  const MachineRegisterInfo &MRI) {
37  auto Splat = getAArch64VectorSplat(MI, MRI);
38  if (!Splat || Splat->isReg())
39  return None;
40  return Splat->getCst();
41 }
42 
44  const CmpInst::Predicate &Pred,
45  const MachineRegisterInfo &MRI) {
46  // Match:
47  //
48  // %sub = G_SUB 0, %y
49  // %cmp = G_ICMP eq/ne, %sub, %z
50  //
51  // Or
52  //
53  // %sub = G_SUB 0, %y
54  // %cmp = G_ICMP eq/ne, %z, %sub
55  if (!MaybeSub || MaybeSub->getOpcode() != TargetOpcode::G_SUB ||
56  !CmpInst::isEquality(Pred))
57  return false;
58  auto MaybeZero =
60  return MaybeZero && MaybeZero->Value.getZExtValue() == 0;
61 }
62 
64  MachineIRBuilder &MIRBuilder,
65  bool MinSize) {
66  assert(MI.getOpcode() == TargetOpcode::G_MEMSET);
67  MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
68  auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
69  if (!TLI.getLibcallName(RTLIB::BZERO))
70  return false;
71  auto Zero = getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI);
72  if (!Zero || Zero->Value.getSExtValue() != 0)
73  return false;
74 
75  // It's not faster to use bzero rather than memset for sizes <= 256.
76  // However, it *does* save us a mov from wzr, so if we're going for
77  // minsize, use bzero even if it's slower.
78  if (!MinSize) {
79  // If the size is known, check it. If it is not known, assume using bzero is
80  // better.
81  if (auto Size =
82  getConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI)) {
83  if (Size->Value.getSExtValue() <= 256)
84  return false;
85  }
86  }
87 
88  MIRBuilder.setInstrAndDebugLoc(MI);
89  MIRBuilder
90  .buildInstr(TargetOpcode::G_BZERO, {},
91  {MI.getOperand(0), MI.getOperand(2)})
92  .addImm(MI.getOperand(3).getImm())
93  .addMemOperand(*MI.memoperands_begin());
94  MI.eraseFromParent();
95  return true;
96 }
97 
100  AArch64CC::CondCode &CondCode2) {
101  CondCode2 = AArch64CC::AL;
102  switch (P) {
103  default:
104  llvm_unreachable("Unknown FP condition!");
105  case CmpInst::FCMP_OEQ:
107  break;
108  case CmpInst::FCMP_OGT:
110  break;
111  case CmpInst::FCMP_OGE:
113  break;
114  case CmpInst::FCMP_OLT:
116  break;
117  case CmpInst::FCMP_OLE:
119  break;
120  case CmpInst::FCMP_ONE:
122  CondCode2 = AArch64CC::GT;
123  break;
124  case CmpInst::FCMP_ORD:
126  break;
127  case CmpInst::FCMP_UNO:
129  break;
130  case CmpInst::FCMP_UEQ:
132  CondCode2 = AArch64CC::VS;
133  break;
134  case CmpInst::FCMP_UGT:
136  break;
137  case CmpInst::FCMP_UGE:
139  break;
140  case CmpInst::FCMP_ULT:
142  break;
143  case CmpInst::FCMP_ULE:
145  break;
146  case CmpInst::FCMP_UNE:
148  break;
149  }
150 }
151 
154  AArch64CC::CondCode &CondCode2, bool &Invert) {
155  Invert = false;
156  switch (P) {
157  default:
158  // Mostly the scalar mappings work fine.
159  changeFCMPPredToAArch64CC(P, CondCode, CondCode2);
160  break;
161  case CmpInst::FCMP_UNO:
162  Invert = true;
164  case CmpInst::FCMP_ORD:
166  CondCode2 = AArch64CC::GE;
167  break;
168  case CmpInst::FCMP_UEQ:
169  case CmpInst::FCMP_ULT:
170  case CmpInst::FCMP_ULE:
171  case CmpInst::FCMP_UGT:
172  case CmpInst::FCMP_UGE:
173  // All of the compare-mask comparisons are ordered, but we can switch
174  // between the two by a double inversion. E.g. ULE == !OGT.
175  Invert = true;
177  CondCode2);
178  break;
179  }
180 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::CmpInst::FCMP_ULE
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
Definition: InstrTypes.h:735
llvm::AArch64GISelUtils::changeVectorFCMPPredToAArch64CC
void changeVectorFCMPPredToAArch64CC(const CmpInst::Predicate P, AArch64CC::CondCode &CondCode, AArch64CC::CondCode &CondCode2, bool &Invert)
Find the AArch64 condition codes necessary to represent P for a vector floating point comparison.
Definition: AArch64GlobalISelUtils.cpp:152
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm::AArch64CC::HI
@ HI
Definition: AArch64BaseInfo.h:263
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::AArch64CC::AL
@ AL
Definition: AArch64BaseInfo.h:269
llvm::AArch64CC::NE
@ NE
Definition: AArch64BaseInfo.h:256
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:720
llvm::AArch64CC::MI
@ MI
Definition: AArch64BaseInfo.h:259
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::AArch64GISelUtils::getAArch64VectorSplat
Optional< RegOrConstant > getAArch64VectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Definition: AArch64GlobalISelUtils.cpp:21
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition: MachineIRBuilder.h:280
llvm::CmpInst::FCMP_ONE
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition: InstrTypes.h:728
llvm::AArch64GISelUtils::changeFCMPPredToAArch64CC
void changeFCMPPredToAArch64CC(const CmpInst::Predicate P, AArch64CC::CondCode &CondCode, AArch64CC::CondCode &CondCode2)
Find the AArch64 condition codes necessary to represent P for a scalar floating point comparison.
Definition: AArch64GlobalISelUtils.cpp:98
llvm::CmpInst::getInversePredicate
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition: InstrTypes.h:820
llvm::AArch64GISelUtils::isCMN
bool isCMN(const MachineInstr *MaybeSub, const CmpInst::Predicate &Pred, const MachineRegisterInfo &MRI)
Definition: AArch64GlobalISelUtils.cpp:43
llvm::Optional
Definition: APInt.h:33
llvm::RegOrConstant
Represents a value which can be a Register or a constant.
Definition: Utils.h:321
llvm::CmpInst::FCMP_OGT
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition: InstrTypes.h:724
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
llvm::CmpInst::FCMP_ULT
@ FCMP_ULT
1 1 0 0 True if unordered or less than
Definition: InstrTypes.h:734
TargetLowering.h
AArch64InstrInfo.h
llvm::AArch64CC::VC
@ VC
Definition: AArch64BaseInfo.h:262
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
InstrTypes.h
llvm::CmpInst::FCMP_UGE
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
Definition: InstrTypes.h:733
Utils.h
llvm::CmpInst::FCMP_UNO
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition: InstrTypes.h:730
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition: MachineIRBuilder.h:262
llvm::AArch64CC::LE
@ LE
Definition: AArch64BaseInfo.h:268
llvm::AArch64CC::PL
@ PL
Definition: AArch64BaseInfo.h:260
llvm::CmpInst::FCMP_OEQ
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition: InstrTypes.h:723
llvm::CmpInst::FCMP_OLT
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition: InstrTypes.h:726
llvm::None
const NoneType None
Definition: None.h:23
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::AArch64GISelUtils::tryEmitBZero
bool tryEmitBZero(MachineInstr &MI, MachineIRBuilder &MIRBuilder, bool MinSize)
Replace a G_MEMSET with a value of 0 with a G_BZERO instruction if it is supported and beneficial to ...
Definition: AArch64GlobalISelUtils.cpp:63
AArch64GlobalISelUtils.h
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:212
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineIRBuilder::setInstrAndDebugLoc
void setInstrAndDebugLoc(MachineInstr &MI)
Set the insertion point to before MI, and set the debug loc to MI's loc.
Definition: MachineIRBuilder.h:342
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::CmpInst::FCMP_OGE
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition: InstrTypes.h:725
llvm::MachineInstrBuilder::addMemOperand
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Definition: MachineInstrBuilder.h:202
llvm::ISD::CondCode
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1355
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineIRBuilder::buildInstr
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Definition: MachineIRBuilder.h:367
llvm::AArch64CC::GE
@ GE
Definition: AArch64BaseInfo.h:265
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:489
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:273
llvm::AArch64CC::EQ
@ EQ
Definition: AArch64BaseInfo.h:255
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::CmpInst::FCMP_UGT
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
Definition: InstrTypes.h:732
llvm::AArch64CC::VS
@ VS
Definition: AArch64BaseInfo.h:261
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
llvm::getVectorSplat
Optional< RegOrConstant > getVectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:937
llvm::CmpInst::isEquality
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition: InstrTypes.h:924
llvm::AArch64CC::GT
@ GT
Definition: AArch64BaseInfo.h:267
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:96
llvm::CmpInst::FCMP_UNE
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Definition: InstrTypes.h:736
llvm::CmpInst::FCMP_OLE
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition: InstrTypes.h:727
llvm::AArch64CC::CondCode
CondCode
Definition: AArch64BaseInfo.h:254
raw_ostream.h
llvm::AArch64GISelUtils::getAArch64VectorSplatScalar
Optional< int64_t > getAArch64VectorSplatScalar(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Definition: AArch64GlobalISelUtils.cpp:35
llvm::CmpInst::FCMP_ORD
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
Definition: InstrTypes.h:729
llvm::getConstantVRegValWithLookThrough
Optional< ValueAndVReg > getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true, bool HandleFConstants=true, bool LookThroughAnyExt=false)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_F/CONSTANT (LookThro...
Definition: Utils.cpp:289
llvm::CmpInst::FCMP_UEQ
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition: InstrTypes.h:731