| 1 | //===-- LegalizeTypes.h - DAG Type Legalizer class definition ---*- 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 DAGTypeLegalizer class. This is a private interface |
| 10 | // shared between the code that implements the SelectionDAG::LegalizeTypes |
| 11 | // method. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_LEGALIZETYPES_H |
| 16 | #define LLVM_LIB_CODEGEN_SELECTIONDAG_LEGALIZETYPES_H |
| 17 | |
| 18 | #include "MatchContext.h" |
| 19 | #include "llvm/ADT/DenseMap.h" |
| 20 | #include "llvm/CodeGen/SelectionDAG.h" |
| 21 | #include "llvm/CodeGen/TargetLowering.h" |
| 22 | #include "llvm/Support/Compiler.h" |
| 23 | |
| 24 | namespace llvm { |
| 25 | |
| 26 | //===----------------------------------------------------------------------===// |
| 27 | /// This takes an arbitrary SelectionDAG as input and hacks on it until only |
| 28 | /// value types the target machine can handle are left. This involves promoting |
| 29 | /// small sizes to large sizes or splitting up large values into small values. |
| 30 | /// |
| 31 | class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { |
| 32 | const TargetLowering &TLI; |
| 33 | SelectionDAG &DAG; |
| 34 | public: |
| 35 | /// This pass uses the NodeId on the SDNodes to hold information about the |
| 36 | /// state of the node. The enum has all the values. |
| 37 | enum NodeIdFlags { |
| 38 | /// All operands have been processed, so this node is ready to be handled. |
| 39 | ReadyToProcess = 0, |
| 40 | |
| 41 | /// This is a new node, not before seen, that was created in the process of |
| 42 | /// legalizing some other node. |
| 43 | NewNode = -1, |
| 44 | |
| 45 | /// This node's ID needs to be set to the number of its unprocessed |
| 46 | /// operands. |
| 47 | Unanalyzed = -2, |
| 48 | |
| 49 | /// This is a node that has already been processed. |
| 50 | Processed = -3 |
| 51 | |
| 52 | // 1+ - This is a node which has this many unprocessed operands. |
| 53 | }; |
| 54 | private: |
| 55 | |
| 56 | /// This is a bitvector that contains two bits for each simple value type, |
| 57 | /// where the two bits correspond to the LegalizeAction enum from |
| 58 | /// TargetLowering. This can be queried with "getTypeAction(VT)". |
| 59 | TargetLowering::ValueTypeActionImpl ValueTypeActions; |
| 60 | |
| 61 | /// Return how we should legalize values of this type. |
| 62 | TargetLowering::LegalizeTypeAction getTypeAction(EVT VT) const { |
| 63 | return TLI.getTypeAction(Context&: *DAG.getContext(), VT); |
| 64 | } |
| 65 | |
| 66 | /// Return true if this type is legal on this target. |
| 67 | bool isTypeLegal(EVT VT) const { |
| 68 | return TLI.getTypeAction(Context&: *DAG.getContext(), VT) == TargetLowering::TypeLegal; |
| 69 | } |
| 70 | |
| 71 | /// Return true if this is a simple legal type. |
| 72 | bool isSimpleLegalType(EVT VT) const { |
| 73 | return VT.isSimple() && TLI.isTypeLegal(VT); |
| 74 | } |
| 75 | |
| 76 | EVT getSetCCResultType(EVT VT) const { |
| 77 | return TLI.getSetCCResultType(DL: DAG.getDataLayout(), Context&: *DAG.getContext(), VT); |
| 78 | } |
| 79 | |
| 80 | /// Pretend all of this node's results are legal. |
| 81 | bool IgnoreNodeResults(SDNode *N) const { |
| 82 | return N->getOpcode() == ISD::TargetConstant || |
| 83 | N->getOpcode() == ISD::Register; |
| 84 | } |
| 85 | |
| 86 | // Bijection from SDValue to unique id. As each created node gets a |
| 87 | // new id we do not need to worry about reuse expunging. Should we |
| 88 | // run out of ids, we can do a one time expensive compactifcation. |
| 89 | typedef unsigned TableId; |
| 90 | |
| 91 | TableId NextValueId = 1; |
| 92 | |
| 93 | SmallDenseMap<SDValue, TableId, 8> ValueToIdMap; |
| 94 | SmallDenseMap<TableId, SDValue, 8> IdToValueMap; |
| 95 | |
| 96 | /// For integer nodes that are below legal width, this map indicates what |
| 97 | /// promoted value to use. |
| 98 | SmallDenseMap<TableId, TableId, 8> PromotedIntegers; |
| 99 | |
| 100 | /// For integer nodes that need to be expanded this map indicates which |
| 101 | /// operands are the expanded version of the input. |
| 102 | SmallDenseMap<TableId, std::pair<TableId, TableId>, 8> ExpandedIntegers; |
| 103 | |
| 104 | /// For floating-point nodes converted to integers of the same size, this map |
| 105 | /// indicates the converted value to use. |
| 106 | SmallDenseMap<TableId, TableId, 8> SoftenedFloats; |
| 107 | |
| 108 | /// For floating-point nodes that have a smaller precision than the smallest |
| 109 | /// supported precision, this map indicates what promoted value to use. |
| 110 | SmallDenseMap<TableId, TableId, 8> PromotedFloats; |
| 111 | |
| 112 | /// For floating-point nodes that have a smaller precision than the smallest |
| 113 | /// supported precision, this map indicates the converted value to use. |
| 114 | SmallDenseMap<TableId, TableId, 8> SoftPromotedHalfs; |
| 115 | |
| 116 | /// For float nodes that need to be expanded this map indicates which operands |
| 117 | /// are the expanded version of the input. |
| 118 | SmallDenseMap<TableId, std::pair<TableId, TableId>, 8> ExpandedFloats; |
| 119 | |
| 120 | /// For nodes that are <1 x ty>, this map indicates the scalar value of type |
| 121 | /// 'ty' to use. |
| 122 | SmallDenseMap<TableId, TableId, 8> ScalarizedVectors; |
| 123 | |
| 124 | /// For nodes that need to be split this map indicates which operands are the |
| 125 | /// expanded version of the input. |
| 126 | SmallDenseMap<TableId, std::pair<TableId, TableId>, 8> SplitVectors; |
| 127 | |
| 128 | /// For vector nodes that need to be widened, indicates the widened value to |
| 129 | /// use. |
| 130 | SmallDenseMap<TableId, TableId, 8> WidenedVectors; |
| 131 | |
| 132 | /// For values that have been replaced with another, indicates the replacement |
| 133 | /// value to use. |
| 134 | SmallDenseMap<TableId, TableId, 8> ReplacedValues; |
| 135 | |
| 136 | /// This defines a worklist of nodes to process. In order to be pushed onto |
| 137 | /// this worklist, all operands of a node must have already been processed. |
| 138 | SmallVector<SDNode*, 128> Worklist; |
| 139 | |
| 140 | TableId getTableId(SDValue V) { |
| 141 | assert(V.getNode() && "Getting TableId on SDValue()" ); |
| 142 | |
| 143 | auto I = ValueToIdMap.find(Val: V); |
| 144 | if (I != ValueToIdMap.end()) { |
| 145 | // replace if there's been a shift. |
| 146 | RemapId(Id&: I->second); |
| 147 | assert(I->second && "All Ids should be nonzero" ); |
| 148 | return I->second; |
| 149 | } |
| 150 | // Add if it's not there. |
| 151 | ValueToIdMap.insert(KV: std::make_pair(x&: V, y&: NextValueId)); |
| 152 | IdToValueMap.insert(KV: std::make_pair(x&: NextValueId, y&: V)); |
| 153 | ++NextValueId; |
| 154 | assert(NextValueId != 0 && |
| 155 | "Ran out of Ids. Increase id type size or add compactification" ); |
| 156 | return NextValueId - 1; |
| 157 | } |
| 158 | |
| 159 | const SDValue &getSDValue(TableId &Id) { |
| 160 | RemapId(Id); |
| 161 | assert(Id && "TableId should be non-zero" ); |
| 162 | auto I = IdToValueMap.find(Val: Id); |
| 163 | assert(I != IdToValueMap.end() && "cannot find Id in map" ); |
| 164 | return I->second; |
| 165 | } |
| 166 | |
| 167 | public: |
| 168 | explicit DAGTypeLegalizer(SelectionDAG &dag) |
| 169 | : TLI(dag.getTargetLoweringInfo()), DAG(dag), |
| 170 | ValueTypeActions(TLI.getValueTypeActions()) { |
| 171 | } |
| 172 | |
| 173 | /// This is the main entry point for the type legalizer. This does a |
| 174 | /// top-down traversal of the dag, legalizing types as it goes. Returns |
| 175 | /// "true" if it made any changes. |
| 176 | bool run(); |
| 177 | |
| 178 | void NoteDeletion(SDNode *Old, SDNode *New) { |
| 179 | assert(Old != New && "node replaced with self" ); |
| 180 | for (unsigned i = 0, e = Old->getNumValues(); i != e; ++i) { |
| 181 | TableId NewId = getTableId(V: SDValue(New, i)); |
| 182 | TableId OldId = getTableId(V: SDValue(Old, i)); |
| 183 | |
| 184 | if (OldId != NewId) { |
| 185 | ReplacedValues[OldId] = NewId; |
| 186 | |
| 187 | // Delete Node from tables. We cannot do this when OldId == NewId, |
| 188 | // because NewId can still have table references to it in |
| 189 | // ReplacedValues. |
| 190 | IdToValueMap.erase(Val: OldId); |
| 191 | PromotedIntegers.erase(Val: OldId); |
| 192 | ExpandedIntegers.erase(Val: OldId); |
| 193 | SoftenedFloats.erase(Val: OldId); |
| 194 | PromotedFloats.erase(Val: OldId); |
| 195 | SoftPromotedHalfs.erase(Val: OldId); |
| 196 | ExpandedFloats.erase(Val: OldId); |
| 197 | ScalarizedVectors.erase(Val: OldId); |
| 198 | SplitVectors.erase(Val: OldId); |
| 199 | WidenedVectors.erase(Val: OldId); |
| 200 | } |
| 201 | |
| 202 | ValueToIdMap.erase(Val: SDValue(Old, i)); |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | SelectionDAG &getDAG() const { return DAG; } |
| 207 | |
| 208 | private: |
| 209 | SDNode *AnalyzeNewNode(SDNode *N); |
| 210 | void AnalyzeNewValue(SDValue &Val); |
| 211 | void PerformExpensiveChecks(); |
| 212 | void RemapId(TableId &Id); |
| 213 | void RemapValue(SDValue &V); |
| 214 | |
| 215 | // Common routines. |
| 216 | SDValue BitConvertToInteger(SDValue Op); |
| 217 | SDValue BitConvertVectorToIntegerVector(SDValue Op); |
| 218 | SDValue CreateStackStoreLoad(SDValue Op, EVT DestVT); |
| 219 | bool CustomLowerNode(SDNode *N, EVT VT, bool LegalizeResult); |
| 220 | bool CustomWidenLowerNode(SDNode *N, EVT VT); |
| 221 | |
| 222 | /// Replace each result of the given MERGE_VALUES node with the corresponding |
| 223 | /// input operand, except for the result 'ResNo', for which the corresponding |
| 224 | /// input operand is returned. |
| 225 | SDValue DisintegrateMERGE_VALUES(SDNode *N, unsigned ResNo); |
| 226 | |
| 227 | SDValue JoinIntegers(SDValue Lo, SDValue Hi); |
| 228 | |
| 229 | std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node); |
| 230 | |
| 231 | SDValue PromoteTargetBoolean(SDValue Bool, EVT ValVT); |
| 232 | |
| 233 | void ReplaceValueWith(SDValue From, SDValue To); |
| 234 | void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi); |
| 235 | void SplitInteger(SDValue Op, EVT LoVT, EVT HiVT, |
| 236 | SDValue &Lo, SDValue &Hi); |
| 237 | |
| 238 | //===--------------------------------------------------------------------===// |
| 239 | // Integer Promotion Support: LegalizeIntegerTypes.cpp |
| 240 | //===--------------------------------------------------------------------===// |
| 241 | |
| 242 | /// Given a processed operand Op which was promoted to a larger integer type, |
| 243 | /// this returns the promoted value. The low bits of the promoted value |
| 244 | /// corresponding to the original type are exactly equal to Op. |
| 245 | /// The extra bits contain rubbish, so the promoted value may need to be zero- |
| 246 | /// or sign-extended from the original type before it is usable (the helpers |
| 247 | /// SExtPromotedInteger and ZExtPromotedInteger can do this for you). |
| 248 | /// For example, if Op is an i16 and was promoted to an i32, then this method |
| 249 | /// returns an i32, the lower 16 bits of which coincide with Op, and the upper |
| 250 | /// 16 bits of which contain rubbish. |
| 251 | SDValue GetPromotedInteger(SDValue Op) { |
| 252 | TableId &PromotedId = PromotedIntegers[getTableId(V: Op)]; |
| 253 | SDValue PromotedOp = getSDValue(Id&: PromotedId); |
| 254 | assert(PromotedOp.getNode() && "Operand wasn't promoted?" ); |
| 255 | return PromotedOp; |
| 256 | } |
| 257 | void SetPromotedInteger(SDValue Op, SDValue Result); |
| 258 | |
| 259 | /// Get a promoted operand and sign extend it to the final size. |
| 260 | SDValue SExtPromotedInteger(SDValue Op) { |
| 261 | EVT OldVT = Op.getValueType(); |
| 262 | SDLoc dl(Op); |
| 263 | Op = GetPromotedInteger(Op); |
| 264 | return DAG.getNode(Opcode: ISD::SIGN_EXTEND_INREG, DL: dl, VT: Op.getValueType(), N1: Op, |
| 265 | N2: DAG.getValueType(OldVT)); |
| 266 | } |
| 267 | |
| 268 | /// Get a promoted operand and zero extend it to the final size. |
| 269 | SDValue ZExtPromotedInteger(SDValue Op) { |
| 270 | EVT OldVT = Op.getValueType(); |
| 271 | SDLoc dl(Op); |
| 272 | Op = GetPromotedInteger(Op); |
| 273 | return DAG.getZeroExtendInReg(Op, DL: dl, VT: OldVT); |
| 274 | } |
| 275 | |
| 276 | /// Get a promoted operand and zero extend it to the final size. |
| 277 | SDValue VPSExtPromotedInteger(SDValue Op, SDValue Mask, SDValue EVL) { |
| 278 | EVT OldVT = Op.getValueType(); |
| 279 | SDLoc dl(Op); |
| 280 | Op = GetPromotedInteger(Op); |
| 281 | // FIXME: Add VP_SIGN_EXTEND_INREG. |
| 282 | EVT VT = Op.getValueType(); |
| 283 | unsigned BitsDiff = VT.getScalarSizeInBits() - OldVT.getScalarSizeInBits(); |
| 284 | SDValue ShiftCst = DAG.getShiftAmountConstant(Val: BitsDiff, VT, DL: dl); |
| 285 | SDValue Shl = DAG.getNode(Opcode: ISD::VP_SHL, DL: dl, VT, N1: Op, N2: ShiftCst, N3: Mask, N4: EVL); |
| 286 | return DAG.getNode(Opcode: ISD::VP_SRA, DL: dl, VT, N1: Shl, N2: ShiftCst, N3: Mask, N4: EVL); |
| 287 | } |
| 288 | |
| 289 | /// Get a promoted operand and zero extend it to the final size. |
| 290 | SDValue VPZExtPromotedInteger(SDValue Op, SDValue Mask, SDValue EVL) { |
| 291 | EVT OldVT = Op.getValueType(); |
| 292 | SDLoc dl(Op); |
| 293 | Op = GetPromotedInteger(Op); |
| 294 | return DAG.getVPZeroExtendInReg(Op, Mask, EVL, DL: dl, VT: OldVT); |
| 295 | } |
| 296 | |
| 297 | // Promote the given operand V (vector or scalar) according to N's specific |
| 298 | // reduction kind. N must be an integer VECREDUCE_* or VP_REDUCE_*. Returns |
| 299 | // the nominal extension opcode (ISD::(ANY|ZERO|SIGN)_EXTEND) and the |
| 300 | // promoted value. |
| 301 | SDValue PromoteIntOpVectorReduction(SDNode *N, SDValue V); |
| 302 | |
| 303 | // Integer Result Promotion. |
| 304 | void PromoteIntegerResult(SDNode *N, unsigned ResNo); |
| 305 | SDValue PromoteIntRes_MERGE_VALUES(SDNode *N, unsigned ResNo); |
| 306 | SDValue PromoteIntRes_AssertSext(SDNode *N); |
| 307 | SDValue PromoteIntRes_AssertZext(SDNode *N); |
| 308 | SDValue PromoteIntRes_Atomic0(AtomicSDNode *N); |
| 309 | SDValue PromoteIntRes_Atomic1(AtomicSDNode *N); |
| 310 | SDValue PromoteIntRes_AtomicCmpSwap(AtomicSDNode *N, unsigned ResNo); |
| 311 | SDValue (SDNode *N); |
| 312 | SDValue PromoteIntRes_INSERT_SUBVECTOR(SDNode *N); |
| 313 | SDValue PromoteIntRes_VECTOR_REVERSE(SDNode *N); |
| 314 | SDValue PromoteIntRes_VECTOR_SHUFFLE(SDNode *N); |
| 315 | SDValue PromoteIntRes_VECTOR_SPLICE(SDNode *N); |
| 316 | SDValue PromoteIntRes_VECTOR_INTERLEAVE_DEINTERLEAVE(SDNode *N); |
| 317 | SDValue PromoteIntRes_BUILD_VECTOR(SDNode *N); |
| 318 | SDValue PromoteIntRes_ScalarOp(SDNode *N); |
| 319 | SDValue PromoteIntRes_STEP_VECTOR(SDNode *N); |
| 320 | SDValue PromoteIntRes_EXTEND_VECTOR_INREG(SDNode *N); |
| 321 | SDValue PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N); |
| 322 | SDValue PromoteIntRes_CONCAT_VECTORS(SDNode *N); |
| 323 | SDValue PromoteIntRes_BITCAST(SDNode *N); |
| 324 | SDValue PromoteIntRes_BSWAP(SDNode *N); |
| 325 | SDValue PromoteIntRes_BITREVERSE(SDNode *N); |
| 326 | SDValue PromoteIntRes_BUILD_PAIR(SDNode *N); |
| 327 | SDValue PromoteIntRes_Constant(SDNode *N); |
| 328 | SDValue PromoteIntRes_CTLZ(SDNode *N); |
| 329 | SDValue PromoteIntRes_CTPOP_PARITY(SDNode *N); |
| 330 | SDValue PromoteIntRes_CTTZ(SDNode *N); |
| 331 | SDValue PromoteIntRes_VP_CttzElements(SDNode *N); |
| 332 | SDValue (SDNode *N); |
| 333 | SDValue PromoteIntRes_FP_TO_XINT(SDNode *N); |
| 334 | SDValue PromoteIntRes_FP_TO_XINT_SAT(SDNode *N); |
| 335 | SDValue PromoteIntRes_FP_TO_FP16_BF16(SDNode *N); |
| 336 | SDValue PromoteIntRes_STRICT_FP_TO_FP16_BF16(SDNode *N); |
| 337 | SDValue PromoteIntRes_XRINT(SDNode *N); |
| 338 | SDValue PromoteIntRes_FREEZE(SDNode *N); |
| 339 | SDValue PromoteIntRes_INT_EXTEND(SDNode *N); |
| 340 | SDValue PromoteIntRes_LOAD(LoadSDNode *N); |
| 341 | SDValue PromoteIntRes_VP_LOAD(VPLoadSDNode *N); |
| 342 | SDValue PromoteIntRes_MLOAD(MaskedLoadSDNode *N); |
| 343 | SDValue PromoteIntRes_MGATHER(MaskedGatherSDNode *N); |
| 344 | SDValue PromoteIntRes_VECTOR_COMPRESS(SDNode *N); |
| 345 | SDValue PromoteIntRes_Overflow(SDNode *N); |
| 346 | SDValue PromoteIntRes_FFREXP(SDNode *N); |
| 347 | SDValue PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo); |
| 348 | SDValue PromoteIntRes_CMP(SDNode *N); |
| 349 | SDValue PromoteIntRes_Select(SDNode *N); |
| 350 | SDValue PromoteIntRes_SELECT_CC(SDNode *N); |
| 351 | SDValue PromoteIntRes_SETCC(SDNode *N); |
| 352 | SDValue PromoteIntRes_SHL(SDNode *N); |
| 353 | SDValue PromoteIntRes_SimpleIntBinOp(SDNode *N); |
| 354 | SDValue PromoteIntRes_ZExtIntBinOp(SDNode *N); |
| 355 | SDValue PromoteIntRes_SExtIntBinOp(SDNode *N); |
| 356 | SDValue PromoteIntRes_UMINUMAX(SDNode *N); |
| 357 | SDValue PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N); |
| 358 | SDValue PromoteIntRes_SRA(SDNode *N); |
| 359 | SDValue PromoteIntRes_SRL(SDNode *N); |
| 360 | SDValue PromoteIntRes_TRUNCATE(SDNode *N); |
| 361 | SDValue PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo); |
| 362 | SDValue PromoteIntRes_UADDSUBO_CARRY(SDNode *N, unsigned ResNo); |
| 363 | SDValue PromoteIntRes_SADDSUBO_CARRY(SDNode *N, unsigned ResNo); |
| 364 | SDValue PromoteIntRes_UNDEF(SDNode *N); |
| 365 | SDValue PromoteIntRes_VAARG(SDNode *N); |
| 366 | SDValue PromoteIntRes_VSCALE(SDNode *N); |
| 367 | SDValue PromoteIntRes_XMULO(SDNode *N, unsigned ResNo); |
| 368 | template <class MatchContextClass> |
| 369 | SDValue PromoteIntRes_ADDSUBSHLSAT(SDNode *N); |
| 370 | SDValue PromoteIntRes_MULFIX(SDNode *N); |
| 371 | SDValue PromoteIntRes_DIVFIX(SDNode *N); |
| 372 | SDValue PromoteIntRes_GET_ROUNDING(SDNode *N); |
| 373 | SDValue PromoteIntRes_VECREDUCE(SDNode *N); |
| 374 | SDValue PromoteIntRes_VP_REDUCE(SDNode *N); |
| 375 | SDValue PromoteIntRes_ABS(SDNode *N); |
| 376 | SDValue PromoteIntRes_Rotate(SDNode *N); |
| 377 | SDValue PromoteIntRes_FunnelShift(SDNode *N); |
| 378 | SDValue PromoteIntRes_VPFunnelShift(SDNode *N); |
| 379 | SDValue PromoteIntRes_IS_FPCLASS(SDNode *N); |
| 380 | SDValue PromoteIntRes_PATCHPOINT(SDNode *N); |
| 381 | SDValue PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(SDNode *N); |
| 382 | SDValue PromoteIntRes_GET_ACTIVE_LANE_MASK(SDNode *N); |
| 383 | SDValue PromoteIntRes_PARTIAL_REDUCE_MLA(SDNode *N); |
| 384 | |
| 385 | // Integer Operand Promotion. |
| 386 | bool PromoteIntegerOperand(SDNode *N, unsigned OpNo); |
| 387 | SDValue PromoteIntOp_ANY_EXTEND(SDNode *N); |
| 388 | SDValue PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N); |
| 389 | SDValue PromoteIntOp_BITCAST(SDNode *N); |
| 390 | SDValue PromoteIntOp_BUILD_PAIR(SDNode *N); |
| 391 | SDValue PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo); |
| 392 | SDValue PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo); |
| 393 | SDValue PromoteIntOp_BUILD_VECTOR(SDNode *N); |
| 394 | SDValue PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo); |
| 395 | SDValue (SDNode *N); |
| 396 | SDValue (SDNode *N); |
| 397 | SDValue PromoteIntOp_INSERT_SUBVECTOR(SDNode *N); |
| 398 | SDValue PromoteIntOp_FAKE_USE(SDNode *N); |
| 399 | SDValue PromoteIntOp_CONCAT_VECTORS(SDNode *N); |
| 400 | SDValue PromoteIntOp_ScalarOp(SDNode *N); |
| 401 | SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo); |
| 402 | SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo); |
| 403 | SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo); |
| 404 | SDValue PromoteIntOp_Shift(SDNode *N); |
| 405 | SDValue PromoteIntOp_CMP(SDNode *N); |
| 406 | SDValue PromoteIntOp_FunnelShift(SDNode *N); |
| 407 | SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N); |
| 408 | SDValue PromoteIntOp_VP_SIGN_EXTEND(SDNode *N); |
| 409 | SDValue PromoteIntOp_SINT_TO_FP(SDNode *N); |
| 410 | SDValue PromoteIntOp_STRICT_SINT_TO_FP(SDNode *N); |
| 411 | SDValue PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo); |
| 412 | SDValue PromoteIntOp_TRUNCATE(SDNode *N); |
| 413 | SDValue PromoteIntOp_UINT_TO_FP(SDNode *N); |
| 414 | SDValue PromoteIntOp_STRICT_UINT_TO_FP(SDNode *N); |
| 415 | SDValue PromoteIntOp_ZERO_EXTEND(SDNode *N); |
| 416 | SDValue PromoteIntOp_VP_ZERO_EXTEND(SDNode *N); |
| 417 | SDValue PromoteIntOp_MSTORE(MaskedStoreSDNode *N, unsigned OpNo); |
| 418 | SDValue PromoteIntOp_MLOAD(MaskedLoadSDNode *N, unsigned OpNo); |
| 419 | SDValue PromoteIntOp_MSCATTER(MaskedScatterSDNode *N, unsigned OpNo); |
| 420 | SDValue PromoteIntOp_MGATHER(MaskedGatherSDNode *N, unsigned OpNo); |
| 421 | SDValue PromoteIntOp_VECTOR_COMPRESS(SDNode *N, unsigned OpNo); |
| 422 | SDValue PromoteIntOp_FRAMERETURNADDR(SDNode *N); |
| 423 | SDValue PromoteIntOp_FIX(SDNode *N); |
| 424 | SDValue PromoteIntOp_ExpOp(SDNode *N); |
| 425 | SDValue PromoteIntOp_VECREDUCE(SDNode *N); |
| 426 | SDValue PromoteIntOp_VP_REDUCE(SDNode *N, unsigned OpNo); |
| 427 | SDValue PromoteIntOp_VP_STORE(VPStoreSDNode *N, unsigned OpNo); |
| 428 | SDValue PromoteIntOp_SET_ROUNDING(SDNode *N); |
| 429 | SDValue PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo); |
| 430 | SDValue PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo); |
| 431 | SDValue PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo); |
| 432 | SDValue PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo); |
| 433 | SDValue PromoteIntOp_VECTOR_HISTOGRAM(SDNode *N, unsigned OpNo); |
| 434 | SDValue PromoteIntOp_VECTOR_FIND_LAST_ACTIVE(SDNode *N, unsigned OpNo); |
| 435 | SDValue PromoteIntOp_GET_ACTIVE_LANE_MASK(SDNode *N); |
| 436 | SDValue PromoteIntOp_PARTIAL_REDUCE_MLA(SDNode *N); |
| 437 | |
| 438 | void SExtOrZExtPromotedOperands(SDValue &LHS, SDValue &RHS); |
| 439 | void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code); |
| 440 | |
| 441 | //===--------------------------------------------------------------------===// |
| 442 | // Integer Expansion Support: LegalizeIntegerTypes.cpp |
| 443 | //===--------------------------------------------------------------------===// |
| 444 | |
| 445 | /// Given a processed operand Op which was expanded into two integers of half |
| 446 | /// the size, this returns the two halves. The low bits of Op are exactly |
| 447 | /// equal to the bits of Lo; the high bits exactly equal Hi. |
| 448 | /// For example, if Op is an i64 which was expanded into two i32's, then this |
| 449 | /// method returns the two i32's, with Lo being equal to the lower 32 bits of |
| 450 | /// Op, and Hi being equal to the upper 32 bits. |
| 451 | void GetExpandedInteger(SDValue Op, SDValue &Lo, SDValue &Hi); |
| 452 | void SetExpandedInteger(SDValue Op, SDValue Lo, SDValue Hi); |
| 453 | |
| 454 | // Integer Result Expansion. |
| 455 | void ExpandIntegerResult(SDNode *N, unsigned ResNo); |
| 456 | void ExpandIntRes_ANY_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 457 | void ExpandIntRes_AssertSext (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 458 | void ExpandIntRes_AssertZext (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 459 | void ExpandIntRes_Constant (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 460 | void ExpandIntRes_ABS (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 461 | void ExpandIntRes_ABD (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 462 | void ExpandIntRes_CTLZ (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 463 | void ExpandIntRes_CTPOP (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 464 | void ExpandIntRes_CTTZ (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 465 | void ExpandIntRes_LOAD (LoadSDNode *N, SDValue &Lo, SDValue &Hi); |
| 466 | void ExpandIntRes_READCOUNTER (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 467 | void ExpandIntRes_SIGN_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 468 | void ExpandIntRes_SIGN_EXTEND_INREG (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 469 | void ExpandIntRes_TRUNCATE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 470 | void ExpandIntRes_ZERO_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 471 | void ExpandIntRes_GET_ROUNDING (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 472 | void ExpandIntRes_FP_TO_XINT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 473 | void ExpandIntRes_FP_TO_XINT_SAT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 474 | void ExpandIntRes_XROUND_XRINT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 475 | |
| 476 | void ExpandIntRes_Logical (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 477 | void ExpandIntRes_ADDSUB (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 478 | void ExpandIntRes_ADDSUBC (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 479 | void ExpandIntRes_ADDSUBE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 480 | void ExpandIntRes_UADDSUBO_CARRY (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 481 | void ExpandIntRes_SADDSUBO_CARRY (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 482 | void ExpandIntRes_BITREVERSE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 483 | void ExpandIntRes_BSWAP (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 484 | void ExpandIntRes_PARITY (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 485 | void ExpandIntRes_MUL (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 486 | void ExpandIntRes_SDIV (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 487 | void ExpandIntRes_SREM (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 488 | void ExpandIntRes_UDIV (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 489 | void ExpandIntRes_UREM (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 490 | void ExpandIntRes_ShiftThroughStack (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 491 | void ExpandIntRes_Shift (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 492 | |
| 493 | void ExpandIntRes_MINMAX (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 494 | |
| 495 | void ExpandIntRes_CMP (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 496 | void ExpandIntRes_SETCC (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 497 | |
| 498 | void ExpandIntRes_SADDSUBO (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 499 | void ExpandIntRes_UADDSUBO (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 500 | void ExpandIntRes_XMULO (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 501 | void ExpandIntRes_AVG (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 502 | void ExpandIntRes_ADDSUBSAT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 503 | void ExpandIntRes_SHLSAT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 504 | void ExpandIntRes_MULFIX (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 505 | void ExpandIntRes_DIVFIX (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 506 | |
| 507 | void ExpandIntRes_ATOMIC_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 508 | void ExpandIntRes_VECREDUCE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 509 | |
| 510 | void ExpandIntRes_Rotate (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 511 | void ExpandIntRes_FunnelShift (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 512 | |
| 513 | void ExpandIntRes_VSCALE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 514 | |
| 515 | void ExpandShiftByConstant(SDNode *N, const APInt &Amt, |
| 516 | SDValue &Lo, SDValue &Hi); |
| 517 | bool ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 518 | bool ExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 519 | |
| 520 | // Integer Operand Expansion. |
| 521 | bool ExpandIntegerOperand(SDNode *N, unsigned OpNo); |
| 522 | SDValue ExpandIntOp_BR_CC(SDNode *N); |
| 523 | SDValue ExpandIntOp_SELECT_CC(SDNode *N); |
| 524 | SDValue ExpandIntOp_SETCC(SDNode *N); |
| 525 | SDValue ExpandIntOp_SETCCCARRY(SDNode *N); |
| 526 | SDValue ExpandIntOp_Shift(SDNode *N); |
| 527 | SDValue ExpandIntOp_CMP(SDNode *N); |
| 528 | SDValue ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo); |
| 529 | SDValue ExpandIntOp_TRUNCATE(SDNode *N); |
| 530 | SDValue ExpandIntOp_XINT_TO_FP(SDNode *N); |
| 531 | SDValue ExpandIntOp_RETURNADDR(SDNode *N); |
| 532 | SDValue ExpandIntOp_ATOMIC_STORE(SDNode *N); |
| 533 | SDValue ExpandIntOp_SPLAT_VECTOR(SDNode *N); |
| 534 | SDValue ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo); |
| 535 | SDValue ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo); |
| 536 | SDValue ExpandIntOp_VP_STRIDED(SDNode *N, unsigned OpNo); |
| 537 | |
| 538 | void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, |
| 539 | ISD::CondCode &CCCode, const SDLoc &dl); |
| 540 | |
| 541 | //===--------------------------------------------------------------------===// |
| 542 | // Float to Integer Conversion Support: LegalizeFloatTypes.cpp |
| 543 | //===--------------------------------------------------------------------===// |
| 544 | |
| 545 | /// GetSoftenedFloat - Given a processed operand Op which was converted to an |
| 546 | /// integer of the same size, this returns the integer. The integer contains |
| 547 | /// exactly the same bits as Op - only the type changed. For example, if Op |
| 548 | /// is an f32 which was softened to an i32, then this method returns an i32, |
| 549 | /// the bits of which coincide with those of Op |
| 550 | SDValue GetSoftenedFloat(SDValue Op) { |
| 551 | TableId Id = getTableId(V: Op); |
| 552 | auto Iter = SoftenedFloats.find(Val: Id); |
| 553 | if (Iter == SoftenedFloats.end()) { |
| 554 | assert(isSimpleLegalType(Op.getValueType()) && |
| 555 | "Operand wasn't converted to integer?" ); |
| 556 | return Op; |
| 557 | } |
| 558 | SDValue SoftenedOp = getSDValue(Id&: Iter->second); |
| 559 | assert(SoftenedOp.getNode() && "Unconverted op in SoftenedFloats?" ); |
| 560 | return SoftenedOp; |
| 561 | } |
| 562 | void SetSoftenedFloat(SDValue Op, SDValue Result); |
| 563 | |
| 564 | // Convert Float Results to Integer. |
| 565 | void SoftenFloatResult(SDNode *N, unsigned ResNo); |
| 566 | SDValue SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC); |
| 567 | SDValue SoftenFloatRes_UnaryWithTwoFPResults( |
| 568 | SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo = {}); |
| 569 | SDValue SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC); |
| 570 | SDValue SoftenFloatRes_MERGE_VALUES(SDNode *N, unsigned ResNo); |
| 571 | SDValue SoftenFloatRes_ARITH_FENCE(SDNode *N); |
| 572 | SDValue SoftenFloatRes_BITCAST(SDNode *N); |
| 573 | SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N); |
| 574 | SDValue SoftenFloatRes_ConstantFP(SDNode *N); |
| 575 | SDValue (SDNode *N); |
| 576 | SDValue (SDNode *N, unsigned ResNo); |
| 577 | SDValue SoftenFloatRes_FABS(SDNode *N); |
| 578 | SDValue SoftenFloatRes_FACOS(SDNode *N); |
| 579 | SDValue SoftenFloatRes_FASIN(SDNode *N); |
| 580 | SDValue SoftenFloatRes_FATAN(SDNode *N); |
| 581 | SDValue SoftenFloatRes_FATAN2(SDNode *N); |
| 582 | SDValue SoftenFloatRes_FMINNUM(SDNode *N); |
| 583 | SDValue SoftenFloatRes_FMAXNUM(SDNode *N); |
| 584 | SDValue SoftenFloatRes_FMINIMUMNUM(SDNode *N); |
| 585 | SDValue SoftenFloatRes_FMAXIMUMNUM(SDNode *N); |
| 586 | SDValue SoftenFloatRes_FMINIMUM(SDNode *N); |
| 587 | SDValue SoftenFloatRes_FMAXIMUM(SDNode *N); |
| 588 | SDValue SoftenFloatRes_FADD(SDNode *N); |
| 589 | SDValue SoftenFloatRes_FCBRT(SDNode *N); |
| 590 | SDValue SoftenFloatRes_FCEIL(SDNode *N); |
| 591 | SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N); |
| 592 | SDValue SoftenFloatRes_FCOS(SDNode *N); |
| 593 | SDValue SoftenFloatRes_FCOSH(SDNode *N); |
| 594 | SDValue SoftenFloatRes_FDIV(SDNode *N); |
| 595 | SDValue SoftenFloatRes_FEXP(SDNode *N); |
| 596 | SDValue SoftenFloatRes_FEXP2(SDNode *N); |
| 597 | SDValue SoftenFloatRes_FEXP10(SDNode *N); |
| 598 | SDValue SoftenFloatRes_FFLOOR(SDNode *N); |
| 599 | SDValue SoftenFloatRes_FLOG(SDNode *N); |
| 600 | SDValue SoftenFloatRes_FLOG2(SDNode *N); |
| 601 | SDValue SoftenFloatRes_FLOG10(SDNode *N); |
| 602 | SDValue SoftenFloatRes_FMA(SDNode *N); |
| 603 | SDValue SoftenFloatRes_FMUL(SDNode *N); |
| 604 | SDValue SoftenFloatRes_FNEARBYINT(SDNode *N); |
| 605 | SDValue SoftenFloatRes_FNEG(SDNode *N); |
| 606 | SDValue SoftenFloatRes_FP_EXTEND(SDNode *N); |
| 607 | SDValue SoftenFloatRes_FP16_TO_FP(SDNode *N); |
| 608 | SDValue SoftenFloatRes_BF16_TO_FP(SDNode *N); |
| 609 | SDValue SoftenFloatRes_FP_ROUND(SDNode *N); |
| 610 | SDValue SoftenFloatRes_FPOW(SDNode *N); |
| 611 | SDValue SoftenFloatRes_ExpOp(SDNode *N); |
| 612 | SDValue SoftenFloatRes_FFREXP(SDNode *N); |
| 613 | SDValue SoftenFloatRes_FSINCOS(SDNode *N); |
| 614 | SDValue SoftenFloatRes_FMODF(SDNode *N); |
| 615 | SDValue SoftenFloatRes_FREEZE(SDNode *N); |
| 616 | SDValue SoftenFloatRes_FREM(SDNode *N); |
| 617 | SDValue SoftenFloatRes_FRINT(SDNode *N); |
| 618 | SDValue SoftenFloatRes_FROUND(SDNode *N); |
| 619 | SDValue SoftenFloatRes_FROUNDEVEN(SDNode *N); |
| 620 | SDValue SoftenFloatRes_FSIN(SDNode *N); |
| 621 | SDValue SoftenFloatRes_FSINH(SDNode *N); |
| 622 | SDValue SoftenFloatRes_FSQRT(SDNode *N); |
| 623 | SDValue SoftenFloatRes_FSUB(SDNode *N); |
| 624 | SDValue SoftenFloatRes_FTAN(SDNode *N); |
| 625 | SDValue SoftenFloatRes_FTANH(SDNode *N); |
| 626 | SDValue SoftenFloatRes_FTRUNC(SDNode *N); |
| 627 | SDValue SoftenFloatRes_LOAD(SDNode *N); |
| 628 | SDValue SoftenFloatRes_ATOMIC_LOAD(SDNode *N); |
| 629 | SDValue SoftenFloatRes_SELECT(SDNode *N); |
| 630 | SDValue SoftenFloatRes_SELECT_CC(SDNode *N); |
| 631 | SDValue SoftenFloatRes_UNDEF(SDNode *N); |
| 632 | SDValue SoftenFloatRes_VAARG(SDNode *N); |
| 633 | SDValue SoftenFloatRes_XINT_TO_FP(SDNode *N); |
| 634 | SDValue SoftenFloatRes_VECREDUCE(SDNode *N); |
| 635 | SDValue SoftenFloatRes_VECREDUCE_SEQ(SDNode *N); |
| 636 | |
| 637 | // Convert Float Operand to Integer. |
| 638 | bool SoftenFloatOperand(SDNode *N, unsigned OpNo); |
| 639 | SDValue SoftenFloatOp_Unary(SDNode *N, RTLIB::Libcall LC); |
| 640 | SDValue SoftenFloatOp_BITCAST(SDNode *N); |
| 641 | SDValue SoftenFloatOp_BR_CC(SDNode *N); |
| 642 | SDValue SoftenFloatOp_FP_ROUND(SDNode *N); |
| 643 | SDValue SoftenFloatOp_FP_TO_XINT(SDNode *N); |
| 644 | SDValue SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N); |
| 645 | SDValue SoftenFloatOp_LROUND(SDNode *N); |
| 646 | SDValue SoftenFloatOp_LLROUND(SDNode *N); |
| 647 | SDValue SoftenFloatOp_LRINT(SDNode *N); |
| 648 | SDValue SoftenFloatOp_LLRINT(SDNode *N); |
| 649 | SDValue SoftenFloatOp_SELECT_CC(SDNode *N); |
| 650 | SDValue SoftenFloatOp_SETCC(SDNode *N); |
| 651 | SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo); |
| 652 | SDValue SoftenFloatOp_ATOMIC_STORE(SDNode *N, unsigned OpNo); |
| 653 | SDValue SoftenFloatOp_FCOPYSIGN(SDNode *N); |
| 654 | SDValue SoftenFloatOp_FAKE_USE(SDNode *N); |
| 655 | |
| 656 | //===--------------------------------------------------------------------===// |
| 657 | // Float Expansion Support: LegalizeFloatTypes.cpp |
| 658 | //===--------------------------------------------------------------------===// |
| 659 | |
| 660 | /// Given a processed operand Op which was expanded into two floating-point |
| 661 | /// values of half the size, this returns the two halves. |
| 662 | /// The low bits of Op are exactly equal to the bits of Lo; the high bits |
| 663 | /// exactly equal Hi. For example, if Op is a ppcf128 which was expanded |
| 664 | /// into two f64's, then this method returns the two f64's, with Lo being |
| 665 | /// equal to the lower 64 bits of Op, and Hi to the upper 64 bits. |
| 666 | void GetExpandedFloat(SDValue Op, SDValue &Lo, SDValue &Hi); |
| 667 | void SetExpandedFloat(SDValue Op, SDValue Lo, SDValue Hi); |
| 668 | |
| 669 | // Float Result Expansion. |
| 670 | void ExpandFloatResult(SDNode *N, unsigned ResNo); |
| 671 | void ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 672 | void ExpandFloatRes_Unary(SDNode *N, RTLIB::Libcall LC, |
| 673 | SDValue &Lo, SDValue &Hi); |
| 674 | void ExpandFloatRes_Binary(SDNode *N, RTLIB::Libcall LC, |
| 675 | SDValue &Lo, SDValue &Hi); |
| 676 | void ExpandFloatRes_UnaryWithTwoFPResults( |
| 677 | SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo = {}); |
| 678 | |
| 679 | // clang-format off |
| 680 | void ExpandFloatRes_FABS (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 681 | void ExpandFloatRes_FACOS (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 682 | void ExpandFloatRes_FASIN (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 683 | void ExpandFloatRes_FATAN (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 684 | void ExpandFloatRes_FATAN2 (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 685 | void ExpandFloatRes_FMINNUM (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 686 | void ExpandFloatRes_FMAXNUM (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 687 | void ExpandFloatRes_FMINIMUMNUM(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 688 | void ExpandFloatRes_FMAXIMUMNUM(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 689 | void ExpandFloatRes_FADD (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 690 | void ExpandFloatRes_FCBRT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 691 | void ExpandFloatRes_FCEIL (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 692 | void ExpandFloatRes_FCOPYSIGN (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 693 | void ExpandFloatRes_FCOS (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 694 | void ExpandFloatRes_FCOSH (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 695 | void ExpandFloatRes_FDIV (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 696 | void ExpandFloatRes_FEXP (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 697 | void ExpandFloatRes_FEXP2 (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 698 | void ExpandFloatRes_FEXP10 (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 699 | void ExpandFloatRes_FFLOOR (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 700 | void ExpandFloatRes_FLOG (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 701 | void ExpandFloatRes_FLOG2 (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 702 | void ExpandFloatRes_FLOG10 (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 703 | void ExpandFloatRes_FMA (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 704 | void ExpandFloatRes_FMUL (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 705 | void ExpandFloatRes_FNEARBYINT(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 706 | void ExpandFloatRes_FNEG (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 707 | void ExpandFloatRes_FP_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 708 | void ExpandFloatRes_FPOW (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 709 | void ExpandFloatRes_FPOWI (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 710 | void ExpandFloatRes_FLDEXP (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 711 | void ExpandFloatRes_FREEZE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 712 | void ExpandFloatRes_FREM (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 713 | void ExpandFloatRes_FRINT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 714 | void ExpandFloatRes_FROUND (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 715 | void ExpandFloatRes_FROUNDEVEN(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 716 | void ExpandFloatRes_FSIN (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 717 | void ExpandFloatRes_FSINH (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 718 | void ExpandFloatRes_FSQRT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 719 | void ExpandFloatRes_FSUB (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 720 | void ExpandFloatRes_FTAN (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 721 | void ExpandFloatRes_FTANH (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 722 | void ExpandFloatRes_FTRUNC (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 723 | void ExpandFloatRes_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 724 | void ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 725 | void ExpandFloatRes_FMODF(SDNode *N); |
| 726 | void ExpandFloatRes_FSINCOS(SDNode* N); |
| 727 | void ExpandFloatRes_FSINCOSPI(SDNode* N); |
| 728 | // clang-format on |
| 729 | |
| 730 | // Float Operand Expansion. |
| 731 | bool ExpandFloatOperand(SDNode *N, unsigned OpNo); |
| 732 | SDValue ExpandFloatOp_BR_CC(SDNode *N); |
| 733 | SDValue ExpandFloatOp_FCOPYSIGN(SDNode *N); |
| 734 | SDValue ExpandFloatOp_FP_ROUND(SDNode *N); |
| 735 | SDValue ExpandFloatOp_FP_TO_XINT(SDNode *N); |
| 736 | SDValue ExpandFloatOp_LROUND(SDNode *N); |
| 737 | SDValue ExpandFloatOp_LLROUND(SDNode *N); |
| 738 | SDValue ExpandFloatOp_LRINT(SDNode *N); |
| 739 | SDValue ExpandFloatOp_LLRINT(SDNode *N); |
| 740 | SDValue ExpandFloatOp_SELECT_CC(SDNode *N); |
| 741 | SDValue ExpandFloatOp_SETCC(SDNode *N); |
| 742 | SDValue ExpandFloatOp_STORE(SDNode *N, unsigned OpNo); |
| 743 | |
| 744 | void FloatExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, |
| 745 | ISD::CondCode &CCCode, const SDLoc &dl, |
| 746 | SDValue &Chain, bool IsSignaling = false); |
| 747 | |
| 748 | //===--------------------------------------------------------------------===// |
| 749 | // Float promotion support: LegalizeFloatTypes.cpp |
| 750 | //===--------------------------------------------------------------------===// |
| 751 | |
| 752 | SDValue GetPromotedFloat(SDValue Op) { |
| 753 | TableId &PromotedId = PromotedFloats[getTableId(V: Op)]; |
| 754 | SDValue PromotedOp = getSDValue(Id&: PromotedId); |
| 755 | assert(PromotedOp.getNode() && "Operand wasn't promoted?" ); |
| 756 | return PromotedOp; |
| 757 | } |
| 758 | void SetPromotedFloat(SDValue Op, SDValue Result); |
| 759 | |
| 760 | void PromoteFloatResult(SDNode *N, unsigned ResNo); |
| 761 | SDValue PromoteFloatRes_BITCAST(SDNode *N); |
| 762 | SDValue PromoteFloatRes_FREEZE(SDNode *N); |
| 763 | SDValue PromoteFloatRes_BinOp(SDNode *N); |
| 764 | SDValue PromoteFloatRes_UnaryWithTwoFPResults(SDNode *N); |
| 765 | SDValue PromoteFloatRes_ConstantFP(SDNode *N); |
| 766 | SDValue (SDNode *N); |
| 767 | SDValue PromoteFloatRes_FCOPYSIGN(SDNode *N); |
| 768 | SDValue PromoteFloatRes_FMAD(SDNode *N); |
| 769 | SDValue PromoteFloatRes_ExpOp(SDNode *N); |
| 770 | SDValue PromoteFloatRes_FFREXP(SDNode *N); |
| 771 | SDValue PromoteFloatRes_FP_ROUND(SDNode *N); |
| 772 | SDValue PromoteFloatRes_STRICT_FP_ROUND(SDNode *N); |
| 773 | SDValue PromoteFloatRes_LOAD(SDNode *N); |
| 774 | SDValue PromoteFloatRes_ATOMIC_LOAD(SDNode *N); |
| 775 | SDValue PromoteFloatRes_SELECT(SDNode *N); |
| 776 | SDValue PromoteFloatRes_SELECT_CC(SDNode *N); |
| 777 | SDValue PromoteFloatRes_UnaryOp(SDNode *N); |
| 778 | SDValue PromoteFloatRes_AssertNoFPClass(SDNode *N); |
| 779 | SDValue PromoteFloatRes_UNDEF(SDNode *N); |
| 780 | SDValue BitcastToInt_ATOMIC_SWAP(SDNode *N); |
| 781 | SDValue PromoteFloatRes_XINT_TO_FP(SDNode *N); |
| 782 | SDValue PromoteFloatRes_VECREDUCE(SDNode *N); |
| 783 | SDValue PromoteFloatRes_VECREDUCE_SEQ(SDNode *N); |
| 784 | |
| 785 | bool PromoteFloatOperand(SDNode *N, unsigned OpNo); |
| 786 | SDValue PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo); |
| 787 | SDValue PromoteFloatOp_FAKE_USE(SDNode *N, unsigned OpNo); |
| 788 | SDValue PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo); |
| 789 | SDValue PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo); |
| 790 | SDValue PromoteFloatOp_STRICT_FP_EXTEND(SDNode *N, unsigned OpNo); |
| 791 | SDValue PromoteFloatOp_UnaryOp(SDNode *N, unsigned OpNo); |
| 792 | SDValue PromoteFloatOp_AssertNoFPClass(SDNode *N, unsigned OpNo); |
| 793 | SDValue PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo); |
| 794 | SDValue PromoteFloatOp_STORE(SDNode *N, unsigned OpNo); |
| 795 | SDValue PromoteFloatOp_ATOMIC_STORE(SDNode *N, unsigned OpNo); |
| 796 | SDValue PromoteFloatOp_SELECT_CC(SDNode *N, unsigned OpNo); |
| 797 | SDValue PromoteFloatOp_SETCC(SDNode *N, unsigned OpNo); |
| 798 | |
| 799 | //===--------------------------------------------------------------------===// |
| 800 | // Half soft promotion support: LegalizeFloatTypes.cpp |
| 801 | //===--------------------------------------------------------------------===// |
| 802 | |
| 803 | SDValue GetSoftPromotedHalf(SDValue Op) { |
| 804 | TableId &PromotedId = SoftPromotedHalfs[getTableId(V: Op)]; |
| 805 | SDValue PromotedOp = getSDValue(Id&: PromotedId); |
| 806 | assert(PromotedOp.getNode() && "Operand wasn't promoted?" ); |
| 807 | return PromotedOp; |
| 808 | } |
| 809 | void SetSoftPromotedHalf(SDValue Op, SDValue Result); |
| 810 | |
| 811 | void SoftPromoteHalfResult(SDNode *N, unsigned ResNo); |
| 812 | SDValue SoftPromoteHalfRes_ARITH_FENCE(SDNode *N); |
| 813 | SDValue SoftPromoteHalfRes_BinOp(SDNode *N); |
| 814 | SDValue SoftPromoteHalfRes_UnaryWithTwoFPResults(SDNode *N); |
| 815 | SDValue SoftPromoteHalfRes_BITCAST(SDNode *N); |
| 816 | SDValue SoftPromoteHalfRes_ConstantFP(SDNode *N); |
| 817 | SDValue (SDNode *N); |
| 818 | SDValue SoftPromoteHalfRes_FCOPYSIGN(SDNode *N); |
| 819 | SDValue SoftPromoteHalfRes_FMAD(SDNode *N); |
| 820 | SDValue SoftPromoteHalfRes_ExpOp(SDNode *N); |
| 821 | SDValue SoftPromoteHalfRes_FFREXP(SDNode *N); |
| 822 | SDValue SoftPromoteHalfRes_FP_ROUND(SDNode *N); |
| 823 | SDValue SoftPromoteHalfRes_LOAD(SDNode *N); |
| 824 | SDValue SoftPromoteHalfRes_ATOMIC_LOAD(SDNode *N); |
| 825 | SDValue SoftPromoteHalfRes_SELECT(SDNode *N); |
| 826 | SDValue SoftPromoteHalfRes_SELECT_CC(SDNode *N); |
| 827 | SDValue SoftPromoteHalfRes_UnaryOp(SDNode *N); |
| 828 | SDValue SoftPromoteHalfRes_AssertNoFPClass(SDNode *N); |
| 829 | SDValue SoftPromoteHalfRes_XINT_TO_FP(SDNode *N); |
| 830 | SDValue SoftPromoteHalfRes_UNDEF(SDNode *N); |
| 831 | SDValue SoftPromoteHalfRes_VECREDUCE(SDNode *N); |
| 832 | SDValue SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N); |
| 833 | |
| 834 | bool SoftPromoteHalfOperand(SDNode *N, unsigned OpNo); |
| 835 | SDValue SoftPromoteHalfOp_BITCAST(SDNode *N); |
| 836 | SDValue SoftPromoteHalfOp_FAKE_USE(SDNode *N, unsigned OpNo); |
| 837 | SDValue SoftPromoteHalfOp_FCOPYSIGN(SDNode *N, unsigned OpNo); |
| 838 | SDValue SoftPromoteHalfOp_FP_EXTEND(SDNode *N); |
| 839 | SDValue SoftPromoteHalfOp_FP_TO_XINT(SDNode *N); |
| 840 | SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N); |
| 841 | SDValue SoftPromoteHalfOp_SETCC(SDNode *N); |
| 842 | SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo); |
| 843 | SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo); |
| 844 | SDValue SoftPromoteHalfOp_ATOMIC_STORE(SDNode *N, unsigned OpNo); |
| 845 | SDValue SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo); |
| 846 | SDValue SoftPromoteHalfOp_PATCHPOINT(SDNode *N, unsigned OpNo); |
| 847 | |
| 848 | //===--------------------------------------------------------------------===// |
| 849 | // Scalarization Support: LegalizeVectorTypes.cpp |
| 850 | //===--------------------------------------------------------------------===// |
| 851 | |
| 852 | /// Given a processed one-element vector Op which was scalarized to its |
| 853 | /// element type, this returns the element. For example, if Op is a v1i32, |
| 854 | /// Op = < i32 val >, this method returns val, an i32. |
| 855 | SDValue GetScalarizedVector(SDValue Op) { |
| 856 | TableId &ScalarizedId = ScalarizedVectors[getTableId(V: Op)]; |
| 857 | SDValue ScalarizedOp = getSDValue(Id&: ScalarizedId); |
| 858 | assert(ScalarizedOp.getNode() && "Operand wasn't scalarized?" ); |
| 859 | return ScalarizedOp; |
| 860 | } |
| 861 | void SetScalarizedVector(SDValue Op, SDValue Result); |
| 862 | |
| 863 | // Vector Result Scalarization: <1 x ty> -> ty. |
| 864 | void ScalarizeVectorResult(SDNode *N, unsigned ResNo); |
| 865 | SDValue ScalarizeVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo); |
| 866 | SDValue ScalarizeVecRes_BinOp(SDNode *N); |
| 867 | SDValue ScalarizeVecRes_CMP(SDNode *N); |
| 868 | SDValue ScalarizeVecRes_TernaryOp(SDNode *N); |
| 869 | SDValue ScalarizeVecRes_UnaryOp(SDNode *N); |
| 870 | SDValue ScalarizeVecRes_StrictFPOp(SDNode *N); |
| 871 | SDValue ScalarizeVecRes_OverflowOp(SDNode *N, unsigned ResNo); |
| 872 | SDValue ScalarizeVecRes_InregOp(SDNode *N); |
| 873 | SDValue ScalarizeVecRes_VecInregOp(SDNode *N); |
| 874 | |
| 875 | SDValue ScalarizeVecRes_ADDRSPACECAST(SDNode *N); |
| 876 | SDValue ScalarizeVecRes_BITCAST(SDNode *N); |
| 877 | SDValue ScalarizeVecRes_BUILD_VECTOR(SDNode *N); |
| 878 | SDValue (SDNode *N); |
| 879 | SDValue ScalarizeVecRes_FP_ROUND(SDNode *N); |
| 880 | SDValue (SDNode *N); |
| 881 | SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N); |
| 882 | SDValue ScalarizeVecRes_LOAD(LoadSDNode *N); |
| 883 | SDValue ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N); |
| 884 | SDValue ScalarizeVecRes_VSELECT(SDNode *N); |
| 885 | SDValue ScalarizeVecRes_SELECT(SDNode *N); |
| 886 | SDValue ScalarizeVecRes_SELECT_CC(SDNode *N); |
| 887 | SDValue ScalarizeVecRes_SETCC(SDNode *N); |
| 888 | SDValue ScalarizeVecRes_UNDEF(SDNode *N); |
| 889 | SDValue ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N); |
| 890 | SDValue ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N); |
| 891 | SDValue ScalarizeVecRes_IS_FPCLASS(SDNode *N); |
| 892 | |
| 893 | SDValue ScalarizeVecRes_FIX(SDNode *N); |
| 894 | SDValue ScalarizeVecRes_UnaryOpWithTwoResults(SDNode *N, unsigned ResNo); |
| 895 | |
| 896 | // Vector Operand Scalarization: <1 x ty> -> ty. |
| 897 | bool ScalarizeVectorOperand(SDNode *N, unsigned OpNo); |
| 898 | SDValue ScalarizeVecOp_BITCAST(SDNode *N); |
| 899 | SDValue ScalarizeVecOp_UnaryOp(SDNode *N); |
| 900 | SDValue (SDNode *N); |
| 901 | SDValue ScalarizeVecOp_UnaryOp_StrictFP(SDNode *N); |
| 902 | SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N); |
| 903 | SDValue ScalarizeVecOp_INSERT_SUBVECTOR(SDNode *N, unsigned OpNo); |
| 904 | SDValue (SDNode *N); |
| 905 | SDValue ScalarizeVecOp_VSELECT(SDNode *N); |
| 906 | SDValue ScalarizeVecOp_VSETCC(SDNode *N); |
| 907 | SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo); |
| 908 | SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo); |
| 909 | SDValue ScalarizeVecOp_STRICT_FP_ROUND(SDNode *N, unsigned OpNo); |
| 910 | SDValue ScalarizeVecOp_FP_EXTEND(SDNode *N); |
| 911 | SDValue ScalarizeVecOp_STRICT_FP_EXTEND(SDNode *N); |
| 912 | SDValue ScalarizeVecOp_VECREDUCE(SDNode *N); |
| 913 | SDValue ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N); |
| 914 | SDValue ScalarizeVecOp_CMP(SDNode *N); |
| 915 | SDValue ScalarizeVecOp_FAKE_USE(SDNode *N); |
| 916 | |
| 917 | //===--------------------------------------------------------------------===// |
| 918 | // Vector Splitting Support: LegalizeVectorTypes.cpp |
| 919 | //===--------------------------------------------------------------------===// |
| 920 | |
| 921 | /// Given a processed vector Op which was split into vectors of half the size, |
| 922 | /// this method returns the halves. The first elements of Op coincide with the |
| 923 | /// elements of Lo; the remaining elements of Op coincide with the elements of |
| 924 | /// Hi: Op is what you would get by concatenating Lo and Hi. |
| 925 | /// For example, if Op is a v8i32 that was split into two v4i32's, then this |
| 926 | /// method returns the two v4i32's, with Lo corresponding to the first 4 |
| 927 | /// elements of Op, and Hi to the last 4 elements. |
| 928 | void GetSplitVector(SDValue Op, SDValue &Lo, SDValue &Hi); |
| 929 | void SetSplitVector(SDValue Op, SDValue Lo, SDValue Hi); |
| 930 | |
| 931 | /// Split mask operator of a VP intrinsic. |
| 932 | std::pair<SDValue, SDValue> SplitMask(SDValue Mask); |
| 933 | |
| 934 | /// Split mask operator of a VP intrinsic in a given location. |
| 935 | std::pair<SDValue, SDValue> SplitMask(SDValue Mask, const SDLoc &DL); |
| 936 | |
| 937 | // Helper function for incrementing the pointer when splitting |
| 938 | // memory operations |
| 939 | void IncrementPointer(MemSDNode *N, EVT MemVT, MachinePointerInfo &MPI, |
| 940 | SDValue &Ptr, uint64_t *ScaledOffset = nullptr); |
| 941 | |
| 942 | // Vector Result Splitting: <128 x ty> -> 2 x <64 x ty>. |
| 943 | void SplitVectorResult(SDNode *N, unsigned ResNo); |
| 944 | void SplitVecRes_BinOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 945 | void SplitVecRes_TernaryOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 946 | void SplitVecRes_CMP(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 947 | void SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 948 | void SplitVecRes_ADDRSPACECAST(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 949 | void SplitVecRes_UnaryOpWithTwoResults(SDNode *N, unsigned ResNo, SDValue &Lo, |
| 950 | SDValue &Hi); |
| 951 | void SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 952 | void SplitVecRes_InregOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 953 | void SplitVecRes_ExtVecInRegOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 954 | void SplitVecRes_StrictFPOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 955 | void SplitVecRes_OverflowOp(SDNode *N, unsigned ResNo, |
| 956 | SDValue &Lo, SDValue &Hi); |
| 957 | |
| 958 | void SplitVecRes_FIX(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 959 | |
| 960 | void SplitVecRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 961 | void SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 962 | void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 963 | void (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 964 | void SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 965 | void SplitVecRes_FPOp_MultiType(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 966 | void SplitVecRes_IS_FPCLASS(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 967 | void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 968 | void SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi); |
| 969 | void SplitVecRes_VP_LOAD(VPLoadSDNode *LD, SDValue &Lo, SDValue &Hi); |
| 970 | void SplitVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *SLD, SDValue &Lo, |
| 971 | SDValue &Hi); |
| 972 | void SplitVecRes_MLOAD(MaskedLoadSDNode *MLD, SDValue &Lo, SDValue &Hi); |
| 973 | void SplitVecRes_Gather(MemSDNode *VPGT, SDValue &Lo, SDValue &Hi, |
| 974 | bool SplitSETCC = false); |
| 975 | void SplitVecRes_VECTOR_COMPRESS(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 976 | void SplitVecRes_ScalarOp(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 977 | void SplitVecRes_VP_SPLAT(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 978 | void SplitVecRes_STEP_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 979 | void SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 980 | void SplitVecRes_VECTOR_REVERSE(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 981 | void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo, |
| 982 | SDValue &Hi); |
| 983 | void SplitVecRes_VECTOR_SPLICE(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 984 | void SplitVecRes_VECTOR_DEINTERLEAVE(SDNode *N); |
| 985 | void SplitVecRes_VECTOR_INTERLEAVE(SDNode *N); |
| 986 | void SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 987 | void SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 988 | void SplitVecRes_VP_SPLICE(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 989 | void SplitVecRes_VP_REVERSE(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 990 | void SplitVecRes_PARTIAL_REDUCE_MLA(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 991 | void SplitVecRes_GET_ACTIVE_LANE_MASK(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 992 | |
| 993 | // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>. |
| 994 | bool SplitVectorOperand(SDNode *N, unsigned OpNo); |
| 995 | SDValue SplitVecOp_VSELECT(SDNode *N, unsigned OpNo); |
| 996 | SDValue SplitVecOp_VECREDUCE(SDNode *N, unsigned OpNo); |
| 997 | SDValue SplitVecOp_VECREDUCE_SEQ(SDNode *N); |
| 998 | SDValue SplitVecOp_VP_REDUCE(SDNode *N, unsigned OpNo); |
| 999 | SDValue SplitVecOp_UnaryOp(SDNode *N); |
| 1000 | SDValue SplitVecOp_TruncateHelper(SDNode *N); |
| 1001 | SDValue SplitVecOp_VECTOR_COMPRESS(SDNode *N, unsigned OpNo); |
| 1002 | |
| 1003 | SDValue SplitVecOp_BITCAST(SDNode *N); |
| 1004 | SDValue SplitVecOp_INSERT_SUBVECTOR(SDNode *N, unsigned OpNo); |
| 1005 | SDValue (SDNode *N); |
| 1006 | SDValue (SDNode *N); |
| 1007 | SDValue SplitVecOp_ExtVecInRegOp(SDNode *N); |
| 1008 | SDValue SplitVecOp_FAKE_USE(SDNode *N); |
| 1009 | SDValue SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo); |
| 1010 | SDValue SplitVecOp_VP_STORE(VPStoreSDNode *N, unsigned OpNo); |
| 1011 | SDValue SplitVecOp_VP_STRIDED_STORE(VPStridedStoreSDNode *N, unsigned OpNo); |
| 1012 | SDValue SplitVecOp_MSTORE(MaskedStoreSDNode *N, unsigned OpNo); |
| 1013 | SDValue SplitVecOp_Scatter(MemSDNode *N, unsigned OpNo); |
| 1014 | SDValue SplitVecOp_Gather(MemSDNode *MGT, unsigned OpNo); |
| 1015 | SDValue SplitVecOp_CONCAT_VECTORS(SDNode *N); |
| 1016 | SDValue SplitVecOp_VSETCC(SDNode *N); |
| 1017 | SDValue SplitVecOp_FP_ROUND(SDNode *N); |
| 1018 | SDValue SplitVecOp_FPOpDifferentTypes(SDNode *N); |
| 1019 | SDValue SplitVecOp_CMP(SDNode *N); |
| 1020 | SDValue SplitVecOp_FP_TO_XINT_SAT(SDNode *N); |
| 1021 | SDValue SplitVecOp_VP_CttzElements(SDNode *N); |
| 1022 | SDValue SplitVecOp_VECTOR_HISTOGRAM(SDNode *N); |
| 1023 | SDValue SplitVecOp_PARTIAL_REDUCE_MLA(SDNode *N); |
| 1024 | |
| 1025 | //===--------------------------------------------------------------------===// |
| 1026 | // Vector Widening Support: LegalizeVectorTypes.cpp |
| 1027 | //===--------------------------------------------------------------------===// |
| 1028 | |
| 1029 | /// Given a processed vector Op which was widened into a larger vector, this |
| 1030 | /// method returns the larger vector. The elements of the returned vector |
| 1031 | /// consist of the elements of Op followed by elements containing rubbish. |
| 1032 | /// For example, if Op is a v2i32 that was widened to a v4i32, then this |
| 1033 | /// method returns a v4i32 for which the first two elements are the same as |
| 1034 | /// those of Op, while the last two elements contain rubbish. |
| 1035 | SDValue GetWidenedVector(SDValue Op) { |
| 1036 | TableId &WidenedId = WidenedVectors[getTableId(V: Op)]; |
| 1037 | SDValue WidenedOp = getSDValue(Id&: WidenedId); |
| 1038 | assert(WidenedOp.getNode() && "Operand wasn't widened?" ); |
| 1039 | return WidenedOp; |
| 1040 | } |
| 1041 | void SetWidenedVector(SDValue Op, SDValue Result); |
| 1042 | |
| 1043 | /// Given a mask Mask, returns the larger vector into which Mask was widened. |
| 1044 | SDValue GetWidenedMask(SDValue Mask, ElementCount EC) { |
| 1045 | // For VP operations, we must also widen the mask. Note that the mask type |
| 1046 | // may not actually need widening, leading it be split along with the VP |
| 1047 | // operation. |
| 1048 | // FIXME: This could lead to an infinite split/widen loop. We only handle |
| 1049 | // the case where the mask needs widening to an identically-sized type as |
| 1050 | // the vector inputs. |
| 1051 | assert(getTypeAction(Mask.getValueType()) == |
| 1052 | TargetLowering::TypeWidenVector && |
| 1053 | "Unable to widen binary VP op" ); |
| 1054 | Mask = GetWidenedVector(Op: Mask); |
| 1055 | assert(Mask.getValueType().getVectorElementCount() == EC && |
| 1056 | "Unable to widen binary VP op" ); |
| 1057 | return Mask; |
| 1058 | } |
| 1059 | |
| 1060 | // Widen Vector Result Promotion. |
| 1061 | void WidenVectorResult(SDNode *N, unsigned ResNo); |
| 1062 | SDValue WidenVecRes_MERGE_VALUES(SDNode* N, unsigned ResNo); |
| 1063 | SDValue WidenVecRes_ADDRSPACECAST(SDNode *N); |
| 1064 | SDValue WidenVecRes_AssertZext(SDNode* N); |
| 1065 | SDValue WidenVecRes_BITCAST(SDNode* N); |
| 1066 | SDValue WidenVecRes_BUILD_VECTOR(SDNode* N); |
| 1067 | SDValue WidenVecRes_CONCAT_VECTORS(SDNode* N); |
| 1068 | SDValue WidenVecRes_EXTEND_VECTOR_INREG(SDNode* N); |
| 1069 | SDValue (SDNode* N); |
| 1070 | SDValue WidenVecRes_INSERT_SUBVECTOR(SDNode *N); |
| 1071 | SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N); |
| 1072 | SDValue WidenVecRes_LOAD(SDNode* N); |
| 1073 | SDValue WidenVecRes_VP_LOAD(VPLoadSDNode *N); |
| 1074 | SDValue WidenVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *N); |
| 1075 | SDValue WidenVecRes_VECTOR_COMPRESS(SDNode *N); |
| 1076 | SDValue WidenVecRes_MLOAD(MaskedLoadSDNode* N); |
| 1077 | SDValue WidenVecRes_MGATHER(MaskedGatherSDNode* N); |
| 1078 | SDValue WidenVecRes_VP_GATHER(VPGatherSDNode* N); |
| 1079 | SDValue WidenVecRes_ScalarOp(SDNode* N); |
| 1080 | SDValue WidenVecRes_Select(SDNode *N); |
| 1081 | SDValue WidenVSELECTMask(SDNode *N); |
| 1082 | SDValue WidenVecRes_SELECT_CC(SDNode* N); |
| 1083 | SDValue WidenVecRes_SETCC(SDNode* N); |
| 1084 | SDValue WidenVecRes_STRICT_FSETCC(SDNode* N); |
| 1085 | SDValue WidenVecRes_UNDEF(SDNode *N); |
| 1086 | SDValue WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N); |
| 1087 | SDValue WidenVecRes_VECTOR_REVERSE(SDNode *N); |
| 1088 | SDValue WidenVecRes_GET_ACTIVE_LANE_MASK(SDNode *N); |
| 1089 | |
| 1090 | SDValue WidenVecRes_Ternary(SDNode *N); |
| 1091 | SDValue WidenVecRes_Binary(SDNode *N); |
| 1092 | SDValue WidenVecRes_CMP(SDNode *N); |
| 1093 | SDValue WidenVecRes_BinaryCanTrap(SDNode *N); |
| 1094 | SDValue (SDNode *N); |
| 1095 | SDValue WidenVecRes_StrictFP(SDNode *N); |
| 1096 | SDValue WidenVecRes_OverflowOp(SDNode *N, unsigned ResNo); |
| 1097 | SDValue WidenVecRes_Convert(SDNode *N); |
| 1098 | SDValue WidenVecRes_Convert_StrictFP(SDNode *N); |
| 1099 | SDValue WidenVecRes_FP_TO_XINT_SAT(SDNode *N); |
| 1100 | SDValue WidenVecRes_XROUND(SDNode *N); |
| 1101 | SDValue WidenVecRes_FCOPYSIGN(SDNode *N); |
| 1102 | SDValue WidenVecRes_UnarySameEltsWithScalarArg(SDNode *N); |
| 1103 | SDValue WidenVecRes_ExpOp(SDNode *N); |
| 1104 | SDValue WidenVecRes_Unary(SDNode *N); |
| 1105 | SDValue WidenVecRes_InregOp(SDNode *N); |
| 1106 | SDValue WidenVecRes_UnaryOpWithTwoResults(SDNode *N, unsigned ResNo); |
| 1107 | void ReplaceOtherWidenResults(SDNode *N, SDNode *WidenNode, |
| 1108 | unsigned WidenResNo); |
| 1109 | |
| 1110 | // Widen Vector Operand. |
| 1111 | bool WidenVectorOperand(SDNode *N, unsigned OpNo); |
| 1112 | SDValue WidenVecOp_BITCAST(SDNode *N); |
| 1113 | SDValue WidenVecOp_CONCAT_VECTORS(SDNode *N); |
| 1114 | SDValue WidenVecOp_EXTEND(SDNode *N); |
| 1115 | SDValue WidenVecOp_CMP(SDNode *N); |
| 1116 | SDValue (SDNode *N); |
| 1117 | SDValue WidenVecOp_INSERT_SUBVECTOR(SDNode *N); |
| 1118 | SDValue (SDNode *N); |
| 1119 | SDValue WidenVecOp_EXTEND_VECTOR_INREG(SDNode *N); |
| 1120 | SDValue WidenVecOp_FAKE_USE(SDNode *N); |
| 1121 | SDValue WidenVecOp_STORE(SDNode* N); |
| 1122 | SDValue WidenVecOp_VP_STORE(SDNode *N, unsigned OpNo); |
| 1123 | SDValue WidenVecOp_VP_STRIDED_STORE(SDNode *N, unsigned OpNo); |
| 1124 | SDValue WidenVecOp_MSTORE(SDNode* N, unsigned OpNo); |
| 1125 | SDValue WidenVecOp_MGATHER(SDNode* N, unsigned OpNo); |
| 1126 | SDValue WidenVecOp_MSCATTER(SDNode* N, unsigned OpNo); |
| 1127 | SDValue WidenVecOp_VP_SCATTER(SDNode* N, unsigned OpNo); |
| 1128 | SDValue WidenVecOp_VP_SPLAT(SDNode *N, unsigned OpNo); |
| 1129 | SDValue WidenVecOp_SETCC(SDNode* N); |
| 1130 | SDValue WidenVecOp_STRICT_FSETCC(SDNode* N); |
| 1131 | SDValue WidenVecOp_VSELECT(SDNode *N); |
| 1132 | |
| 1133 | SDValue WidenVecOp_Convert(SDNode *N); |
| 1134 | SDValue WidenVecOp_FP_TO_XINT_SAT(SDNode *N); |
| 1135 | SDValue WidenVecOp_UnrollVectorOp(SDNode *N); |
| 1136 | SDValue WidenVecOp_IS_FPCLASS(SDNode *N); |
| 1137 | SDValue WidenVecOp_VECREDUCE(SDNode *N); |
| 1138 | SDValue WidenVecOp_VECREDUCE_SEQ(SDNode *N); |
| 1139 | SDValue WidenVecOp_VP_REDUCE(SDNode *N); |
| 1140 | SDValue WidenVecOp_ExpOp(SDNode *N); |
| 1141 | SDValue WidenVecOp_VP_CttzElements(SDNode *N); |
| 1142 | |
| 1143 | /// Helper function to generate a set of operations to perform |
| 1144 | /// a vector operation for a wider type. |
| 1145 | /// |
| 1146 | SDValue UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE); |
| 1147 | |
| 1148 | //===--------------------------------------------------------------------===// |
| 1149 | // Vector Widening Utilities Support: LegalizeVectorTypes.cpp |
| 1150 | //===--------------------------------------------------------------------===// |
| 1151 | |
| 1152 | /// Helper function to generate a set of loads to load a vector with a |
| 1153 | /// resulting wider type. It takes: |
| 1154 | /// LdChain: list of chains for the load to be generated. |
| 1155 | /// Ld: load to widen |
| 1156 | SDValue GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain, |
| 1157 | LoadSDNode *LD); |
| 1158 | |
| 1159 | /// Helper function to generate a set of extension loads to load a vector with |
| 1160 | /// a resulting wider type. It takes: |
| 1161 | /// LdChain: list of chains for the load to be generated. |
| 1162 | /// Ld: load to widen |
| 1163 | /// ExtType: extension element type |
| 1164 | SDValue GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain, |
| 1165 | LoadSDNode *LD, ISD::LoadExtType ExtType); |
| 1166 | |
| 1167 | /// Helper function to generate a set of stores to store a widen vector into |
| 1168 | /// non-widen memory. Returns true if successful, false otherwise. |
| 1169 | /// StChain: list of chains for the stores we have generated |
| 1170 | /// ST: store of a widen value |
| 1171 | bool GenWidenVectorStores(SmallVectorImpl<SDValue> &StChain, StoreSDNode *ST); |
| 1172 | |
| 1173 | /// Modifies a vector input (widen or narrows) to a vector of NVT. The |
| 1174 | /// input vector must have the same element type as NVT. |
| 1175 | /// When FillWithZeroes is "on" the vector will be widened with zeroes. |
| 1176 | /// By default, the vector will be widened with undefined values. |
| 1177 | SDValue ModifyToType(SDValue InOp, EVT NVT, bool FillWithZeroes = false); |
| 1178 | |
| 1179 | /// Return a mask of vector type MaskVT to replace InMask. Also adjust |
| 1180 | /// MaskVT to ToMaskVT if needed with vector extension or truncation. |
| 1181 | SDValue convertMask(SDValue InMask, EVT MaskVT, EVT ToMaskVT); |
| 1182 | |
| 1183 | //===--------------------------------------------------------------------===// |
| 1184 | // Generic Splitting: LegalizeTypesGeneric.cpp |
| 1185 | //===--------------------------------------------------------------------===// |
| 1186 | |
| 1187 | // Legalization methods which only use that the illegal type is split into two |
| 1188 | // not necessarily identical types. As such they can be used for splitting |
| 1189 | // vectors and expanding integers and floats. |
| 1190 | |
| 1191 | void GetSplitOp(SDValue Op, SDValue &Lo, SDValue &Hi) { |
| 1192 | if (Op.getValueType().isVector()) |
| 1193 | GetSplitVector(Op, Lo, Hi); |
| 1194 | else if (Op.getValueType().isInteger()) |
| 1195 | GetExpandedInteger(Op, Lo, Hi); |
| 1196 | else |
| 1197 | GetExpandedFloat(Op, Lo, Hi); |
| 1198 | } |
| 1199 | |
| 1200 | /// Use ISD::EXTRACT_ELEMENT nodes to extract the low and high parts of the |
| 1201 | /// given value. |
| 1202 | void GetPairElements(SDValue Pair, SDValue &Lo, SDValue &Hi); |
| 1203 | |
| 1204 | // Generic Result Splitting. |
| 1205 | void SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo, |
| 1206 | SDValue &Lo, SDValue &Hi); |
| 1207 | void SplitVecRes_AssertZext (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1208 | void SplitRes_ARITH_FENCE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1209 | void SplitRes_Select (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1210 | void SplitRes_SELECT_CC (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1211 | void SplitRes_UNDEF (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1212 | void SplitRes_FREEZE (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1213 | |
| 1214 | //===--------------------------------------------------------------------===// |
| 1215 | // Generic Expansion: LegalizeTypesGeneric.cpp |
| 1216 | //===--------------------------------------------------------------------===// |
| 1217 | |
| 1218 | // Legalization methods which only use that the illegal type is split into two |
| 1219 | // identical types of half the size, and that the Lo/Hi part is stored first |
| 1220 | // in memory on little/big-endian machines, followed by the Hi/Lo part. As |
| 1221 | // such they can be used for expanding integers and floats. |
| 1222 | |
| 1223 | void GetExpandedOp(SDValue Op, SDValue &Lo, SDValue &Hi) { |
| 1224 | if (Op.getValueType().isInteger()) |
| 1225 | GetExpandedInteger(Op, Lo, Hi); |
| 1226 | else |
| 1227 | GetExpandedFloat(Op, Lo, Hi); |
| 1228 | } |
| 1229 | |
| 1230 | |
| 1231 | /// This function will split the integer \p Op into \p NumElements |
| 1232 | /// operations of type \p EltVT and store them in \p Ops. |
| 1233 | void IntegerToVector(SDValue Op, unsigned NumElements, |
| 1234 | SmallVectorImpl<SDValue> &Ops, EVT EltVT); |
| 1235 | |
| 1236 | // Generic Result Expansion. |
| 1237 | void ExpandRes_MERGE_VALUES (SDNode *N, unsigned ResNo, |
| 1238 | SDValue &Lo, SDValue &Hi); |
| 1239 | void ExpandRes_BITCAST (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1240 | void ExpandRes_BUILD_PAIR (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1241 | void ExpandRes_EXTRACT_ELEMENT (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1242 | void ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1243 | void ExpandRes_NormalLoad (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1244 | void ExpandRes_VAARG (SDNode *N, SDValue &Lo, SDValue &Hi); |
| 1245 | |
| 1246 | // Generic Operand Expansion. |
| 1247 | SDValue ExpandOp_BITCAST (SDNode *N); |
| 1248 | SDValue ExpandOp_BUILD_VECTOR (SDNode *N); |
| 1249 | SDValue ExpandOp_EXTRACT_ELEMENT (SDNode *N); |
| 1250 | SDValue ExpandOp_FAKE_USE(SDNode *N); |
| 1251 | SDValue ExpandOp_INSERT_VECTOR_ELT(SDNode *N); |
| 1252 | SDValue ExpandOp_SCALAR_TO_VECTOR (SDNode *N); |
| 1253 | SDValue ExpandOp_NormalStore (SDNode *N, unsigned OpNo); |
| 1254 | }; |
| 1255 | |
| 1256 | } // end namespace llvm. |
| 1257 | |
| 1258 | #endif |
| 1259 | |