1//===-- SystemZISelLowering.h - SystemZ 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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that SystemZ uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
15#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
16
17#include "SystemZ.h"
18#include "SystemZInstrInfo.h"
19#include "llvm/CodeGen/LibcallLoweringInfo.h"
20#include "llvm/CodeGen/MachineBasicBlock.h"
21#include "llvm/CodeGen/SelectionDAG.h"
22#include "llvm/CodeGen/TargetLowering.h"
23#include <optional>
24
25namespace llvm {
26
27namespace SystemZICMP {
28// Describes whether an integer comparison needs to be signed or unsigned,
29// or whether either type is OK.
30enum {
31 Any,
32 UnsignedOnly,
33 SignedOnly
34};
35} // end namespace SystemZICMP
36
37class SystemZSubtarget;
38
39class SystemZTargetLowering : public TargetLowering {
40public:
41 explicit SystemZTargetLowering(const TargetMachine &TM,
42 const SystemZSubtarget &STI);
43
44 bool useSoftFloat() const override;
45
46 // Override TargetLowering.
47 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
48 return MVT::i32;
49 }
50 unsigned getVectorIdxWidth(const DataLayout &DL) const override {
51 // Only the lower 12 bits of an element index are used, so we don't
52 // want to clobber the upper 32 bits of a GPR unnecessarily.
53 return 32;
54 }
55 TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT)
56 const override {
57 // Widen subvectors to the full width rather than promoting integer
58 // elements. This is better because:
59 //
60 // (a) it means that we can handle the ABI for passing and returning
61 // sub-128 vectors without having to handle them as legal types.
62 //
63 // (b) we don't have instructions to extend on load and truncate on store,
64 // so promoting the integers is less efficient.
65 //
66 // (c) there are no multiplication instructions for the widest integer
67 // type (v2i64).
68
69 // Expand (narrow) f16 vectors during type legalization to avoid
70 // operations for all elements as with expansion after widening.
71 if (VT.getScalarType() == MVT::f16)
72 return VT.getVectorElementCount().isScalar() ? TypeScalarizeVector
73 : TypeSplitVector;
74 if (VT.getScalarSizeInBits() % 8 == 0)
75 return TypeWidenVector;
76 return TargetLoweringBase::getPreferredVectorAction(VT);
77 }
78 unsigned
79 getNumRegisters(LLVMContext &Context, EVT VT,
80 std::optional<MVT> RegisterVT) const override {
81 // i128 inline assembly operand.
82 if (VT == MVT::i128 && RegisterVT && *RegisterVT == MVT::Untyped)
83 return 1;
84 return TargetLowering::getNumRegisters(Context, VT);
85 }
86 unsigned
87 getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC,
88 EVT VT, EVT &IntermediateVT,
89 unsigned &NumIntermediates,
90 MVT &RegisterVT) const override;
91 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
92 EVT VT) const override;
93 unsigned getNumRegistersForCallingConv(LLVMContext &Context,
94 CallingConv::ID CC,
95 EVT VT) const override;
96 bool isCheapToSpeculateCtlz(Type *) const override { return true; }
97 bool isCheapToSpeculateCttz(Type *) const override { return true; }
98 bool preferZeroCompareBranch() const override { return true; }
99 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override {
100 ConstantInt* Mask = dyn_cast<ConstantInt>(Val: AndI.getOperand(i: 1));
101 return Mask && Mask->getValue().isIntN(N: 16);
102 }
103 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
104 return VT.isScalarInteger();
105 }
106 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &,
107 EVT) const override;
108 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
109 EVT VT) const override;
110 bool isFPImmLegal(const APFloat &Imm, EVT VT,
111 bool ForCodeSize) const override;
112 bool ShouldShrinkFPConstant(EVT VT) const override {
113 // Do not shrink 64-bit FP constpool entries since LDEB is slower than
114 // LD, and having the full constant in memory enables reg/mem opcodes.
115 return VT != MVT::f64;
116 }
117 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
118 MachineBasicBlock *MBB) const;
119
120 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
121 MachineBasicBlock *MBB) const;
122
123 bool hasInlineStackProbe(const MachineFunction &MF) const override;
124 AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override;
125 AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override;
126 AtomicExpansionKind
127 shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override;
128 bool isLegalICmpImmediate(int64_t Imm) const override;
129 bool isLegalAddImmediate(int64_t Imm) const override;
130 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
131 unsigned AS,
132 Instruction *I = nullptr) const override;
133 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment,
134 MachineMemOperand::Flags Flags,
135 unsigned *Fast) const override;
136 bool findOptimalMemOpLowering(LLVMContext &Context, std::vector<EVT> &MemOps,
137 unsigned Limit, const MemOp &Op, unsigned DstAS,
138 unsigned SrcAS,
139 const AttributeList &FuncAttributes,
140 EVT *LargestVT = nullptr) const override;
141 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
142 const AttributeList &FuncAttributes) const override;
143 bool isTruncateFree(Type *, Type *) const override;
144 bool isTruncateFree(EVT, EVT) const override;
145
146 bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
147 bool MathUsed) const override {
148 // Form add and sub with overflow intrinsics regardless of any extra
149 // users of the math result.
150 return VT == MVT::i32 || VT == MVT::i64 || VT == MVT::i128;
151 }
152
153 bool shouldConsiderGEPOffsetSplit() const override { return true; }
154
155 bool preferSelectsOverBooleanArithmetic(EVT VT) const override {
156 return true;
157 }
158
159 bool isProfitableToCombineMinNumMaxNum(EVT VT) const override {
160 // We have instructions for pseudo min/max, no need to convert them to
161 // minnum/maxnum.
162 return false;
163 }
164
165 // This function currently returns cost for srl/ipm/cc sequence for merging.
166 CondMergingParams
167 getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs,
168 const Value *Rhs,
169 const Function *F) const override;
170
171 // Handle Lowering flag assembly outputs.
172 SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
173 const SDLoc &DL,
174 const AsmOperandInfo &Constraint,
175 SelectionDAG &DAG) const override;
176
177 std::pair<unsigned, const TargetRegisterClass *>
178 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
179 StringRef Constraint, MVT VT) const override;
180 TargetLowering::ConstraintType
181 getConstraintType(StringRef Constraint) const override;
182 TargetLowering::ConstraintWeight
183 getSingleConstraintMatchWeight(AsmOperandInfo &info,
184 const char *constraint) const override;
185 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
186 std::vector<SDValue> &Ops,
187 SelectionDAG &DAG) const override;
188
189 InlineAsm::ConstraintCode
190 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
191 if (ConstraintCode.size() == 1) {
192 switch(ConstraintCode[0]) {
193 default:
194 break;
195 case 'o':
196 return InlineAsm::ConstraintCode::o;
197 case 'Q':
198 return InlineAsm::ConstraintCode::Q;
199 case 'R':
200 return InlineAsm::ConstraintCode::R;
201 case 'S':
202 return InlineAsm::ConstraintCode::S;
203 case 'T':
204 return InlineAsm::ConstraintCode::T;
205 }
206 } else if (ConstraintCode.size() == 2 && ConstraintCode[0] == 'Z') {
207 switch (ConstraintCode[1]) {
208 default:
209 break;
210 case 'Q':
211 return InlineAsm::ConstraintCode::ZQ;
212 case 'R':
213 return InlineAsm::ConstraintCode::ZR;
214 case 'S':
215 return InlineAsm::ConstraintCode::ZS;
216 case 'T':
217 return InlineAsm::ConstraintCode::ZT;
218 }
219 }
220 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
221 }
222
223 Register getRegisterByName(const char *RegName, LLT VT,
224 const MachineFunction &MF) const override;
225
226 /// If a physical register, this returns the register that receives the
227 /// exception address on entry to an EH pad.
228 Register
229 getExceptionPointerRegister(ExceptionHandling EH,
230 const Constant *PersonalityFn) const override;
231
232 /// If a physical register, this returns the register that receives the
233 /// exception typeid on entry to a landing pad.
234 Register
235 getExceptionSelectorRegister(ExceptionHandling EH,
236 const Constant *PersonalityFn) const override;
237
238 /// Override to support customized stack guard loading.
239 bool useLoadStackGuardNode(const Module &M) const override { return true; }
240 /// Insert SSP declaration if global stack protector is used.
241 void
242 insertSSPDeclarations(Module &M,
243 const LibcallLoweringInfo &Libcalls) const override;
244 MachineBasicBlock *
245 EmitInstrWithCustomInserter(MachineInstr &MI,
246 MachineBasicBlock *BB) const override;
247 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
248 void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
249 SelectionDAG &DAG) const override;
250 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
251 SelectionDAG &DAG) const override;
252 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
253 bool allowTruncateForTailCall(Type *, Type *) const override;
254 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
255 bool splitValueIntoRegisterParts(
256 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
257 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
258 const override;
259 SDValue joinRegisterPartsIntoValue(
260 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
261 unsigned NumParts, MVT PartVT, EVT ValueVT,
262 std::optional<CallingConv::ID> CC) const override;
263 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
264 bool isVarArg,
265 const SmallVectorImpl<ISD::InputArg> &Ins,
266 const SDLoc &DL, SelectionDAG &DAG,
267 SmallVectorImpl<SDValue> &InVals) const override;
268 SDValue LowerCall(CallLoweringInfo &CLI,
269 SmallVectorImpl<SDValue> &InVals) const override;
270
271 std::pair<SDValue, SDValue>
272 makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName,
273 EVT RetVT, ArrayRef<SDValue> Ops, CallingConv::ID CallConv,
274 bool IsSigned, SDLoc DL, bool DoesNotReturn,
275 bool IsReturnValueUsed) const;
276
277 SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg,
278 SDLoc DL, SDValue Chain, bool IsStrict) const;
279
280 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
281 bool isVarArg,
282 const SmallVectorImpl<ISD::OutputArg> &Outs,
283 LLVMContext &Context,
284 const Type *RetTy) const override;
285 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
286 const SmallVectorImpl<ISD::OutputArg> &Outs,
287 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
288 SelectionDAG &DAG) const override;
289 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
290
291 /// Determine which of the bits specified in Mask are known to be either
292 /// zero or one and return them in the KnownZero/KnownOne bitsets.
293 void computeKnownBitsForTargetNode(const SDValue Op,
294 KnownBits &Known,
295 const APInt &DemandedElts,
296 const SelectionDAG &DAG,
297 unsigned Depth = 0) const override;
298
299 /// Determine the number of bits in the operation that are sign bits.
300 unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
301 const APInt &DemandedElts,
302 const SelectionDAG &DAG,
303 unsigned Depth) const override;
304
305 bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
306 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
307 UndefPoisonKind Kind, unsigned Depth) const override;
308
309 ISD::NodeType getExtendForAtomicOps() const override {
310 return ISD::ANY_EXTEND;
311 }
312 ISD::NodeType getExtendForAtomicCmpSwapArg() const override {
313 return ISD::ZERO_EXTEND;
314 }
315
316 bool supportSwiftError() const override {
317 return true;
318 }
319
320 unsigned getStackProbeSize(const MachineFunction &MF) const;
321 bool hasAndNot(SDValue Y) const override;
322
323private:
324 const SystemZSubtarget &Subtarget;
325
326 // Implement LowerOperation for individual opcodes.
327 SDValue getVectorCmp(SelectionDAG &DAG, unsigned Opcode,
328 const SDLoc &DL, EVT VT,
329 SDValue CmpOp0, SDValue CmpOp1, SDValue Chain) const;
330 SDValue lowerVectorSETCC(SelectionDAG &DAG, const SDLoc &DL,
331 EVT VT, ISD::CondCode CC,
332 SDValue CmpOp0, SDValue CmpOp1,
333 SDValue Chain = SDValue(),
334 bool IsSignaling = false) const;
335 SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
336 SDValue lowerSTRICT_FSETCC(SDValue Op, SelectionDAG &DAG,
337 bool IsSignaling) const;
338 SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
339 SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
340 SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
341 SelectionDAG &DAG) const;
342 SDValue lowerTLSGetOffset(GlobalAddressSDNode *Node,
343 SelectionDAG &DAG, unsigned Opcode,
344 SDValue GOTOffset) const;
345 SDValue lowerThreadPointer(const SDLoc &DL, SelectionDAG &DAG) const;
346 SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
347 SelectionDAG &DAG) const;
348 SDValue lowerBlockAddress(BlockAddressSDNode *Node,
349 SelectionDAG &DAG) const;
350 SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
351 SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
352 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
353 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
354 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
355 SDValue lowerVASTART_ELF(SDValue Op, SelectionDAG &DAG) const;
356 SDValue lowerVASTART_XPLINK(SDValue Op, SelectionDAG &DAG) const;
357 SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
358 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
359 SDValue lowerDYNAMIC_STACKALLOC_ELF(SDValue Op, SelectionDAG &DAG) const;
360 SDValue lowerDYNAMIC_STACKALLOC_XPLINK(SDValue Op, SelectionDAG &DAG) const;
361 SDValue lowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const;
362 SDValue lowerMULH(SDValue Op, SelectionDAG &DAG, unsigned Opcode) const;
363 SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
364 SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
365 SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
366 SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
367 SDValue lowerXALUO(SDValue Op, SelectionDAG &DAG) const;
368 SDValue lowerUADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;
369 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
370 SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
371 SDValue lowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
372 SDValue lowerVECREDUCE_ADD(SDValue Op, SelectionDAG &DAG) const;
373 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
374 SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
375 SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
376 SDValue lowerATOMIC_LDST_I128(SDValue Op, SelectionDAG &DAG) const;
377 SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
378 unsigned Opcode) const;
379 SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
380 SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
381 SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
382 SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
383 SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
384 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
385 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
386 bool isVectorElementLoad(SDValue Op) const;
387 SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
388 SmallVectorImpl<SDValue> &Elems) const;
389 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
390 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
391 SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;
392 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
393 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
394 SDValue lowerSIGN_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
395 SDValue lowerZERO_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
396 SDValue lowerShift(SDValue Op, SelectionDAG &DAG, unsigned ByScalar) const;
397 SDValue lowerFSHL(SDValue Op, SelectionDAG &DAG) const;
398 SDValue lowerFSHR(SDValue Op, SelectionDAG &DAG) const;
399 SDValue lowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
400 SDValue lower_FP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
401 SDValue lower_INT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
402 SDValue lowerLoadF16(SDValue Op, SelectionDAG &DAG) const;
403 SDValue lowerStoreF16(SDValue Op, SelectionDAG &DAG) const;
404
405 SDValue lowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
406 SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
407 SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
408
409 bool canTreatAsByteVector(EVT VT) const;
410 SDValue combineExtract(const SDLoc &DL, EVT ElemVT, EVT VecVT, SDValue OrigOp,
411 unsigned Index, DAGCombinerInfo &DCI,
412 bool Force) const;
413 SDValue combineTruncateExtract(const SDLoc &DL, EVT TruncVT, SDValue Op,
414 DAGCombinerInfo &DCI) const;
415 SDValue combineZERO_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
416 SDValue combineSIGN_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
417 SDValue combineSIGN_EXTEND_INREG(SDNode *N, DAGCombinerInfo &DCI) const;
418 SDValue combineMERGE(SDNode *N, DAGCombinerInfo &DCI) const;
419 bool canLoadStoreByteSwapped(EVT VT) const;
420 SDValue combineLOAD(SDNode *N, DAGCombinerInfo &DCI) const;
421 SDValue combineSTORE(SDNode *N, DAGCombinerInfo &DCI) const;
422 SDValue combineVECTOR_SHUFFLE(SDNode *N, DAGCombinerInfo &DCI) const;
423 SDValue combineEXTRACT_VECTOR_ELT(SDNode *N, DAGCombinerInfo &DCI) const;
424 SDValue combineJOIN_DWORDS(SDNode *N, DAGCombinerInfo &DCI) const;
425 SDValue combineFP_ROUND(SDNode *N, DAGCombinerInfo &DCI) const;
426 SDValue combineFP_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
427 SDValue combineINT_TO_FP(SDNode *N, DAGCombinerInfo &DCI) const;
428 SDValue combineFCOPYSIGN(SDNode *N, DAGCombinerInfo &DCI) const;
429 SDValue combineBSWAP(SDNode *N, DAGCombinerInfo &DCI) const;
430 SDValue combineSETCC(SDNode *N, DAGCombinerInfo &DCI) const;
431 SDValue combineBR_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
432 SDValue combineSELECT_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
433 SDValue combineGET_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
434 SDValue combineShiftToMulAddHigh(SDNode *N, DAGCombinerInfo &DCI) const;
435 SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;
436 SDValue combineIntDIVREM(SDNode *N, DAGCombinerInfo &DCI) const;
437 SDValue combineINTRINSIC(SDNode *N, DAGCombinerInfo &DCI) const;
438
439 SDValue unwrapAddress(SDValue N) const override;
440
441 // If the last instruction before MBBI in MBB was some form of COMPARE,
442 // try to replace it with a COMPARE AND BRANCH just before MBBI.
443 // CCMask and Target are the BRC-like operands for the branch.
444 // Return true if the change was made.
445 bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
446 MachineBasicBlock::iterator MBBI,
447 unsigned CCMask,
448 MachineBasicBlock *Target) const;
449
450 // Implement EmitInstrWithCustomInserter for individual operation types.
451 MachineBasicBlock *emitAdjCallStack(MachineInstr &MI,
452 MachineBasicBlock *BB) const;
453 MachineBasicBlock *emitSelect(MachineInstr &MI, MachineBasicBlock *BB) const;
454 MachineBasicBlock *emitCondStore(MachineInstr &MI, MachineBasicBlock *BB,
455 unsigned StoreOpcode, unsigned STOCOpcode,
456 bool Invert) const;
457 MachineBasicBlock *emitICmp128Hi(MachineInstr &MI, MachineBasicBlock *BB,
458 bool Unsigned) const;
459 MachineBasicBlock *emitPair128(MachineInstr &MI,
460 MachineBasicBlock *MBB) const;
461 MachineBasicBlock *emitExt128(MachineInstr &MI, MachineBasicBlock *MBB,
462 bool ClearEven) const;
463 MachineBasicBlock *emitAtomicLoadBinary(MachineInstr &MI,
464 MachineBasicBlock *BB,
465 unsigned BinOpcode,
466 bool Invert = false) const;
467 MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr &MI,
468 MachineBasicBlock *MBB,
469 unsigned CompareOpcode,
470 unsigned KeepOldMask) const;
471 MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr &MI,
472 MachineBasicBlock *BB) const;
473 MachineBasicBlock *emitMemMemWrapper(MachineInstr &MI, MachineBasicBlock *BB,
474 unsigned Opcode,
475 bool IsMemset = false) const;
476 MachineBasicBlock *emitMemmoveImm(MachineInstr &MI,
477 MachineBasicBlock *BB) const;
478 MachineBasicBlock *emitStringWrapper(MachineInstr &MI, MachineBasicBlock *BB,
479 unsigned Opcode) const;
480 MachineBasicBlock *emitTransactionBegin(MachineInstr &MI,
481 MachineBasicBlock *MBB,
482 unsigned Opcode, bool NoFloat) const;
483 MachineBasicBlock *emitLoadAndTestCmp0(MachineInstr &MI,
484 MachineBasicBlock *MBB,
485 unsigned Opcode) const;
486 MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,
487 MachineBasicBlock *MBB) const;
488 MachineBasicBlock *emitStackGuardPseudo(MachineInstr &MI,
489 MachineBasicBlock *MBB,
490 unsigned PseudoOp) const;
491 SDValue getBackchainAddress(SDValue SP, SelectionDAG &DAG) const;
492
493 MachineMemOperand::Flags
494 getTargetMMOFlags(const Instruction &I) const override;
495 const TargetRegisterClass *getRepRegClassFor(MVT VT) const override;
496
497private:
498 bool isInternal(const Function *Fn) const;
499 mutable std::map<const Function *, bool> IsInternalCache;
500 void verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
501 const Function *F, SDValue Callee) const;
502 void verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
503 const Function *F) const;
504 bool
505 verifyNarrowIntegerArgs(const SmallVectorImpl<ISD::OutputArg> &Outs) const;
506
507public:
508};
509
510struct SystemZVectorConstantInfo {
511private:
512 APInt IntBits; // The 128 bits as an integer.
513 APInt SplatBits; // Smallest splat value.
514 APInt SplatUndef; // Bits correspoding to undef operands of the BVN.
515 unsigned SplatBitSize = 0;
516 bool isFP128 = false;
517public:
518 unsigned Opcode = 0;
519 SmallVector<unsigned, 2> OpVals;
520 MVT VecVT;
521 SystemZVectorConstantInfo(APInt IntImm);
522 SystemZVectorConstantInfo(APFloat FPImm)
523 : SystemZVectorConstantInfo(FPImm.bitcastToAPInt()) {
524 isFP128 = (&FPImm.getSemantics() == &APFloat::IEEEquad());
525 }
526 SystemZVectorConstantInfo(BuildVectorSDNode *BVN);
527 bool isVectorConstantLegal(const SystemZSubtarget &Subtarget);
528};
529
530} // end namespace llvm
531
532#endif
533