956 lines · c
1//===-- PPCISelLowering.h - PPC32 DAG Lowering Interface --------*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that PPC uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H15#define LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H16 17#include "PPCInstrInfo.h"18#include "llvm/CodeGen/CallingConvLower.h"19#include "llvm/CodeGen/MachineFunction.h"20#include "llvm/CodeGen/MachineMemOperand.h"21#include "llvm/CodeGen/SelectionDAG.h"22#include "llvm/CodeGen/SelectionDAGNodes.h"23#include "llvm/CodeGen/TargetLowering.h"24#include "llvm/CodeGen/ValueTypes.h"25#include "llvm/CodeGenTypes/MachineValueType.h"26#include "llvm/IR/Attributes.h"27#include "llvm/IR/CallingConv.h"28#include "llvm/IR/Function.h"29#include "llvm/IR/InlineAsm.h"30#include "llvm/IR/Metadata.h"31#include "llvm/IR/Type.h"32#include <optional>33#include <utility>34 35namespace llvm {36 37 /// Define some predicates that are used for node matching.38 namespace PPC {39 40 /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a41 /// VPKUHUM instruction.42 bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,43 SelectionDAG &DAG);44 45 /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a46 /// VPKUWUM instruction.47 bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,48 SelectionDAG &DAG);49 50 /// isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a51 /// VPKUDUM instruction.52 bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,53 SelectionDAG &DAG);54 55 /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for56 /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).57 bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,58 unsigned ShuffleKind, SelectionDAG &DAG);59 60 /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for61 /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).62 bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,63 unsigned ShuffleKind, SelectionDAG &DAG);64 65 /// isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for66 /// a VMRGEW or VMRGOW instruction67 bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven,68 unsigned ShuffleKind, SelectionDAG &DAG);69 /// isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable70 /// for a XXSLDWI instruction.71 bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,72 bool &Swap, bool IsLE);73 74 /// isXXBRHShuffleMask - Return true if this is a shuffle mask suitable75 /// for a XXBRH instruction.76 bool isXXBRHShuffleMask(ShuffleVectorSDNode *N);77 78 /// isXXBRWShuffleMask - Return true if this is a shuffle mask suitable79 /// for a XXBRW instruction.80 bool isXXBRWShuffleMask(ShuffleVectorSDNode *N);81 82 /// isXXBRDShuffleMask - Return true if this is a shuffle mask suitable83 /// for a XXBRD instruction.84 bool isXXBRDShuffleMask(ShuffleVectorSDNode *N);85 86 /// isXXBRQShuffleMask - Return true if this is a shuffle mask suitable87 /// for a XXBRQ instruction.88 bool isXXBRQShuffleMask(ShuffleVectorSDNode *N);89 90 /// isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable91 /// for a XXPERMDI instruction.92 bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,93 bool &Swap, bool IsLE);94 95 /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the96 /// shift amount, otherwise return -1.97 int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind,98 SelectionDAG &DAG);99 100 /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand101 /// specifies a splat of a single element that is suitable for input to102 /// VSPLTB/VSPLTH/VSPLTW.103 bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize);104 105 /// isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by106 /// the XXINSERTW instruction introduced in ISA 3.0. This is essentially any107 /// shuffle of v4f32/v4i32 vectors that just inserts one element from one108 /// vector into the other. This function will also set a couple of109 /// output parameters for how much the source vector needs to be shifted and110 /// what byte number needs to be specified for the instruction to put the111 /// element in the desired location of the target vector.112 bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,113 unsigned &InsertAtByte, bool &Swap, bool IsLE);114 115 /// getSplatIdxForPPCMnemonics - Return the splat index as a value that is116 /// appropriate for PPC mnemonics (which have a big endian bias - namely117 /// elements are counted from the left of the vector register).118 unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize,119 SelectionDAG &DAG);120 121 /// get_VSPLTI_elt - If this is a build_vector of constants which can be122 /// formed by using a vspltis[bhw] instruction of the specified element123 /// size, return the constant being splatted. The ByteSize field indicates124 /// the number of bytes of each element [124] -> [bhw].125 SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);126 127 // Flags for computing the optimal addressing mode for loads and stores.128 enum MemOpFlags {129 MOF_None = 0,130 131 // Extension mode for integer loads.132 MOF_SExt = 1,133 MOF_ZExt = 1 << 1,134 MOF_NoExt = 1 << 2,135 136 // Address computation flags.137 MOF_NotAddNorCst = 1 << 5, // Not const. or sum of ptr and scalar.138 MOF_RPlusSImm16 = 1 << 6, // Reg plus signed 16-bit constant.139 MOF_RPlusLo = 1 << 7, // Reg plus signed 16-bit relocation140 MOF_RPlusSImm16Mult4 = 1 << 8, // Reg plus 16-bit signed multiple of 4.141 MOF_RPlusSImm16Mult16 = 1 << 9, // Reg plus 16-bit signed multiple of 16.142 MOF_RPlusSImm34 = 1 << 10, // Reg plus 34-bit signed constant.143 MOF_RPlusR = 1 << 11, // Sum of two variables.144 MOF_PCRel = 1 << 12, // PC-Relative relocation.145 MOF_AddrIsSImm32 = 1 << 13, // A simple 32-bit constant.146 147 // The in-memory type.148 MOF_SubWordInt = 1 << 15,149 MOF_WordInt = 1 << 16,150 MOF_DoubleWordInt = 1 << 17,151 MOF_ScalarFloat = 1 << 18, // Scalar single or double precision.152 MOF_Vector = 1 << 19, // Vector types and quad precision scalars.153 MOF_Vector256 = 1 << 20,154 155 // Subtarget features.156 MOF_SubtargetBeforeP9 = 1 << 22,157 MOF_SubtargetP9 = 1 << 23,158 MOF_SubtargetP10 = 1 << 24,159 MOF_SubtargetSPE = 1 << 25160 };161 162 // The addressing modes for loads and stores.163 enum AddrMode {164 AM_None,165 AM_DForm,166 AM_DSForm,167 AM_DQForm,168 AM_PrefixDForm,169 AM_XForm,170 AM_PCRel171 };172 } // end namespace PPC173 174 class PPCTargetLowering : public TargetLowering {175 const PPCSubtarget &Subtarget;176 177 public:178 explicit PPCTargetLowering(const PPCTargetMachine &TM,179 const PPCSubtarget &STI);180 181 bool isSelectSupported(SelectSupportKind Kind) const override {182 // PowerPC does not support scalar condition selects on vectors.183 return (Kind != SelectSupportKind::ScalarCondVectorVal);184 }185 186 /// getPreferredVectorAction - The code we generate when vector types are187 /// legalized by promoting the integer element type is often much worse188 /// than code we generate if we widen the type for applicable vector types.189 /// The issue with promoting is that the vector is scalaraized, individual190 /// elements promoted and then the vector is rebuilt. So say we load a pair191 /// of v4i8's and shuffle them. This will turn into a mess of 8 extending192 /// loads, moves back into VSR's (or memory ops if we don't have moves) and193 /// then the VPERM for the shuffle. All in all a very slow sequence.194 TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT)195 const override {196 // Default handling for scalable and single-element vectors.197 if (VT.isScalableVector() || VT.getVectorNumElements() == 1)198 return TargetLoweringBase::getPreferredVectorAction(VT);199 200 // Split and promote vNi1 vectors so we don't produce v256i1/v512i1201 // types as those are only for MMA instructions.202 if (VT.getScalarSizeInBits() == 1 && VT.getSizeInBits() > 16)203 return TypeSplitVector;204 if (VT.getScalarSizeInBits() == 1)205 return TypePromoteInteger;206 207 // Widen vectors that have reasonably sized elements.208 if (VT.getScalarSizeInBits() % 8 == 0)209 return TypeWidenVector;210 return TargetLoweringBase::getPreferredVectorAction(VT);211 }212 213 bool useSoftFloat() const override;214 215 bool hasSPE() const;216 217 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {218 return MVT::i32;219 }220 221 bool isCheapToSpeculateCttz(Type *Ty) const override {222 return true;223 }224 225 bool isCheapToSpeculateCtlz(Type *Ty) const override {226 return true;227 }228 229 bool230 shallExtractConstSplatVectorElementToStore(Type *VectorTy,231 unsigned ElemSizeInBits,232 unsigned &Index) const override;233 234 bool isCtlzFast() const override {235 return true;236 }237 238 bool isEqualityCmpFoldedWithSignedCmp() const override {239 return false;240 }241 242 bool hasAndNotCompare(SDValue) const override {243 return true;244 }245 246 bool preferIncOfAddToSubOfNot(EVT VT) const override;247 248 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {249 return VT.isScalarInteger();250 }251 252 SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps,253 bool OptForSize, NegatibleCost &Cost,254 unsigned Depth = 0) const override;255 256 /// getSetCCResultType - Return the ISD::SETCC ValueType257 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,258 EVT VT) const override;259 260 /// Return true if target always benefits from combining into FMA for a261 /// given value type. This must typically return false on targets where FMA262 /// takes more cycles to execute than FADD.263 bool enableAggressiveFMAFusion(EVT VT) const override;264 265 /// getPreIndexedAddressParts - returns true by value, base pointer and266 /// offset pointer and addressing mode by reference if the node's address267 /// can be legally represented as pre-indexed load / store address.268 bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,269 SDValue &Offset,270 ISD::MemIndexedMode &AM,271 SelectionDAG &DAG) const override;272 273 /// SelectAddressEVXRegReg - Given the specified addressed, check to see if274 /// it can be more efficiently represented as [r+imm].275 bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index,276 SelectionDAG &DAG) const;277 278 /// SelectAddressRegReg - Given the specified addressed, check to see if it279 /// can be more efficiently represented as [r+imm]. If \p EncodingAlignment280 /// is non-zero, only accept displacement which is not suitable for [r+imm].281 /// Returns false if it can be represented by [r+imm], which are preferred.282 bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index,283 SelectionDAG &DAG,284 MaybeAlign EncodingAlignment = std::nullopt) const;285 286 /// SelectAddressRegImm - Returns true if the address N can be represented287 /// by a base register plus a signed 16-bit displacement [r+imm], and if it288 /// is not better represented as reg+reg. If \p EncodingAlignment is289 /// non-zero, only accept displacements suitable for instruction encoding290 /// requirement, i.e. multiples of 4 for DS form.291 bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base,292 SelectionDAG &DAG,293 MaybeAlign EncodingAlignment) const;294 bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base,295 SelectionDAG &DAG) const;296 297 /// SelectAddressRegRegOnly - Given the specified addressed, force it to be298 /// represented as an indexed [r+r] operation.299 bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index,300 SelectionDAG &DAG) const;301 302 /// SelectAddressPCRel - Represent the specified address as pc relative to303 /// be represented as [pc+imm]304 bool SelectAddressPCRel(SDValue N, SDValue &Base) const;305 306 Sched::Preference getSchedulingPreference(SDNode *N) const override;307 308 /// LowerOperation - Provide custom lowering hooks for some operations.309 ///310 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;311 312 /// ReplaceNodeResults - Replace the results of node with an illegal result313 /// type with new values built out of custom code.314 ///315 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,316 SelectionDAG &DAG) const override;317 318 SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const;319 SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const;320 321 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;322 323 SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,324 SmallVectorImpl<SDNode *> &Created) const override;325 326 Register getRegisterByName(const char* RegName, LLT VT,327 const MachineFunction &MF) const override;328 329 void computeKnownBitsForTargetNode(const SDValue Op,330 KnownBits &Known,331 const APInt &DemandedElts,332 const SelectionDAG &DAG,333 unsigned Depth = 0) const override;334 335 Align getPrefLoopAlignment(MachineLoop *ML) const override;336 337 bool shouldInsertFencesForAtomic(const Instruction *I) const override {338 return true;339 }340 341 Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,342 AtomicOrdering Ord) const override;343 344 Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,345 AtomicOrdering Ord) const override;346 347 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,348 AtomicOrdering Ord) const override;349 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,350 AtomicOrdering Ord) const override;351 352 bool shouldInlineQuadwordAtomics() const;353 354 TargetLowering::AtomicExpansionKind355 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;356 357 TargetLowering::AtomicExpansionKind358 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;359 360 Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder,361 AtomicRMWInst *AI, Value *AlignedAddr,362 Value *Incr, Value *Mask,363 Value *ShiftAmt,364 AtomicOrdering Ord) const override;365 Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,366 AtomicCmpXchgInst *CI,367 Value *AlignedAddr, Value *CmpVal,368 Value *NewVal, Value *Mask,369 AtomicOrdering Ord) const override;370 371 MachineBasicBlock *372 EmitInstrWithCustomInserter(MachineInstr &MI,373 MachineBasicBlock *MBB) const override;374 MachineBasicBlock *EmitAtomicBinary(MachineInstr &MI,375 MachineBasicBlock *MBB,376 unsigned AtomicSize,377 unsigned BinOpcode,378 unsigned CmpOpcode = 0,379 unsigned CmpPred = 0) const;380 MachineBasicBlock *EmitPartwordAtomicBinary(MachineInstr &MI,381 MachineBasicBlock *MBB,382 bool is8bit,383 unsigned Opcode,384 unsigned CmpOpcode = 0,385 unsigned CmpPred = 0) const;386 387 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,388 MachineBasicBlock *MBB) const;389 390 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,391 MachineBasicBlock *MBB) const;392 393 MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,394 MachineBasicBlock *MBB) const;395 396 bool hasInlineStackProbe(const MachineFunction &MF) const override;397 398 unsigned getStackProbeSize(const MachineFunction &MF) const;399 400 ConstraintType getConstraintType(StringRef Constraint) const override;401 402 /// Examine constraint string and operand type and determine a weight value.403 /// The operand object must already have been set up with the operand type.404 ConstraintWeight getSingleConstraintMatchWeight(405 AsmOperandInfo &info, const char *constraint) const override;406 407 std::pair<unsigned, const TargetRegisterClass *>408 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,409 StringRef Constraint, MVT VT) const override;410 411 /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate412 /// function arguments in the caller parameter area.413 Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override;414 415 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops416 /// vector. If it is invalid, don't add anything to Ops.417 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,418 std::vector<SDValue> &Ops,419 SelectionDAG &DAG) const override;420 421 InlineAsm::ConstraintCode422 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {423 if (ConstraintCode == "es")424 return InlineAsm::ConstraintCode::es;425 else if (ConstraintCode == "Q")426 return InlineAsm::ConstraintCode::Q;427 else if (ConstraintCode == "Z")428 return InlineAsm::ConstraintCode::Z;429 else if (ConstraintCode == "Zy")430 return InlineAsm::ConstraintCode::Zy;431 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);432 }433 434 void CollectTargetIntrinsicOperands(const CallInst &I,435 SmallVectorImpl<SDValue> &Ops,436 SelectionDAG &DAG) const override;437 438 /// isLegalAddressingMode - Return true if the addressing mode represented439 /// by AM is legal for this target, for a load/store of the specified type.440 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,441 Type *Ty, unsigned AS,442 Instruction *I = nullptr) const override;443 444 /// isLegalICmpImmediate - Return true if the specified immediate is legal445 /// icmp immediate, that is the target has icmp instructions which can446 /// compare a register against the immediate without having to materialize447 /// the immediate into a register.448 bool isLegalICmpImmediate(int64_t Imm) const override;449 450 /// isLegalAddImmediate - Return true if the specified immediate is legal451 /// add immediate, that is the target has add instructions which can452 /// add a register and the immediate without having to materialize453 /// the immediate into a register.454 bool isLegalAddImmediate(int64_t Imm) const override;455 456 /// isTruncateFree - Return true if it's free to truncate a value of457 /// type Ty1 to type Ty2. e.g. On PPC it's free to truncate a i64 value in458 /// register X1 to i32 by referencing its sub-register R1.459 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;460 bool isTruncateFree(EVT VT1, EVT VT2) const override;461 462 bool isZExtFree(SDValue Val, EVT VT2) const override;463 464 bool isFPExtFree(EVT DestVT, EVT SrcVT) const override;465 466 /// Returns true if it is beneficial to convert a load of a constant467 /// to just the constant itself.468 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,469 Type *Ty) const override;470 471 bool convertSelectOfConstantsToMath(EVT VT) const override {472 return true;473 }474 475 bool decomposeMulByConstant(LLVMContext &Context, EVT VT,476 SDValue C) const override;477 478 bool isDesirableToTransformToIntegerOp(unsigned Opc,479 EVT VT) const override {480 // Only handle float load/store pair because float(fpr) load/store481 // instruction has more cycles than integer(gpr) load/store in PPC.482 if (Opc != ISD::LOAD && Opc != ISD::STORE)483 return false;484 if (VT != MVT::f32 && VT != MVT::f64)485 return false;486 487 return true;488 }489 490 // Returns true if the address of the global is stored in TOC entry.491 bool isAccessedAsGotIndirect(SDValue N) const;492 493 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;494 495 bool getTgtMemIntrinsic(IntrinsicInfo &Info,496 const CallInst &I,497 MachineFunction &MF,498 unsigned Intrinsic) const override;499 500 /// It returns EVT::Other if the type should be determined using generic501 /// target-independent logic.502 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,503 const AttributeList &FuncAttributes) const override;504 505 /// Is unaligned memory access allowed for the given type, and is it fast506 /// relative to software emulation.507 bool allowsMisalignedMemoryAccesses(508 EVT VT, unsigned AddrSpace, Align Alignment = Align(1),509 MachineMemOperand::Flags Flags = MachineMemOperand::MONone,510 unsigned *Fast = nullptr) const override;511 512 /// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster513 /// than a pair of fmul and fadd instructions. fmuladd intrinsics will be514 /// expanded to FMAs when this method returns true, otherwise fmuladd is515 /// expanded to fmul + fadd.516 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,517 EVT VT) const override;518 519 bool isFMAFasterThanFMulAndFAdd(const Function &F, Type *Ty) const override;520 521 /// isProfitableToHoist - Check if it is profitable to hoist instruction522 /// \p I to its dominator block.523 /// For example, it is not profitable if \p I and it's only user can form a524 /// FMA instruction, because Powerpc prefers FMADD.525 bool isProfitableToHoist(Instruction *I) const override;526 527 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;528 529 // Should we expand the build vector with shuffles?530 bool531 shouldExpandBuildVectorWithShuffles(EVT VT,532 unsigned DefinedValues) const override;533 534 // Keep the zero-extensions for arguments to libcalls.535 bool shouldKeepZExtForFP16Conv() const override { return true; }536 537 /// createFastISel - This method returns a target-specific FastISel object,538 /// or null if the target does not support "fast" instruction selection.539 FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,540 const TargetLibraryInfo *LibInfo) const override;541 542 /// Returns true if an argument of type Ty needs to be passed in a543 /// contiguous block of registers in calling convention CallConv.544 bool functionArgumentNeedsConsecutiveRegisters(545 Type *Ty, CallingConv::ID CallConv, bool isVarArg,546 const DataLayout &DL) const override {547 // We support any array type as "consecutive" block in the parameter548 // save area. The element type defines the alignment requirement and549 // whether the argument should go in GPRs, FPRs, or VRs if available.550 //551 // Note that clang uses this capability both to implement the ELFv2552 // homogeneous float/vector aggregate ABI, and to avoid having to use553 // "byval" when passing aggregates that might fully fit in registers.554 return Ty->isArrayTy();555 }556 557 /// If a physical register, this returns the register that receives the558 /// exception address on entry to an EH pad.559 Register560 getExceptionPointerRegister(const Constant *PersonalityFn) const override;561 562 /// If a physical register, this returns the register that receives the563 /// exception typeid on entry to a landing pad.564 Register565 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;566 567 /// Override to support customized stack guard loading.568 bool useLoadStackGuardNode(const Module &M) const override;569 570 bool isFPImmLegal(const APFloat &Imm, EVT VT,571 bool ForCodeSize) const override;572 573 unsigned getJumpTableEncoding() const override;574 bool isJumpTableRelative() const override;575 SDValue getPICJumpTableRelocBase(SDValue Table,576 SelectionDAG &DAG) const override;577 const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF,578 unsigned JTI,579 MCContext &Ctx) const override;580 581 /// SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode),582 /// compute the address flags of the node, get the optimal address mode583 /// based on the flags, and set the Base and Disp based on the address mode.584 PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N,585 SDValue &Disp, SDValue &Base,586 SelectionDAG &DAG,587 MaybeAlign Align) const;588 /// SelectForceXFormMode - Given the specified address, force it to be589 /// represented as an indexed [r+r] operation (an XForm instruction).590 PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base,591 SelectionDAG &DAG) const;592 593 bool splitValueIntoRegisterParts(594 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,595 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)596 const override;597 /// Structure that collects some common arguments that get passed around598 /// between the functions for call lowering.599 struct CallFlags {600 const CallingConv::ID CallConv;601 const bool IsTailCall : 1;602 const bool IsVarArg : 1;603 const bool IsPatchPoint : 1;604 const bool IsIndirect : 1;605 const bool HasNest : 1;606 const bool NoMerge : 1;607 608 CallFlags(CallingConv::ID CC, bool IsTailCall, bool IsVarArg,609 bool IsPatchPoint, bool IsIndirect, bool HasNest, bool NoMerge)610 : CallConv(CC), IsTailCall(IsTailCall), IsVarArg(IsVarArg),611 IsPatchPoint(IsPatchPoint), IsIndirect(IsIndirect),612 HasNest(HasNest), NoMerge(NoMerge) {}613 };614 615 CCAssignFn *ccAssignFnForCall(CallingConv::ID CC, bool Return,616 bool IsVarArg) const;617 bool supportsTailCallFor(const CallBase *CB) const;618 619 bool hasMultipleConditionRegisters(EVT VT) const override;620 621 private:622 struct ReuseLoadInfo {623 SDValue Ptr;624 SDValue Chain;625 SDValue ResChain;626 MachinePointerInfo MPI;627 bool IsDereferenceable = false;628 bool IsInvariant = false;629 Align Alignment;630 AAMDNodes AAInfo;631 const MDNode *Ranges = nullptr;632 633 ReuseLoadInfo() = default;634 635 MachineMemOperand::Flags MMOFlags() const {636 MachineMemOperand::Flags F = MachineMemOperand::MONone;637 if (IsDereferenceable)638 F |= MachineMemOperand::MODereferenceable;639 if (IsInvariant)640 F |= MachineMemOperand::MOInvariant;641 return F;642 }643 };644 645 // Map that relates a set of common address flags to PPC addressing modes.646 std::map<PPC::AddrMode, SmallVector<unsigned, 16>> AddrModesMap;647 void initializeAddrModeMap();648 649 bool canReuseLoadAddress(SDValue Op, EVT MemVT, ReuseLoadInfo &RLI,650 SelectionDAG &DAG,651 ISD::LoadExtType ET = ISD::NON_EXTLOAD) const;652 653 void LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,654 SelectionDAG &DAG, const SDLoc &dl) const;655 SDValue LowerFP_TO_INTDirectMove(SDValue Op, SelectionDAG &DAG,656 const SDLoc &dl) const;657 658 bool directMoveIsProfitable(const SDValue &Op) const;659 SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG &DAG,660 const SDLoc &dl) const;661 662 SDValue LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,663 const SDLoc &dl) const;664 665 SDValue LowerTRUNCATEVector(SDValue Op, SelectionDAG &DAG) const;666 667 SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;668 SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;669 670 bool IsEligibleForTailCallOptimization(671 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,672 CallingConv::ID CallerCC, bool isVarArg,673 const SmallVectorImpl<ISD::InputArg> &Ins) const;674 675 bool IsEligibleForTailCallOptimization_64SVR4(676 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,677 CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,678 const SmallVectorImpl<ISD::OutputArg> &Outs,679 const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc,680 bool isCalleeExternalSymbol) const;681 682 bool isEligibleForTCO(const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,683 CallingConv::ID CallerCC, const CallBase *CB,684 bool isVarArg,685 const SmallVectorImpl<ISD::OutputArg> &Outs,686 const SmallVectorImpl<ISD::InputArg> &Ins,687 const Function *CallerFunc,688 bool isCalleeExternalSymbol) const;689 690 SDValue EmitTailCallLoadFPAndRetAddr(SelectionDAG &DAG, int SPDiff,691 SDValue Chain, SDValue &LROpOut,692 SDValue &FPOpOut,693 const SDLoc &dl) const;694 695 SDValue getTOCEntry(SelectionDAG &DAG, const SDLoc &dl, SDValue GA) const;696 697 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;698 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;699 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;700 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;701 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;702 SDValue LowerGlobalTLSAddressAIX(SDValue Op, SelectionDAG &DAG) const;703 SDValue LowerGlobalTLSAddressLinux(SDValue Op, SelectionDAG &DAG) const;704 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;705 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;706 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;707 SDValue LowerSSUBO(SDValue Op, SelectionDAG &DAG) const;708 SDValue LowerSADDO(SDValue Op, SelectionDAG &DAG) const;709 SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;710 SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;711 SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;712 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;713 SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const;714 SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const;715 SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;716 SDValue LowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const;717 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;718 SDValue LowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;719 SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;720 SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;721 SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;722 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;723 SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,724 const SDLoc &dl) const;725 SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;726 SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;727 SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;728 SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const;729 SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const;730 SDValue LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const;731 SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) const;732 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;733 SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;734 SDValue LowerVPERM(SDValue Op, SelectionDAG &DAG, ArrayRef<int> PermMask,735 EVT VT, SDValue V1, SDValue V2) const;736 SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;737 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;738 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;739 SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const;740 SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;741 SDValue LowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;742 SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;743 SDValue LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const;744 SDValue LowerUCMP(SDValue Op, SelectionDAG &DAG) const;745 SDValue lowerToLibCall(const char *LibCallName, SDValue Op,746 SelectionDAG &DAG) const;747 SDValue lowerLibCallBasedOnType(const char *LibCallFloatName,748 const char *LibCallDoubleName, SDValue Op,749 SelectionDAG &DAG) const;750 bool isLowringToMASSFiniteSafe(SDValue Op) const;751 bool isLowringToMASSSafe(SDValue Op) const;752 bool isScalarMASSConversionEnabled() const;753 SDValue lowerLibCallBase(const char *LibCallDoubleName,754 const char *LibCallFloatName,755 const char *LibCallDoubleNameFinite,756 const char *LibCallFloatNameFinite, SDValue Op,757 SelectionDAG &DAG) const;758 SDValue lowerPow(SDValue Op, SelectionDAG &DAG) const;759 SDValue lowerSin(SDValue Op, SelectionDAG &DAG) const;760 SDValue lowerCos(SDValue Op, SelectionDAG &DAG) const;761 SDValue lowerLog(SDValue Op, SelectionDAG &DAG) const;762 SDValue lowerLog10(SDValue Op, SelectionDAG &DAG) const;763 SDValue lowerExp(SDValue Op, SelectionDAG &DAG) const;764 SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) const;765 SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;766 SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const;767 SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;768 SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;769 SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;770 771 SDValue LowerVP_LOAD(SDValue Op, SelectionDAG &DAG) const;772 SDValue LowerVP_STORE(SDValue Op, SelectionDAG &DAG) const;773 774 SDValue LowerVectorLoad(SDValue Op, SelectionDAG &DAG) const;775 SDValue LowerVectorStore(SDValue Op, SelectionDAG &DAG) const;776 SDValue LowerDMFVectorLoad(SDValue Op, SelectionDAG &DAG) const;777 SDValue LowerDMFVectorStore(SDValue Op, SelectionDAG &DAG) const;778 SDValue DMFInsert1024(const SmallVectorImpl<SDValue> &Pairs,779 const SDLoc &dl, SelectionDAG &DAG) const;780 781 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,782 CallingConv::ID CallConv, bool isVarArg,783 const SmallVectorImpl<ISD::InputArg> &Ins,784 const SDLoc &dl, SelectionDAG &DAG,785 SmallVectorImpl<SDValue> &InVals) const;786 787 SDValue FinishCall(CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG,788 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,789 SDValue InGlue, SDValue Chain, SDValue CallSeqStart,790 SDValue &Callee, int SPDiff, unsigned NumBytes,791 const SmallVectorImpl<ISD::InputArg> &Ins,792 SmallVectorImpl<SDValue> &InVals,793 const CallBase *CB) const;794 795 SDValue796 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,797 const SmallVectorImpl<ISD::InputArg> &Ins,798 const SDLoc &dl, SelectionDAG &DAG,799 SmallVectorImpl<SDValue> &InVals) const override;800 801 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,802 SmallVectorImpl<SDValue> &InVals) const override;803 804 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,805 bool isVarArg,806 const SmallVectorImpl<ISD::OutputArg> &Outs,807 LLVMContext &Context, const Type *RetTy) const override;808 809 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,810 const SmallVectorImpl<ISD::OutputArg> &Outs,811 const SmallVectorImpl<SDValue> &OutVals,812 const SDLoc &dl, SelectionDAG &DAG) const override;813 814 SDValue extendArgForPPC64(ISD::ArgFlagsTy Flags, EVT ObjectVT,815 SelectionDAG &DAG, SDValue ArgVal,816 const SDLoc &dl) const;817 818 SDValue LowerFormalArguments_AIX(819 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,820 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,821 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;822 SDValue LowerFormalArguments_64SVR4(823 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,824 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,825 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;826 SDValue LowerFormalArguments_32SVR4(827 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,828 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,829 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;830 831 SDValue createMemcpyOutsideCallSeq(SDValue Arg, SDValue PtrOff,832 SDValue CallSeqStart,833 ISD::ArgFlagsTy Flags, SelectionDAG &DAG,834 const SDLoc &dl) const;835 836 SDValue LowerCall_64SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags,837 const SmallVectorImpl<ISD::OutputArg> &Outs,838 const SmallVectorImpl<SDValue> &OutVals,839 const SmallVectorImpl<ISD::InputArg> &Ins,840 const SDLoc &dl, SelectionDAG &DAG,841 SmallVectorImpl<SDValue> &InVals,842 const CallBase *CB) const;843 SDValue LowerCall_32SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags,844 const SmallVectorImpl<ISD::OutputArg> &Outs,845 const SmallVectorImpl<SDValue> &OutVals,846 const SmallVectorImpl<ISD::InputArg> &Ins,847 const SDLoc &dl, SelectionDAG &DAG,848 SmallVectorImpl<SDValue> &InVals,849 const CallBase *CB) const;850 SDValue LowerCall_AIX(SDValue Chain, SDValue Callee, CallFlags CFlags,851 const SmallVectorImpl<ISD::OutputArg> &Outs,852 const SmallVectorImpl<SDValue> &OutVals,853 const SmallVectorImpl<ISD::InputArg> &Ins,854 const SDLoc &dl, SelectionDAG &DAG,855 SmallVectorImpl<SDValue> &InVals,856 const CallBase *CB) const;857 858 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;859 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;860 SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const;861 862 SDValue DAGCombineExtBoolTrunc(SDNode *N, DAGCombinerInfo &DCI) const;863 SDValue DAGCombineBuildVector(SDNode *N, DAGCombinerInfo &DCI) const;864 SDValue DAGCombineTruncBoolExt(SDNode *N, DAGCombinerInfo &DCI) const;865 SDValue combineStoreFPToInt(SDNode *N, DAGCombinerInfo &DCI) const;866 SDValue combineFPToIntToFP(SDNode *N, DAGCombinerInfo &DCI) const;867 SDValue combineSHL(SDNode *N, DAGCombinerInfo &DCI) const;868 SDValue combineVectorShift(SDNode *N, DAGCombinerInfo &DCI) const;869 SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const;870 SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const;871 SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;872 SDValue combineADD(SDNode *N, DAGCombinerInfo &DCI) const;873 SDValue combineFMALike(SDNode *N, DAGCombinerInfo &DCI) const;874 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;875 SDValue combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const;876 SDValue combineVectorShuffle(ShuffleVectorSDNode *SVN,877 SelectionDAG &DAG) const;878 SDValue combineVReverseMemOP(ShuffleVectorSDNode *SVN, LSBaseSDNode *LSBase,879 DAGCombinerInfo &DCI) const;880 881 /// ConvertSETCCToSubtract - looks at SETCC that compares ints. It replaces882 /// SETCC with integer subtraction when (1) there is a legal way of doing it883 /// (2) keeping the result of comparison in GPR has performance benefit.884 SDValue ConvertSETCCToSubtract(SDNode *N, DAGCombinerInfo &DCI) const;885 886 SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,887 int &RefinementSteps, bool &UseOneConstNR,888 bool Reciprocal) const override;889 SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,890 int &RefinementSteps) const override;891 SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,892 const DenormalMode &Mode) const override;893 SDValue getSqrtResultForDenormInput(SDValue Operand,894 SelectionDAG &DAG) const override;895 unsigned combineRepeatedFPDivisors() const override;896 897 SDValue898 combineElementTruncationToVectorTruncation(SDNode *N,899 DAGCombinerInfo &DCI) const;900 901 SDValue combineBVLoadsSpecialValue(SDValue Operand,902 SelectionDAG &DAG) const;903 904 /// lowerToVINSERTH - Return the SDValue if this VECTOR_SHUFFLE can be905 /// handled by the VINSERTH instruction introduced in ISA 3.0. This is906 /// essentially any shuffle of v8i16 vectors that just inserts one element907 /// from one vector into the other.908 SDValue lowerToVINSERTH(ShuffleVectorSDNode *N, SelectionDAG &DAG) const;909 910 /// lowerToVINSERTB - Return the SDValue if this VECTOR_SHUFFLE can be911 /// handled by the VINSERTB instruction introduced in ISA 3.0. This is912 /// essentially v16i8 vector version of VINSERTH.913 SDValue lowerToVINSERTB(ShuffleVectorSDNode *N, SelectionDAG &DAG) const;914 915 /// lowerToXXSPLTI32DX - Return the SDValue if this VECTOR_SHUFFLE can be916 /// handled by the XXSPLTI32DX instruction introduced in ISA 3.1.917 SDValue lowerToXXSPLTI32DX(ShuffleVectorSDNode *N, SelectionDAG &DAG) const;918 919 // Return whether the call instruction can potentially be optimized to a920 // tail call. This will cause the optimizers to attempt to move, or921 // duplicate return instructions to help enable tail call optimizations.922 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;923 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;924 925 /// getAddrModeForFlags - Based on the set of address flags, select the most926 /// optimal instruction format to match by.927 PPC::AddrMode getAddrModeForFlags(unsigned Flags) const;928 929 /// computeMOFlags - Given a node N and it's Parent (a MemSDNode), compute930 /// the address flags of the load/store instruction that is to be matched.931 /// The address flags are stored in a map, which is then searched932 /// through to determine the optimal load/store instruction format.933 unsigned computeMOFlags(const SDNode *Parent, SDValue N,934 SelectionDAG &DAG) const;935 }; // end class PPCTargetLowering936 937 namespace PPC {938 939 FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,940 const TargetLibraryInfo *LibInfo);941 942 } // end namespace PPC943 944 bool isIntS16Immediate(SDNode *N, int16_t &Imm);945 bool isIntS16Immediate(SDValue Op, int16_t &Imm);946 bool isIntS34Immediate(SDNode *N, int64_t &Imm);947 bool isIntS34Immediate(SDValue Op, int64_t &Imm);948 949 bool convertToNonDenormSingle(APInt &ArgAPInt);950 bool convertToNonDenormSingle(APFloat &ArgAPFloat);951 bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat);952 953} // end namespace llvm954 955#endif // LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H956