Chris Lattner | 08d1275 | 2007-12-08 20:24:38 +0000 | [diff] [blame] | 1 | //===-- LegalizeTypesPromote.cpp - Promotion for LegalizeTypes ------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame^] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Chris Lattner | 08d1275 | 2007-12-08 20:24:38 +0000 | [diff] [blame] | 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements promotion support for LegalizeTypes. Promotion is the |
| 11 | // act of changing a computation in an invalid type to be a computation in a |
| 12 | // larger type. For example, implementing i8 arithmetic in an i32 register (as |
| 13 | // is often needed on powerpc for example). |
| 14 | // |
| 15 | //===----------------------------------------------------------------------===// |
| 16 | |
| 17 | #include "LegalizeTypes.h" |
| 18 | using namespace llvm; |
| 19 | |
| 20 | //===----------------------------------------------------------------------===// |
| 21 | // Result Promotion |
| 22 | //===----------------------------------------------------------------------===// |
| 23 | |
| 24 | /// PromoteResult - This method is called when a result of a node is found to be |
| 25 | /// in need of promotion to a larger type. At this point, the node may also |
| 26 | /// have invalid operands or may have other results that need expansion, we just |
| 27 | /// know that (at least) one result needs promotion. |
| 28 | void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) { |
| 29 | DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n"); |
| 30 | SDOperand Result = SDOperand(); |
| 31 | |
| 32 | switch (N->getOpcode()) { |
| 33 | default: |
| 34 | #ifndef NDEBUG |
| 35 | cerr << "PromoteResult #" << ResNo << ": "; |
| 36 | N->dump(&DAG); cerr << "\n"; |
| 37 | #endif |
| 38 | assert(0 && "Do not know how to promote this operator!"); |
| 39 | abort(); |
| 40 | case ISD::UNDEF: Result = PromoteResult_UNDEF(N); break; |
| 41 | case ISD::Constant: Result = PromoteResult_Constant(N); break; |
| 42 | |
| 43 | case ISD::TRUNCATE: Result = PromoteResult_TRUNCATE(N); break; |
| 44 | case ISD::SIGN_EXTEND: |
| 45 | case ISD::ZERO_EXTEND: |
| 46 | case ISD::ANY_EXTEND: Result = PromoteResult_INT_EXTEND(N); break; |
| 47 | case ISD::FP_ROUND: Result = PromoteResult_FP_ROUND(N); break; |
| 48 | case ISD::FP_TO_SINT: |
| 49 | case ISD::FP_TO_UINT: Result = PromoteResult_FP_TO_XINT(N); break; |
| 50 | case ISD::SETCC: Result = PromoteResult_SETCC(N); break; |
| 51 | case ISD::LOAD: Result = PromoteResult_LOAD(cast<LoadSDNode>(N)); break; |
| 52 | |
| 53 | case ISD::AND: |
| 54 | case ISD::OR: |
| 55 | case ISD::XOR: |
| 56 | case ISD::ADD: |
| 57 | case ISD::SUB: |
| 58 | case ISD::MUL: Result = PromoteResult_SimpleIntBinOp(N); break; |
| 59 | |
| 60 | case ISD::SDIV: |
| 61 | case ISD::SREM: Result = PromoteResult_SDIV(N); break; |
| 62 | |
| 63 | case ISD::UDIV: |
| 64 | case ISD::UREM: Result = PromoteResult_UDIV(N); break; |
| 65 | |
| 66 | case ISD::SHL: Result = PromoteResult_SHL(N); break; |
| 67 | case ISD::SRA: Result = PromoteResult_SRA(N); break; |
| 68 | case ISD::SRL: Result = PromoteResult_SRL(N); break; |
| 69 | |
| 70 | case ISD::SELECT: Result = PromoteResult_SELECT(N); break; |
| 71 | case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break; |
| 72 | |
| 73 | } |
| 74 | |
| 75 | // If Result is null, the sub-method took care of registering the result. |
| 76 | if (Result.Val) |
| 77 | SetPromotedOp(SDOperand(N, ResNo), Result); |
| 78 | } |
| 79 | |
| 80 | SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) { |
| 81 | return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0))); |
| 82 | } |
| 83 | |
| 84 | SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) { |
| 85 | MVT::ValueType VT = N->getValueType(0); |
| 86 | // Zero extend things like i1, sign extend everything else. It shouldn't |
| 87 | // matter in theory which one we pick, but this tends to give better code? |
| 88 | unsigned Opc = VT != MVT::i1 ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; |
| 89 | SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT), |
| 90 | SDOperand(N, 0)); |
| 91 | assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?"); |
| 92 | return Result; |
| 93 | } |
| 94 | |
| 95 | SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) { |
| 96 | SDOperand Res; |
| 97 | |
| 98 | switch (getTypeAction(N->getOperand(0).getValueType())) { |
| 99 | default: assert(0 && "Unknown type action!"); |
| 100 | case Legal: |
| 101 | case Expand: |
| 102 | Res = N->getOperand(0); |
| 103 | break; |
| 104 | case Promote: |
| 105 | Res = GetPromotedOp(N->getOperand(0)); |
| 106 | break; |
| 107 | } |
| 108 | |
| 109 | MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); |
| 110 | assert(MVT::getSizeInBits(Res.getValueType()) >= MVT::getSizeInBits(NVT) && |
| 111 | "Truncation doesn't make sense!"); |
| 112 | if (Res.getValueType() == NVT) |
| 113 | return Res; |
| 114 | |
| 115 | // Truncate to NVT instead of VT |
| 116 | return DAG.getNode(ISD::TRUNCATE, NVT, Res); |
| 117 | } |
| 118 | |
| 119 | SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) { |
| 120 | MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); |
| 121 | |
| 122 | if (getTypeAction(N->getOperand(0).getValueType()) == Promote) { |
| 123 | SDOperand Res = GetPromotedOp(N->getOperand(0)); |
| 124 | assert(MVT::getSizeInBits(Res.getValueType()) <= MVT::getSizeInBits(NVT) && |
| 125 | "Extension doesn't make sense!"); |
| 126 | |
| 127 | // If the result and operand types are the same after promotion, simplify |
| 128 | // to an in-register extension. |
| 129 | if (NVT == Res.getValueType()) { |
| 130 | // The high bits are not guaranteed to be anything. Insert an extend. |
| 131 | if (N->getOpcode() == ISD::SIGN_EXTEND) |
| 132 | return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, |
| 133 | DAG.getValueType(N->getOperand(0).getValueType())); |
| 134 | if (N->getOpcode() == ISD::ZERO_EXTEND) |
| 135 | return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType()); |
| 136 | assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!"); |
| 137 | return Res; |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | // Otherwise, just extend the original operand all the way to the larger type. |
| 142 | return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0)); |
| 143 | } |
| 144 | |
| 145 | SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) { |
| 146 | // NOTE: Assumes input is legal. |
| 147 | return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(), |
| 148 | N->getOperand(0), DAG.getValueType(N->getValueType(0))); |
| 149 | } |
| 150 | |
| 151 | SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) { |
| 152 | SDOperand Op = N->getOperand(0); |
| 153 | // If the operand needed to be promoted, do so now. |
| 154 | if (getTypeAction(Op.getValueType()) == Promote) |
| 155 | // The input result is prerounded, so we don't have to do anything special. |
| 156 | Op = GetPromotedOp(Op); |
| 157 | |
| 158 | unsigned NewOpc = N->getOpcode(); |
| 159 | MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); |
| 160 | |
| 161 | // If we're promoting a UINT to a larger size, check to see if the new node |
| 162 | // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since |
| 163 | // we can use that instead. This allows us to generate better code for |
| 164 | // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not |
| 165 | // legal, such as PowerPC. |
| 166 | if (N->getOpcode() == ISD::FP_TO_UINT) { |
| 167 | if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && |
| 168 | (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || |
| 169 | TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)) |
| 170 | NewOpc = ISD::FP_TO_SINT; |
| 171 | } |
| 172 | |
| 173 | return DAG.getNode(NewOpc, NVT, Op); |
| 174 | } |
| 175 | |
| 176 | SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) { |
| 177 | assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??"); |
| 178 | return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0), |
| 179 | N->getOperand(1), N->getOperand(2)); |
| 180 | } |
| 181 | |
| 182 | SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) { |
| 183 | MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); |
| 184 | ISD::LoadExtType ExtType = |
| 185 | ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); |
| 186 | SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(), |
| 187 | N->getSrcValue(), N->getSrcValueOffset(), |
| 188 | N->getLoadedVT(), N->isVolatile(), |
| 189 | N->getAlignment()); |
| 190 | |
| 191 | // Legalized the chain result - switch anything that used the old chain to |
| 192 | // use the new one. |
| 193 | ReplaceValueWith(SDOperand(N, 1), Res.getValue(1)); |
| 194 | return Res; |
| 195 | } |
| 196 | |
| 197 | SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) { |
| 198 | // The input may have strange things in the top bits of the registers, but |
| 199 | // these operations don't care. They may have weird bits going out, but |
| 200 | // that too is okay if they are integer operations. |
| 201 | SDOperand LHS = GetPromotedOp(N->getOperand(0)); |
| 202 | SDOperand RHS = GetPromotedOp(N->getOperand(1)); |
| 203 | return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); |
| 204 | } |
| 205 | |
| 206 | SDOperand DAGTypeLegalizer::PromoteResult_SDIV(SDNode *N) { |
| 207 | // Sign extend the input. |
| 208 | SDOperand LHS = GetPromotedOp(N->getOperand(0)); |
| 209 | SDOperand RHS = GetPromotedOp(N->getOperand(1)); |
| 210 | MVT::ValueType VT = N->getValueType(0); |
| 211 | LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS, |
| 212 | DAG.getValueType(VT)); |
| 213 | RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS, |
| 214 | DAG.getValueType(VT)); |
| 215 | |
| 216 | return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); |
| 217 | } |
| 218 | |
| 219 | SDOperand DAGTypeLegalizer::PromoteResult_UDIV(SDNode *N) { |
| 220 | // Zero extend the input. |
| 221 | SDOperand LHS = GetPromotedOp(N->getOperand(0)); |
| 222 | SDOperand RHS = GetPromotedOp(N->getOperand(1)); |
| 223 | MVT::ValueType VT = N->getValueType(0); |
| 224 | LHS = DAG.getZeroExtendInReg(LHS, VT); |
| 225 | RHS = DAG.getZeroExtendInReg(RHS, VT); |
| 226 | |
| 227 | return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); |
| 228 | } |
| 229 | |
| 230 | SDOperand DAGTypeLegalizer::PromoteResult_SHL(SDNode *N) { |
| 231 | return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)), |
| 232 | GetPromotedOp(N->getOperand(0)), N->getOperand(1)); |
| 233 | } |
| 234 | |
| 235 | SDOperand DAGTypeLegalizer::PromoteResult_SRA(SDNode *N) { |
| 236 | // The input value must be properly sign extended. |
| 237 | MVT::ValueType VT = N->getValueType(0); |
| 238 | MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); |
| 239 | SDOperand Res = GetPromotedOp(N->getOperand(0)); |
| 240 | Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT)); |
| 241 | return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1)); |
| 242 | } |
| 243 | |
| 244 | SDOperand DAGTypeLegalizer::PromoteResult_SRL(SDNode *N) { |
| 245 | // The input value must be properly zero extended. |
| 246 | MVT::ValueType VT = N->getValueType(0); |
| 247 | MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); |
| 248 | SDOperand Res = GetPromotedZExtOp(N->getOperand(0)); |
| 249 | return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1)); |
| 250 | } |
| 251 | |
| 252 | SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) { |
| 253 | SDOperand LHS = GetPromotedOp(N->getOperand(1)); |
| 254 | SDOperand RHS = GetPromotedOp(N->getOperand(2)); |
| 255 | return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); |
| 256 | } |
| 257 | |
| 258 | SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) { |
| 259 | SDOperand LHS = GetPromotedOp(N->getOperand(2)); |
| 260 | SDOperand RHS = GetPromotedOp(N->getOperand(3)); |
| 261 | return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), |
| 262 | N->getOperand(1), LHS, RHS, N->getOperand(4)); |
| 263 | } |
| 264 | |
| 265 | |
| 266 | //===----------------------------------------------------------------------===// |
| 267 | // Operand Promotion |
| 268 | //===----------------------------------------------------------------------===// |
| 269 | |
| 270 | /// PromoteOperand - This method is called when the specified operand of the |
| 271 | /// specified node is found to need promotion. At this point, all of the result |
| 272 | /// types of the node are known to be legal, but other operands of the node may |
| 273 | /// need promotion or expansion as well as the specified one. |
| 274 | bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) { |
| 275 | DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n"); |
| 276 | SDOperand Res; |
| 277 | switch (N->getOpcode()) { |
| 278 | default: |
| 279 | #ifndef NDEBUG |
| 280 | cerr << "PromoteOperand Op #" << OpNo << ": "; |
| 281 | N->dump(&DAG); cerr << "\n"; |
| 282 | #endif |
| 283 | assert(0 && "Do not know how to promote this operator's operand!"); |
| 284 | abort(); |
| 285 | |
| 286 | case ISD::ANY_EXTEND: Res = PromoteOperand_ANY_EXTEND(N); break; |
| 287 | case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break; |
| 288 | case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break; |
| 289 | case ISD::TRUNCATE: Res = PromoteOperand_TRUNCATE(N); break; |
| 290 | case ISD::FP_EXTEND: Res = PromoteOperand_FP_EXTEND(N); break; |
| 291 | case ISD::FP_ROUND: Res = PromoteOperand_FP_ROUND(N); break; |
| 292 | case ISD::SINT_TO_FP: |
| 293 | case ISD::UINT_TO_FP: Res = PromoteOperand_INT_TO_FP(N); break; |
| 294 | |
| 295 | case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break; |
| 296 | case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break; |
| 297 | case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break; |
| 298 | case ISD::SETCC: Res = PromoteOperand_SETCC(N, OpNo); break; |
| 299 | |
| 300 | case ISD::STORE: Res = PromoteOperand_STORE(cast<StoreSDNode>(N), |
| 301 | OpNo); break; |
| 302 | case ISD::MEMSET: |
| 303 | case ISD::MEMCPY: |
| 304 | case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; |
| 305 | } |
| 306 | |
| 307 | // If the result is null, the sub-method took care of registering results etc. |
| 308 | if (!Res.Val) return false; |
| 309 | // If the result is N, the sub-method updated N in place. |
| 310 | if (Res.Val == N) { |
| 311 | // Mark N as new and remark N and its operands. This allows us to correctly |
| 312 | // revisit N if it needs another step of promotion and allows us to visit |
| 313 | // any new operands to N. |
| 314 | N->setNodeId(NewNode); |
| 315 | MarkNewNodes(N); |
| 316 | return true; |
| 317 | } |
| 318 | |
| 319 | assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && |
| 320 | "Invalid operand expansion"); |
| 321 | |
| 322 | ReplaceValueWith(SDOperand(N, 0), Res); |
| 323 | return false; |
| 324 | } |
| 325 | |
| 326 | SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) { |
| 327 | SDOperand Op = GetPromotedOp(N->getOperand(0)); |
| 328 | return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); |
| 329 | } |
| 330 | |
| 331 | SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) { |
| 332 | SDOperand Op = GetPromotedOp(N->getOperand(0)); |
| 333 | Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); |
| 334 | return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType()); |
| 335 | } |
| 336 | |
| 337 | SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) { |
| 338 | SDOperand Op = GetPromotedOp(N->getOperand(0)); |
| 339 | Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); |
| 340 | return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), |
| 341 | Op, DAG.getValueType(N->getOperand(0).getValueType())); |
| 342 | } |
| 343 | |
| 344 | SDOperand DAGTypeLegalizer::PromoteOperand_TRUNCATE(SDNode *N) { |
| 345 | SDOperand Op = GetPromotedOp(N->getOperand(0)); |
| 346 | return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op); |
| 347 | } |
| 348 | |
| 349 | SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) { |
| 350 | SDOperand Op = GetPromotedOp(N->getOperand(0)); |
| 351 | return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op); |
| 352 | } |
| 353 | |
| 354 | SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) { |
| 355 | SDOperand Op = GetPromotedOp(N->getOperand(0)); |
| 356 | return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op); |
| 357 | } |
| 358 | |
| 359 | SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) { |
| 360 | SDOperand In = GetPromotedOp(N->getOperand(0)); |
| 361 | MVT::ValueType OpVT = N->getOperand(0).getValueType(); |
| 362 | if (N->getOpcode() == ISD::UINT_TO_FP) |
| 363 | In = DAG.getZeroExtendInReg(In, OpVT); |
| 364 | else |
| 365 | In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), |
| 366 | In, DAG.getValueType(OpVT)); |
| 367 | |
| 368 | return DAG.UpdateNodeOperands(SDOperand(N, 0), In); |
| 369 | } |
| 370 | |
| 371 | SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) { |
| 372 | assert(OpNo == 0 && "Only know how to promote condition"); |
| 373 | SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition. |
| 374 | |
| 375 | // The top bits of the promoted condition are not necessarily zero, ensure |
| 376 | // that the value is properly zero extended. |
| 377 | if (!DAG.MaskedValueIsZero(Cond, |
| 378 | MVT::getIntVTBitMask(Cond.getValueType())^1)) { |
| 379 | Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); |
| 380 | MarkNewNodes(Cond.Val); |
| 381 | } |
| 382 | |
| 383 | // The chain (Op#0) and basic block destination (Op#2) are always legal types. |
| 384 | return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1), |
| 385 | N->getOperand(2)); |
| 386 | } |
| 387 | |
| 388 | SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) { |
| 389 | assert(OpNo == 1 && "only know how to promote condition"); |
| 390 | SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition. |
| 391 | |
| 392 | // The top bits of the promoted condition are not necessarily zero, ensure |
| 393 | // that the value is properly zero extended. |
| 394 | if (!DAG.MaskedValueIsZero(Cond, |
| 395 | MVT::getIntVTBitMask(Cond.getValueType())^1)) { |
| 396 | Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); |
| 397 | MarkNewNodes(Cond.Val); |
| 398 | } |
| 399 | |
| 400 | // The chain (Op#0) and basic block destination (Op#2) are always legal types. |
| 401 | return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond, |
| 402 | N->getOperand(2)); |
| 403 | } |
| 404 | |
| 405 | SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) { |
| 406 | assert(OpNo == 2 && "Don't know how to promote this operand"); |
| 407 | |
| 408 | SDOperand LHS = N->getOperand(2); |
| 409 | SDOperand RHS = N->getOperand(3); |
| 410 | PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get()); |
| 411 | |
| 412 | // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always |
| 413 | // legal types. |
| 414 | return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), |
| 415 | N->getOperand(1), LHS, RHS, N->getOperand(4)); |
| 416 | } |
| 417 | |
| 418 | SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) { |
| 419 | assert(OpNo == 0 && "Don't know how to promote this operand"); |
| 420 | |
| 421 | SDOperand LHS = N->getOperand(0); |
| 422 | SDOperand RHS = N->getOperand(1); |
| 423 | PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get()); |
| 424 | |
| 425 | // The CC (#2) is always legal. |
| 426 | return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2)); |
| 427 | } |
| 428 | |
| 429 | /// PromoteSetCCOperands - Promote the operands of a comparison. This code is |
| 430 | /// shared among BR_CC, SELECT_CC, and SETCC handlers. |
| 431 | void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS, |
| 432 | ISD::CondCode CCCode) { |
| 433 | MVT::ValueType VT = NewLHS.getValueType(); |
| 434 | |
| 435 | // Get the promoted values. |
| 436 | NewLHS = GetPromotedOp(NewLHS); |
| 437 | NewRHS = GetPromotedOp(NewRHS); |
| 438 | |
| 439 | // If this is an FP compare, the operands have already been extended. |
| 440 | if (!MVT::isInteger(NewLHS.getValueType())) |
| 441 | return; |
| 442 | |
| 443 | // Otherwise, we have to insert explicit sign or zero extends. Note |
| 444 | // that we could insert sign extends for ALL conditions, but zero extend |
| 445 | // is cheaper on many machines (an AND instead of two shifts), so prefer |
| 446 | // it. |
| 447 | switch (CCCode) { |
| 448 | default: assert(0 && "Unknown integer comparison!"); |
| 449 | case ISD::SETEQ: |
| 450 | case ISD::SETNE: |
| 451 | case ISD::SETUGE: |
| 452 | case ISD::SETUGT: |
| 453 | case ISD::SETULE: |
| 454 | case ISD::SETULT: |
| 455 | // ALL of these operations will work if we either sign or zero extend |
| 456 | // the operands (including the unsigned comparisons!). Zero extend is |
| 457 | // usually a simpler/cheaper operation, so prefer it. |
| 458 | NewLHS = DAG.getZeroExtendInReg(NewLHS, VT); |
| 459 | NewRHS = DAG.getZeroExtendInReg(NewRHS, VT); |
| 460 | return; |
| 461 | case ISD::SETGE: |
| 462 | case ISD::SETGT: |
| 463 | case ISD::SETLT: |
| 464 | case ISD::SETLE: |
| 465 | NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS, |
| 466 | DAG.getValueType(VT)); |
| 467 | NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS, |
| 468 | DAG.getValueType(VT)); |
| 469 | return; |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){ |
| 474 | SDOperand Ch = N->getChain(), Ptr = N->getBasePtr(); |
| 475 | int SVOffset = N->getSrcValueOffset(); |
| 476 | unsigned Alignment = N->getAlignment(); |
| 477 | bool isVolatile = N->isVolatile(); |
| 478 | |
| 479 | SDOperand Val = GetPromotedOp(N->getValue()); // Get promoted value. |
| 480 | |
| 481 | assert(!N->isTruncatingStore() && "Cannot promote this store operand!"); |
| 482 | |
| 483 | // Truncate the value and store the result. |
| 484 | return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(), |
| 485 | SVOffset, N->getStoredVT(), |
| 486 | isVolatile, Alignment); |
| 487 | } |