brintos

brintos / llvm-project-archived public Read only

0
0
Text · 45.5 KiB · 74af055 Raw
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