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  getAnyConstantVRegValWithLookThrough(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 =
72  getIConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI);
73  if (!Zero || Zero->Value.getSExtValue() != 0)
74  return false;
75 
76  // It's not faster to use bzero rather than memset for sizes <= 256.
77  // However, it *does* save us a mov from wzr, so if we're going for
78  // minsize, use bzero even if it's slower.
79  if (!MinSize) {
80  // If the size is known, check it. If it is not known, assume using bzero is
81  // better.
83  MI.getOperand(2).getReg(), MRI)) {
84  if (Size->Value.getSExtValue() <= 256)
85  return false;
86  }
87  }
88 
89  MIRBuilder.setInstrAndDebugLoc(MI);
90  MIRBuilder
91  .buildInstr(TargetOpcode::G_BZERO, {},
92  {MI.getOperand(0), MI.getOperand(2)})
93  .addImm(MI.getOperand(3).getImm())
94  .addMemOperand(*MI.memoperands_begin());
95  MI.eraseFromParent();
96  return true;
97 }
98 
101  AArch64CC::CondCode &CondCode2) {
102  CondCode2 = AArch64CC::AL;
103  switch (P) {
104  default:
105  llvm_unreachable("Unknown FP condition!");
106  case CmpInst::FCMP_OEQ:
108  break;
109  case CmpInst::FCMP_OGT:
111  break;
112  case CmpInst::FCMP_OGE:
114  break;
115  case CmpInst::FCMP_OLT:
117  break;
118  case CmpInst::FCMP_OLE:
120  break;
121  case CmpInst::FCMP_ONE:
123  CondCode2 = AArch64CC::GT;
124  break;
125  case CmpInst::FCMP_ORD:
127  break;
128  case CmpInst::FCMP_UNO:
130  break;
131  case CmpInst::FCMP_UEQ:
133  CondCode2 = AArch64CC::VS;
134  break;
135  case CmpInst::FCMP_UGT:
137  break;
138  case CmpInst::FCMP_UGE:
140  break;
141  case CmpInst::FCMP_ULT:
143  break;
144  case CmpInst::FCMP_ULE:
146  break;
147  case CmpInst::FCMP_UNE:
149  break;
150  }
151 }
152 
155  AArch64CC::CondCode &CondCode2, bool &Invert) {
156  Invert = false;
157  switch (P) {
158  default:
159  // Mostly the scalar mappings work fine.
160  changeFCMPPredToAArch64CC(P, CondCode, CondCode2);
161  break;
162  case CmpInst::FCMP_UNO:
163  Invert = true;
165  case CmpInst::FCMP_ORD:
167  CondCode2 = AArch64CC::GE;
168  break;
169  case CmpInst::FCMP_UEQ:
170  case CmpInst::FCMP_ULT:
171  case CmpInst::FCMP_ULE:
172  case CmpInst::FCMP_UGT:
173  case CmpInst::FCMP_UGE:
174  // All of the compare-mask comparisons are ordered, but we can switch
175  // between the two by a double inversion. E.g. ULE == !OGT.
176  Invert = true;
178  CondCode2);
179  break;
180  }
181 }
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:736
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:153
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm::AArch64CC::HI
@ HI
Definition: AArch64BaseInfo.h:263
llvm
This is an optimization pass for GlobalISel generic memory operations.
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:721
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:729
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:99
llvm::CmpInst::getInversePredicate
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition: InstrTypes.h:835
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:347
llvm::CmpInst::FCMP_OGT
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition: InstrTypes.h:725
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:735
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:734
Utils.h
llvm::CmpInst::FCMP_UNO
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition: InstrTypes.h:731
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:724
llvm::CmpInst::FCMP_OLT
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition: InstrTypes.h:727
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:641
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:726
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:1366
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::getAnyConstantVRegValWithLookThrough
Optional< ValueAndVReg > getAnyConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true, bool LookThroughAnyExt=false)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT or G_FCONST...
Definition: Utils.cpp:407
llvm::AArch64CC::GE
@ GE
Definition: AArch64BaseInfo.h:265
llvm::getIConstantVRegValWithLookThrough
Optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
Definition: Utils.cpp:401
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:134
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:286
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:733
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:1079
llvm::CmpInst::isEquality
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition: InstrTypes.h:939
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:737
llvm::CmpInst::FCMP_OLE
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition: InstrTypes.h:728
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:730
llvm::CmpInst::FCMP_UEQ
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition: InstrTypes.h:732