DAGCombiner.cpp revision 4ebd805c6af9db5099214b463003387691df50e8
1//===-- DAGCombiner.cpp - Implement a DAG node combiner -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Nate Begeman and is distributed under the 6// University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This pass combines dag nodes to form fewer, simpler DAG nodes. It can be run 11// both before and after the DAG is legalized. 12// 13// FIXME: Missing folds 14// sdiv, udiv, srem, urem (X, const) where X is an integer can be expanded into 15// a sequence of multiplies, shifts, and adds. This should be controlled by 16// some kind of hint from the target that int div is expensive. 17// various folds of mulh[s,u] by constants such as -1, powers of 2, etc. 18// 19// FIXME: Should add a corresponding version of fold AND with 20// ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which 21// we don't have yet. 22// 23// FIXME: mul (x, const) -> shifts + adds 24// FIXME: undef values 25// FIXME: zero extend when top bits are 0 -> drop it ? 26// FIXME: make truncate see through SIGN_EXTEND and AND 27// FIXME: sext_in_reg(setcc) on targets that return zero or one, and where 28// EVT != MVT::i1 can drop the sext. 29// FIXME: (or x, c) -> c iff maskedValueIsZero(x, ~c) 30// FIXME: MaskedValueIsZero can see through SRL, so it should be sufficient to: 31//if (N2C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) 32// return DAG.getConstant(0, VT).Val; 33// FIXME: (sra (sra x, c1), c2) -> (sra x, c1+c2) 34// 35//===----------------------------------------------------------------------===// 36 37#define DEBUG_TYPE "dagcombine" 38#include "llvm/ADT/Statistic.h" 39#include "llvm/CodeGen/SelectionDAG.h" 40#include "llvm/Support/MathExtras.h" 41#include "llvm/Target/TargetLowering.h" 42#include <cmath> 43using namespace llvm; 44 45namespace { 46 Statistic<> NodesCombined ("dagcombiner", "Number of dag nodes combined"); 47 48 class DAGCombiner { 49 SelectionDAG &DAG; 50 TargetLowering &TLI; 51 bool AfterLegalize; 52 53 // Worklist of all of the nodes that need to be simplified. 54 std::vector<SDNode*> WorkList; 55 56 /// AddUsersToWorkList - When an instruction is simplified, add all users of 57 /// the instruction to the work lists because they might get more simplified 58 /// now. 59 /// 60 void AddUsersToWorkList(SDNode *N) { 61 for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); 62 UI != UE; ++UI) 63 WorkList.push_back(*UI); 64 } 65 66 /// removeFromWorkList - remove all instances of N from the worklist. 67 void removeFromWorkList(SDNode *N) { 68 WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), N), 69 WorkList.end()); 70 } 71 72 /// visit - call the node-specific routine that knows how to fold each 73 /// particular type of node. 74 SDNode *visit(SDNode *N); 75 76 // Visitation implementation - Implement dag node combining for different 77 // node types. The semantics are as follows: 78 // Return Value: 79 // null - No change was made 80 // otherwise - Node N should be replaced by the returned node. 81 // 82 SDNode *visitTokenFactor(SDNode *N); 83 SDNode *visitAdd(SDNode *N); 84 SDNode *visitSub(SDNode *N); 85 SDNode *visitMul(SDNode *N); 86 SDNode *visitSdiv(SDNode *N); 87 SDNode *visitUdiv(SDNode *N); 88 SDNode *visitSrem(SDNode *N); 89 SDNode *visitUrem(SDNode *N); 90 SDNode *visitMulHiU(SDNode *N); 91 SDNode *visitMulHiS(SDNode *N); 92 SDNode *visitAnd(SDNode *N); 93 SDNode *visitOr(SDNode *N); 94 SDNode *visitXor(SDNode *N); 95 SDNode *visitShl(SDNode *N); 96 SDNode *visitSra(SDNode *N); 97 SDNode *visitSrl(SDNode *N); 98 SDNode *visitCtlz(SDNode *N); 99 SDNode *visitCttz(SDNode *N); 100 SDNode *visitCtpop(SDNode *N); 101 // select 102 // select_cc 103 // setcc 104 SDNode *visitSignExtend(SDNode *N); 105 SDNode *visitZeroExtend(SDNode *N); 106 SDNode *visitSignExtendInReg(SDNode *N); 107 SDNode *visitTruncate(SDNode *N); 108 SDNode *visitSintToFP(SDNode *N); 109 SDNode *visitUintToFP(SDNode *N); 110 SDNode *visitFPToSint(SDNode *N); 111 SDNode *visitFPToUint(SDNode *N); 112 SDNode *visitFPRound(SDNode *N); 113 SDNode *visitFPRoundInReg(SDNode *N); 114 SDNode *visitFPExtend(SDNode *N); 115 SDNode *visitFneg(SDNode *N); 116 SDNode *visitFabs(SDNode *N); 117 SDNode *visitExtLoad(SDNode *N); 118 SDNode *visitSextLoad(SDNode *N); 119 SDNode *visitZextLoad(SDNode *N); 120 SDNode *visitTruncStore(SDNode *N); 121 // brcond 122 // brcondtwoway 123 // br_cc 124 // brtwoway_cc 125public: 126 DAGCombiner(SelectionDAG &D) 127 : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) { 128 // Add all the dag nodes to the worklist. 129 WorkList.insert(WorkList.end(), D.allnodes_begin(), D.allnodes_end()); 130 } 131 132 /// Run - runs the dag combiner on all nodes in the work list 133 void Run(bool RunningAfterLegalize); 134 }; 135} 136 137/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use 138/// this predicate to simplify operations downstream. V and Mask are known to 139/// be the same type. 140static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask, 141 const TargetLowering &TLI) { 142 unsigned SrcBits; 143 if (Mask == 0) return true; 144 145 // If we know the result of a setcc has the top bits zero, use this info. 146 switch (Op.getOpcode()) { 147 case ISD::Constant: 148 return (cast<ConstantSDNode>(Op)->getValue() & Mask) == 0; 149 case ISD::SETCC: 150 return ((Mask & 1) == 0) && 151 TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult; 152 case ISD::ZEXTLOAD: 153 SrcBits = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT()); 154 return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. 155 case ISD::ZERO_EXTEND: 156 SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); 157 return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); 158 case ISD::AssertZext: 159 SrcBits = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT()); 160 return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. 161 case ISD::AND: 162 // (X & C1) & C2 == 0 iff C1 & C2 == 0. 163 if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(Op.getOperand(1))) 164 return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI); 165 // FALL THROUGH 166 case ISD::OR: 167 case ISD::XOR: 168 return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) && 169 MaskedValueIsZero(Op.getOperand(1), Mask, TLI); 170 case ISD::SELECT: 171 return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) && 172 MaskedValueIsZero(Op.getOperand(2), Mask, TLI); 173 case ISD::SELECT_CC: 174 return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) && 175 MaskedValueIsZero(Op.getOperand(3), Mask, TLI); 176 case ISD::SRL: 177 // (ushr X, C1) & C2 == 0 iff X & (C2 << C1) == 0 178 if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 179 uint64_t NewVal = Mask << ShAmt->getValue(); 180 SrcBits = MVT::getSizeInBits(Op.getValueType()); 181 if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1; 182 return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); 183 } 184 return false; 185 case ISD::SHL: 186 // (ushl X, C1) & C2 == 0 iff X & (C2 >> C1) == 0 187 if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 188 uint64_t NewVal = Mask >> ShAmt->getValue(); 189 return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI); 190 } 191 return false; 192 case ISD::CTTZ: 193 case ISD::CTLZ: 194 case ISD::CTPOP: 195 // Bit counting instructions can not set the high bits of the result 196 // register. The max number of bits sets depends on the input. 197 return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0; 198 199 // TODO we could handle some SRA cases here. 200 default: break; 201 } 202 return false; 203} 204 205// isSetCCEquivalent - Return true if this node is a setcc, or is a select_cc 206// that selects between the values 1 and 0, making it equivalent to a setcc. 207static bool isSetCCEquivalent(SDOperand N) { 208 if (N.getOpcode() == ISD::SETCC) 209 return true; 210 if (N.getOpcode() == ISD::SELECT_CC && 211 N.getOperand(2).getOpcode() == ISD::Constant && 212 N.getOperand(3).getOpcode() == ISD::Constant && 213 cast<ConstantSDNode>(N.getOperand(2))->getValue() == 1 && 214 cast<ConstantSDNode>(N.getOperand(3))->isNullValue()) 215 return true; 216 return false; 217} 218 219// isInvertibleForFree - Return true if there is no cost to emitting the logical 220// inverse of this node. 221static bool isInvertibleForFree(SDOperand N) { 222 if (isa<ConstantSDNode>(N.Val)) return true; 223 if (isSetCCEquivalent(N) && N.Val->hasOneUse()) 224 return true; 225 return false; 226} 227 228void DAGCombiner::Run(bool RunningAfterLegalize) { 229 // set the instance variable, so that the various visit routines may use it. 230 AfterLegalize = RunningAfterLegalize; 231 232 // while the worklist isn't empty, inspect the node on the end of it and 233 // try and combine it. 234 while (!WorkList.empty()) { 235 SDNode *N = WorkList.back(); 236 WorkList.pop_back(); 237 238 // If N has no uses, it is dead. Make sure to revisit all N's operands once 239 // N is deleted from the DAG, since they too may now be dead. 240 if (N->use_empty()) { 241 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) 242 WorkList.push_back(N->getOperand(i).Val); 243 244 DAG.DeleteNode(N); 245 removeFromWorkList(N); 246 continue; 247 } 248 249 if (SDNode *Result = visit(N)) { 250 ++NodesCombined; 251 assert(Result != N && "Modifying DAG nodes in place is illegal!"); 252 253 std::cerr << "DC: Old = "; N->dump(); 254 std::cerr << " New = "; Result->dump(); 255 std::cerr << '\n'; 256 DAG.ReplaceAllUsesWith(N, Result); 257 258 // Push the new node and any users onto the worklist 259 WorkList.push_back(Result); 260 AddUsersToWorkList(Result); 261 262 // Nodes can end up on the worklist more than once. Make sure we do 263 // not process a node that has been replaced. 264 removeFromWorkList(N); 265 } 266 } 267} 268 269SDNode *DAGCombiner::visit(SDNode *N) { 270 switch(N->getOpcode()) { 271 default: break; 272 case ISD::TokenFactor: return visitTokenFactor(N); 273 case ISD::ADD: return visitAdd(N); 274 case ISD::SUB: return visitSub(N); 275 case ISD::MUL: return visitMul(N); 276 case ISD::SDIV: return visitSdiv(N); 277 case ISD::UDIV: return visitUdiv(N); 278 case ISD::SREM: return visitSrem(N); 279 case ISD::UREM: return visitUrem(N); 280 case ISD::MULHU: return visitMulHiU(N); 281 case ISD::MULHS: return visitMulHiS(N); 282 case ISD::AND: return visitAnd(N); 283 case ISD::OR: return visitOr(N); 284 case ISD::XOR: return visitXor(N); 285 case ISD::SHL: return visitShl(N); 286 case ISD::SRA: return visitSra(N); 287 case ISD::SRL: return visitSrl(N); 288 case ISD::CTLZ: return visitCtlz(N); 289 case ISD::CTTZ: return visitCttz(N); 290 case ISD::CTPOP: return visitCtpop(N); 291 case ISD::SIGN_EXTEND: return visitSignExtend(N); 292 case ISD::ZERO_EXTEND: return visitZeroExtend(N); 293 case ISD::SIGN_EXTEND_INREG: return visitSignExtendInReg(N); 294 case ISD::TRUNCATE: return visitTruncate(N); 295 case ISD::SINT_TO_FP: return visitSintToFP(N); 296 case ISD::UINT_TO_FP: return visitUintToFP(N); 297 case ISD::FP_TO_SINT: return visitFPToSint(N); 298 case ISD::FP_TO_UINT: return visitFPToUint(N); 299 case ISD::FP_ROUND: return visitFPRound(N); 300 case ISD::FP_ROUND_INREG: return visitFPRoundInReg(N); 301 case ISD::FP_EXTEND: return visitFPExtend(N); 302 case ISD::FNEG: return visitFneg(N); 303 case ISD::FABS: return visitFabs(N); 304 } 305 return 0; 306} 307 308SDNode *DAGCombiner::visitTokenFactor(SDNode *N) { 309 // If the token factor only has one operand, fold TF(x) -> x 310 if (N->getNumOperands() == 1) 311 return N->getOperand(0).Val; 312 313 // If the token factor has two operands and one is the entry token, replace 314 // the token factor with the other operand. 315 if (N->getNumOperands() == 2) { 316 if (N->getOperand(0).getOpcode() == ISD::EntryToken) 317 return N->getOperand(1).Val; 318 if (N->getOperand(1).getOpcode() == ISD::EntryToken) 319 return N->getOperand(0).Val; 320 } 321 return 0; 322} 323 324SDNode *DAGCombiner::visitAdd(SDNode *N) { 325 SDOperand N0 = N->getOperand(0); 326 SDOperand N1 = N->getOperand(1); 327 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 328 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 329 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N0); 330 ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N1); 331 332 // fold (add c1, c2) -> c1+c2 333 if (N1C && N2C) 334 return DAG.getConstant(N1C->getValue() + N2C->getValue(), 335 N->getValueType(0)).Val; 336 // fold (add x, 0) -> x 337 if (N2C && N2C->isNullValue()) 338 return N0.Val; 339 // fold floating point (add c1, c2) -> c1+c2 340 if (N1CFP && N2CFP) 341 return DAG.getConstantFP(N1CFP->getValue() + N2CFP->getValue(), 342 N->getValueType(0)).Val; 343 // fold (A + (-B)) -> A-B 344 if (N1.getOpcode() == ISD::FNEG) 345 return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(0)).Val; 346 // fold ((-A) + B) -> B-A 347 if (N0.getOpcode() == ISD::FNEG) 348 return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(0)).Val; 349 // fold ((0-A) + B) -> B-A 350 if (N0.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N0.getOperand(0)) && 351 cast<ConstantSDNode>(N0.getOperand(0))->isNullValue()) 352 return DAG.getNode(ISD::SUB, N->getValueType(0), N1, N0.getOperand(1)).Val; 353 // fold (A + (0-B)) -> A-B 354 if (N1.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N1.getOperand(0)) && 355 cast<ConstantSDNode>(N1.getOperand(0))->isNullValue()) 356 return DAG.getNode(ISD::SUB, N->getValueType(0), N0, N1.getOperand(1)).Val; 357 // fold (A+(B-A)) -> B for non-fp types 358 if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1) && 359 !MVT::isFloatingPoint(N1.getValueType())) 360 return N1.getOperand(0).Val; 361 return 0; 362} 363 364SDNode *DAGCombiner::visitSub(SDNode *N) { 365 SDOperand N0 = N->getOperand(0); 366 SDOperand N1 = N->getOperand(1); 367 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0.Val); 368 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1.Val); 369 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N0.Val); 370 ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N1.Val); 371 372 // fold (sub c1, c2) -> c1-c2 373 if (N1C && N2C) 374 return DAG.getConstant(N1C->getValue() - N2C->getValue(), 375 N->getValueType(0)).Val; 376 // fold (sub x, 0) -> x 377 if (N2C && N2C->isNullValue()) 378 return N0.Val; 379 // fold floating point (sub c1, c2) -> c1-c2 380 if (N1CFP && N2CFP) 381 return DAG.getConstantFP(N1CFP->getValue() - N2CFP->getValue(), 382 N->getValueType(0)).Val; 383 // fold (A+B)-A -> B 384 if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1 && 385 !MVT::isFloatingPoint(N1.getValueType())) 386 return N0.getOperand(1).Val; 387 // fold (A+B)-B -> A 388 if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 && 389 !MVT::isFloatingPoint(N1.getValueType())) 390 return N0.getOperand(0).Val; 391 // fold (A-(-B)) -> A+B 392 if (N1.getOpcode() == ISD::FNEG) 393 return DAG.getNode(ISD::ADD, N0.getValueType(), N0, N1.getOperand(0)).Val; 394 return 0; 395} 396 397SDNode *DAGCombiner::visitMul(SDNode *N) { 398 SDOperand N0 = N->getOperand(0); 399 SDOperand N1 = N->getOperand(1); 400 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 401 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 402 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N0); 403 ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N1); 404 405 // fold (mul c1, c2) -> c1*c2 406 if (N1C && N2C) 407 return DAG.getConstant(N1C->getValue() * N2C->getValue(), 408 N->getValueType(0)).Val; 409 // fold (mul x, 0) -> 0 410 if (N2C && N2C->isNullValue()) 411 return N1.Val; 412 // fold (mul x, -1) -> 0-x 413 if (N2C && N2C->isAllOnesValue()) 414 return DAG.getNode(ISD::SUB, N->getValueType(0), 415 DAG.getConstant(0, N->getValueType(0)), N0).Val; 416 // fold (mul x, (1 << c)) -> x << c 417 if (N2C && isPowerOf2_64(N2C->getValue())) 418 return DAG.getNode(ISD::SHL, N->getValueType(0), N0, 419 DAG.getConstant(Log2_64(N2C->getValue()), 420 TLI.getShiftAmountTy())).Val; 421 // fold floating point (mul c1, c2) -> c1*c2 422 if (N1CFP && N2CFP) 423 return DAG.getConstantFP(N1CFP->getValue() * N2CFP->getValue(), 424 N->getValueType(0)).Val; 425 return 0; 426} 427 428SDNode *DAGCombiner::visitSdiv(SDNode *N) { 429 SDOperand N0 = N->getOperand(0); 430 SDOperand N1 = N->getOperand(1); 431 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0.Val); 432 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1.Val); 433 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N0.Val); 434 ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N1.Val); 435 436 // fold (sdiv c1, c2) -> c1/c2 437 if (N1C && N2C) 438 return DAG.getConstant(N1C->getSignExtended() / N2C->getSignExtended(), 439 N->getValueType(0)).Val; 440 // fold floating point (sdiv c1, c2) -> c1/c2 441 if (N1CFP && N2CFP) 442 return DAG.getConstantFP(N1CFP->getValue() / N2CFP->getValue(), 443 N->getValueType(0)).Val; 444 return 0; 445} 446 447SDNode *DAGCombiner::visitUdiv(SDNode *N) { 448 SDOperand N0 = N->getOperand(0); 449 SDOperand N1 = N->getOperand(1); 450 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0.Val); 451 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1.Val); 452 453 // fold (udiv c1, c2) -> c1/c2 454 if (N1C && N2C) 455 return DAG.getConstant(N1C->getValue() / N2C->getValue(), 456 N->getValueType(0)).Val; 457 // fold (udiv x, (1 << c)) -> x >>u c 458 if (N2C && isPowerOf2_64(N2C->getValue())) 459 return DAG.getNode(ISD::SRL, N->getValueType(0), N0, 460 DAG.getConstant(Log2_64(N2C->getValue()), 461 TLI.getShiftAmountTy())).Val; 462 return 0; 463} 464 465SDNode *DAGCombiner::visitSrem(SDNode *N) { 466 SDOperand N0 = N->getOperand(0); 467 SDOperand N1 = N->getOperand(1); 468 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 469 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 470 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N0); 471 ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N1); 472 473 // fold (srem c1, c2) -> c1%c2 474 if (N1C && N2C) 475 return DAG.getConstant(N1C->getSignExtended() % N2C->getSignExtended(), 476 N->getValueType(0)).Val; 477 // fold floating point (srem c1, c2) -> fmod(c1, c2) 478 if (N1CFP && N2CFP) 479 return DAG.getConstantFP(fmod(N1CFP->getValue(),N2CFP->getValue()), 480 N->getValueType(0)).Val; 481 return 0; 482} 483 484SDNode *DAGCombiner::visitUrem(SDNode *N) { 485 SDOperand N0 = N->getOperand(0); 486 SDOperand N1 = N->getOperand(1); 487 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 488 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 489 490 // fold (urem c1, c2) -> c1%c2 491 if (N1C && N2C) 492 return DAG.getConstant(N1C->getValue() % N2C->getValue(), 493 N->getValueType(0)).Val; 494 return 0; 495} 496 497SDNode *DAGCombiner::visitMulHiS(SDNode *N) { 498 SDOperand N0 = N->getOperand(0); 499 SDOperand N1 = N->getOperand(1); 500 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 501 502 // fold (mulhs x, 0) -> 0 503 if (N2C && N2C->isNullValue()) 504 return N1.Val; 505 506 // fold (mulhs x, 1) -> (sra x, size(x)-1) 507 if (N2C && N2C->getValue() == 1) 508 return DAG.getNode(ISD::SRA, N0.getValueType(), N0, 509 DAG.getConstant(MVT::getSizeInBits(N0.getValueType())-1, 510 TLI.getShiftAmountTy())).Val; 511 return 0; 512} 513 514SDNode *DAGCombiner::visitMulHiU(SDNode *N) { 515 SDOperand N0 = N->getOperand(0); 516 SDOperand N1 = N->getOperand(1); 517 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 518 519 // fold (mulhu x, 0) -> 0 520 if (N2C && N2C->isNullValue()) 521 return N1.Val; 522 523 // fold (mulhu x, 1) -> 0 524 if (N2C && N2C->getValue() == 1) 525 return DAG.getConstant(0, N0.getValueType()).Val; 526 return 0; 527} 528 529SDNode *DAGCombiner::visitAnd(SDNode *N) { 530 SDOperand N0 = N->getOperand(0); 531 SDOperand N1 = N->getOperand(1); 532 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 533 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 534 MVT::ValueType VT = N1.getValueType(); 535 536 // fold (and c1, c2) -> c1&c2 537 if (N1C && N2C) 538 return DAG.getConstant(N1C->getValue() & N2C->getValue(), VT).Val; 539 // fold (and x, -1) -> x 540 if (N2C && N2C->isAllOnesValue()) 541 return N0.Val; 542 // fold (and x, 0) -> 0 543 if (N2C && MaskedValueIsZero(N0, N2C->getValue(), TLI)) 544 return DAG.getConstant(0, VT).Val; 545 // fold (and x, mask containing x) -> x 546 if (N2C) { 547 uint64_t NotC2 = ~N2C->getValue(); 548 NotC2 &= ~0ULL >> (64-MVT::getSizeInBits(VT)); 549 if (MaskedValueIsZero(N0, NotC2, TLI)) 550 return N0.Val; 551 } 552 // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) 553 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { 554 unsigned ExtendBits = 555 MVT::getSizeInBits(cast<VTSDNode>(N0.getOperand(1))->getVT()); 556 if ((N2C->getValue() & (~0ULL << ExtendBits)) == 0) 557 return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1).Val; 558 } 559 // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF 560 if (N0.getOpcode() == ISD::OR) 561 if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N0.getOperand(1))) 562 if ((ORI->getValue() & N2C->getValue()) == N2C->getValue()) 563 return N1.Val; 564 return 0; 565} 566 567SDNode *DAGCombiner::visitOr(SDNode *N) { 568 SDOperand N0 = N->getOperand(0); 569 SDOperand N1 = N->getOperand(1); 570 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 571 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 572 573 // fold (or c1, c2) -> c1|c2 574 if (N1C && N2C) 575 return DAG.getConstant(N1C->getValue() | N2C->getValue(), 576 N->getValueType(0)).Val; 577 // fold (or x, 0) -> x 578 if (N2C && N2C->isNullValue()) 579 return N0.Val; 580 // fold (or x, -1) -> -1 581 if (N2C && N2C->isAllOnesValue()) 582 return N1.Val; 583 return 0; 584} 585 586SDNode *DAGCombiner::visitXor(SDNode *N) { 587 SDOperand N0 = N->getOperand(0); 588 SDOperand N1 = N->getOperand(1); 589 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 590 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 591 MVT::ValueType VT = N0.getValueType(); 592 593 // fold (xor c1, c2) -> c1^c2 594 if (N1C && N2C) 595 return DAG.getConstant(N1C->getValue() ^ N2C->getValue(), VT).Val; 596 // fold (xor x, 0) -> x 597 if (N2C && N2C->isNullValue()) 598 return N0.Val; 599 // fold !(x cc y) -> (x !cc y) 600 if (N2C && N2C->getValue() == 1 && N0.getOpcode() == ISD::SETCC) { 601 bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); 602 ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get(); 603 return DAG.getSetCC(VT, N0.getOperand(0), N0.getOperand(1), 604 ISD::getSetCCInverse(CC, isInt)).Val; 605 } 606 // fold !(x cc y) -> (x !cc y) 607 if (N2C && N2C->getValue() == 1 && isSetCCEquivalent(N0)) { 608 bool isInt = MVT::isInteger(N0.getOperand(0).getValueType()); 609 ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(4))->get(); 610 return DAG.getSelectCC(N0.getOperand(0), N0.getOperand(1), 611 N0.getOperand(2), N0.getOperand(3), 612 ISD::getSetCCInverse(CC, isInt)).Val; 613 } 614 // fold !(x or y) -> (!x and !y) iff x or y are freely invertible 615 if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::OR) { 616 SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); 617 if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { 618 LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS 619 RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS 620 return DAG.getNode(ISD::AND, VT, LHS, RHS).Val; 621 } 622 } 623 // fold !(x and y) -> (!x or !y) iff x or y are freely invertible 624 if (N2C && N2C->isAllOnesValue() && N0.getOpcode() == ISD::AND) { 625 SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1); 626 if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) { 627 LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS 628 RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS 629 return DAG.getNode(ISD::OR, VT, LHS, RHS).Val; 630 } 631 } 632 return 0; 633} 634 635SDNode *DAGCombiner::visitShl(SDNode *N) { 636 SDOperand N0 = N->getOperand(0); 637 SDOperand N1 = N->getOperand(1); 638 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 639 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 640 MVT::ValueType VT = N0.getValueType(); 641 unsigned OpSizeInBits = MVT::getSizeInBits(VT); 642 643 // fold (shl c1, c2) -> c1<<c2 644 if (N1C && N2C) 645 return DAG.getConstant(N1C->getValue() << N2C->getValue(), VT).Val; 646 // fold (shl 0, x) -> 0 647 if (N1C && N1C->isNullValue()) 648 return N0.Val; 649 // fold (shl x, c >= size(x)) -> undef 650 if (N2C && N2C->getValue() >= OpSizeInBits) 651 return DAG.getNode(ISD::UNDEF, VT).Val; 652 // fold (shl x, 0) -> x 653 if (N2C && N2C->isNullValue()) 654 return N0.Val; 655 // if (shl x, c) is known to be zero, return 0 656 if (N2C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))>>N2C->getValue(), 657 TLI)) 658 return DAG.getConstant(0, VT).Val; 659 // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2) 660 if (N2C && N0.getOpcode() == ISD::SHL && 661 N0.getOperand(1).getOpcode() == ISD::Constant) { 662 uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getValue(); 663 uint64_t c2 = N2C->getValue(); 664 if (c1 + c2 > OpSizeInBits) 665 return DAG.getConstant(0, VT).Val; 666 return DAG.getNode(ISD::SHL, VT, N0.getOperand(0), 667 DAG.getConstant(c1 + c2, N1.getValueType())).Val; 668 } 669 // fold (shl (srl x, c1), c2) -> (shl (and x, -1 << c1), c2-c1) or 670 // (srl (and x, -1 << c1), c1-c2) 671 if (N2C && N0.getOpcode() == ISD::SRL && 672 N0.getOperand(1).getOpcode() == ISD::Constant) { 673 uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getValue(); 674 uint64_t c2 = N2C->getValue(); 675 SDOperand Mask = DAG.getNode(ISD::AND, VT, N0.getOperand(0), 676 DAG.getConstant(~0ULL << c1, VT)); 677 if (c2 > c1) 678 return DAG.getNode(ISD::SHL, VT, Mask, 679 DAG.getConstant(c2-c1, N1.getValueType())).Val; 680 else 681 return DAG.getNode(ISD::SRL, VT, Mask, 682 DAG.getConstant(c1-c2, N1.getValueType())).Val; 683 } 684 // fold (shl (sra x, c1), c1) -> (and x, -1 << c1) 685 if (N2C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) 686 return DAG.getNode(ISD::AND, VT, N0.getOperand(0), 687 DAG.getConstant(~0ULL << N2C->getValue(), VT)).Val; 688 return 0; 689} 690 691SDNode *DAGCombiner::visitSra(SDNode *N) { 692 SDOperand N0 = N->getOperand(0); 693 SDOperand N1 = N->getOperand(1); 694 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 695 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 696 MVT::ValueType VT = N0.getValueType(); 697 unsigned OpSizeInBits = MVT::getSizeInBits(VT); 698 699 // fold (sra c1, c2) -> c1>>c2 700 if (N1C && N2C) 701 return DAG.getConstant(N1C->getSignExtended() >> N2C->getValue(), VT).Val; 702 // fold (sra 0, x) -> 0 703 if (N1C && N1C->isNullValue()) 704 return N0.Val; 705 // fold (sra -1, x) -> -1 706 if (N1C && N1C->isAllOnesValue()) 707 return N0.Val; 708 // fold (sra x, c >= size(x)) -> undef 709 if (N2C && N2C->getValue() >= OpSizeInBits) 710 return DAG.getNode(ISD::UNDEF, VT).Val; 711 // fold (sra x, 0) -> x 712 if (N2C && N2C->isNullValue()) 713 return N0.Val; 714 // If the sign bit is known to be zero, switch this to a SRL. 715 if (N2C && MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI)) 716 return DAG.getNode(ISD::SRL, VT, N0, N1).Val; 717 return 0; 718} 719 720SDNode *DAGCombiner::visitSrl(SDNode *N) { 721 SDOperand N0 = N->getOperand(0); 722 SDOperand N1 = N->getOperand(1); 723 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 724 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N1); 725 MVT::ValueType VT = N0.getValueType(); 726 unsigned OpSizeInBits = MVT::getSizeInBits(VT); 727 728 // fold (srl c1, c2) -> c1 >>u c2 729 if (N1C && N2C) 730 return DAG.getConstant(N1C->getValue() >> N2C->getValue(), VT).Val; 731 // fold (srl 0, x) -> 0 732 if (N1C && N1C->isNullValue()) 733 return N0.Val; 734 // fold (srl x, c >= size(x)) -> undef 735 if (N2C && N2C->getValue() >= OpSizeInBits) 736 return DAG.getNode(ISD::UNDEF, VT).Val; 737 // fold (srl x, 0) -> x 738 if (N2C && N2C->isNullValue()) 739 return N0.Val; 740 // if (srl x, c) is known to be zero, return 0 741 if (N2C && MaskedValueIsZero(N0,(~0ULL >> (64-OpSizeInBits))<<N2C->getValue(), 742 TLI)) 743 return DAG.getConstant(0, VT).Val; 744 // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2) 745 if (N2C && N0.getOpcode() == ISD::SRL && 746 N0.getOperand(1).getOpcode() == ISD::Constant) { 747 uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getValue(); 748 uint64_t c2 = N2C->getValue(); 749 if (c1 + c2 > OpSizeInBits) 750 return DAG.getConstant(0, VT).Val; 751 return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), 752 DAG.getConstant(c1 + c2, N1.getValueType())).Val; 753 } 754 return 0; 755} 756 757SDNode *DAGCombiner::visitCtlz(SDNode *N) { 758 SDOperand N0 = N->getOperand(0); 759 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 760 761 // fold (ctlz c1) -> c2 762 if (N1C) 763 return DAG.getConstant(CountLeadingZeros_64(N1C->getValue()), 764 N0.getValueType()).Val; 765 return 0; 766} 767 768SDNode *DAGCombiner::visitCttz(SDNode *N) { 769 SDOperand N0 = N->getOperand(0); 770 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 771 772 // fold (cttz c1) -> c2 773 if (N1C) 774 return DAG.getConstant(CountTrailingZeros_64(N1C->getValue()), 775 N0.getValueType()).Val; 776 return 0; 777} 778 779SDNode *DAGCombiner::visitCtpop(SDNode *N) { 780 SDOperand N0 = N->getOperand(0); 781 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 782 783 // fold (ctpop c1) -> c2 784 if (N1C) 785 return DAG.getConstant(CountPopulation_64(N1C->getValue()), 786 N0.getValueType()).Val; 787 return 0; 788} 789 790SDNode *DAGCombiner::visitSignExtend(SDNode *N) { 791 SDOperand N0 = N->getOperand(0); 792 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 793 MVT::ValueType VT = N->getValueType(0); 794 795 // fold (sext c1) -> c1 796 if (N1C) 797 return DAG.getConstant(N1C->getSignExtended(), VT).Val; 798 // fold (sext (sext x)) -> (sext x) 799 if (N0.getOpcode() == ISD::SIGN_EXTEND) 800 return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)).Val; 801 return 0; 802} 803 804SDNode *DAGCombiner::visitZeroExtend(SDNode *N) { 805 SDOperand N0 = N->getOperand(0); 806 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 807 MVT::ValueType VT = N->getValueType(0); 808 809 // fold (zext c1) -> c1 810 if (N1C) 811 return DAG.getConstant(N1C->getValue(), VT).Val; 812 // fold (zext (zext x)) -> (zext x) 813 if (N0.getOpcode() == ISD::ZERO_EXTEND) 814 return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0)).Val; 815 return 0; 816} 817 818SDNode *DAGCombiner::visitSignExtendInReg(SDNode *N) { 819 SDOperand N0 = N->getOperand(0); 820 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 821 MVT::ValueType VT = N->getValueType(0); 822 MVT::ValueType EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 823 824 // fold (sext_in_reg c1) -> c1 825 if (N1C) { 826 SDOperand Truncate = DAG.getConstant(N1C->getValue(), EVT); 827 return DAG.getNode(ISD::SIGN_EXTEND, VT, Truncate).Val; 828 } 829 // fold (sext_in_reg (sext_in_reg x)) -> (sext_in_reg x) 830 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && 831 cast<VTSDNode>(N0.getOperand(1))->getVT() <= EVT) { 832 return N0.Val; 833 } 834 // fold (sext_in_reg (assert_sext x)) -> (assert_sext x) 835 if (N0.getOpcode() == ISD::AssertSext && 836 cast<VTSDNode>(N0.getOperand(1))->getVT() <= EVT) { 837 return N0.Val; 838 } 839 // fold (sext_in_reg (sextload x)) -> (sextload x) 840 if (N0.getOpcode() == ISD::SEXTLOAD && 841 cast<VTSDNode>(N0.getOperand(3))->getVT() <= EVT) { 842 return N0.Val; 843 } 844 // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1 845 if (N0.getOpcode() == ISD::SETCC && 846 TLI.getSetCCResultContents() == 847 TargetLowering::ZeroOrNegativeOneSetCCResult) 848 return N0.Val; 849 // FIXME: this code is currently just ported over from SelectionDAG.cpp 850 // we probably actually want to handle this in two pieces. Rather than 851 // checking all the top bits for zero, just check the sign bit here and turn 852 // it into a zero extend inreg (AND with constant). 853 // then, let the code for AND figure out if the mask is superfluous rather 854 // than doing so here. 855 if (N0.getOpcode() == ISD::AND && 856 N0.getOperand(1).getOpcode() == ISD::Constant) { 857 uint64_t Mask = cast<ConstantSDNode>(N0.getOperand(1))->getValue(); 858 unsigned NumBits = MVT::getSizeInBits(EVT); 859 if ((Mask & (~0ULL << (NumBits-1))) == 0) 860 return N0.Val; 861 } 862 return 0; 863} 864 865SDNode *DAGCombiner::visitTruncate(SDNode *N) { 866 SDOperand N0 = N->getOperand(0); 867 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 868 MVT::ValueType VT = N->getValueType(0); 869 870 // noop truncate 871 if (N0.getValueType() == N->getValueType(0)) 872 return N0.Val; 873 // fold (truncate c1) -> c1 874 if (N1C) 875 return DAG.getConstant(N1C->getValue(), VT).Val; 876 // fold (truncate (truncate x)) -> (truncate x) 877 if (N0.getOpcode() == ISD::TRUNCATE) 878 return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; 879 // fold (truncate (ext x)) -> (ext x) or (truncate x) or x 880 if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND){ 881 if (N0.getValueType() < VT) 882 // if the source is smaller than the dest, we still need an extend 883 return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0)).Val; 884 else if (N0.getValueType() > VT) 885 // if the source is larger than the dest, than we just need the truncate 886 return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)).Val; 887 else 888 // if the source and dest are the same type, we can drop both the extend 889 // and the truncate 890 return N0.getOperand(0).Val; 891 } 892 return 0; 893} 894 895SDNode *DAGCombiner::visitSintToFP(SDNode *N) { 896 SDOperand N0 = N->getOperand(0); 897 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 898 MVT::ValueType VT = N->getValueType(0); 899 900 // fold (sint_to_fp c1) -> c1fp 901 if (N1C) 902 return DAG.getConstantFP(N1C->getSignExtended(), VT).Val; 903 return 0; 904} 905 906SDNode *DAGCombiner::visitUintToFP(SDNode *N) { 907 SDOperand N0 = N->getOperand(0); 908 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N0); 909 MVT::ValueType VT = N->getValueType(0); 910 911 // fold (uint_to_fp c1) -> c1fp 912 if (N1C) 913 return DAG.getConstantFP(N1C->getValue(), VT).Val; 914 return 0; 915} 916 917SDNode *DAGCombiner::visitFPToSint(SDNode *N) { 918 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)); 919 920 // fold (fp_to_sint c1fp) -> c1 921 if (N1CFP) 922 return DAG.getConstant((int64_t)N1CFP->getValue(), N->getValueType(0)).Val; 923 return 0; 924} 925 926SDNode *DAGCombiner::visitFPToUint(SDNode *N) { 927 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)); 928 929 // fold (fp_to_uint c1fp) -> c1 930 if (N1CFP) 931 return DAG.getConstant((uint64_t)N1CFP->getValue(), N->getValueType(0)).Val; 932 return 0; 933} 934 935SDNode *DAGCombiner::visitFPRound(SDNode *N) { 936 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)); 937 938 // fold (fp_round c1fp) -> c1fp 939 if (N1CFP) 940 return DAG.getConstantFP(N1CFP->getValue(), N->getValueType(0)).Val; 941 return 0; 942} 943 944SDNode *DAGCombiner::visitFPRoundInReg(SDNode *N) { 945 SDOperand N0 = N->getOperand(0); 946 MVT::ValueType VT = N->getValueType(0); 947 MVT::ValueType EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 948 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N0); 949 950 // noop fp_round_inreg 951 if (EVT == VT) 952 return N0.Val; 953 // fold (fp_round_inreg c1fp) -> c1fp 954 if (N1CFP) { 955 SDOperand Round = DAG.getConstantFP(N1CFP->getValue(), EVT); 956 return DAG.getNode(ISD::FP_EXTEND, VT, Round).Val; 957 } 958 return 0; 959} 960 961SDNode *DAGCombiner::visitFPExtend(SDNode *N) { 962 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)); 963 964 // fold (fp_extend c1fp) -> c1fp 965 if (N1CFP) 966 return DAG.getConstantFP(N1CFP->getValue(), N->getValueType(0)).Val; 967 return 0; 968} 969 970SDNode *DAGCombiner::visitFneg(SDNode *N) { 971 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)); 972 // fold (neg c1) -> -c1 973 if (N1CFP) 974 return DAG.getConstantFP(-N1CFP->getValue(), N->getValueType(0)).Val; 975 // fold (neg (sub x, y)) -> (sub y, x) 976 if (N->getOperand(0).getOpcode() == ISD::SUB) 977 return DAG.getNode(ISD::SUB, N->getValueType(0), N->getOperand(1), 978 N->getOperand(0)).Val; 979 // fold (neg (neg x)) -> x 980 if (N->getOperand(0).getOpcode() == ISD::FNEG) 981 return N->getOperand(0).getOperand(0).Val; 982 return 0; 983} 984 985SDNode *DAGCombiner::visitFabs(SDNode *N) { 986 ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0)); 987 // fold (fabs c1) -> fabs(c1) 988 if (N1CFP) 989 return DAG.getConstantFP(fabs(N1CFP->getValue()), N->getValueType(0)).Val; 990 // fold (fabs (fabs x)) -> (fabs x) 991 if (N->getOperand(0).getOpcode() == ISD::FABS) 992 return N->getOperand(0).Val; 993 // fold (fabs (fneg x)) -> (fabs x) 994 if (N->getOperand(0).getOpcode() == ISD::FNEG) 995 return DAG.getNode(ISD::FABS, N->getValueType(0), 996 N->getOperand(0).getOperand(0)).Val; 997 return 0; 998} 999 1000// SelectionDAG::Combine - This is the entry point for the file. 1001// 1002void SelectionDAG::Combine(bool RunningAfterLegalize) { 1003 /// run - This is the main entry point to this class. 1004 /// 1005 DAGCombiner(*this).Run(RunningAfterLegalize); 1006} 1007