LegalizeIntegerTypes.cpp revision b3e009a165a423536acfa5861c12ef631239d9e4
169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===//
2cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
3cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//                     The LLVM Compiler Infrastructure
4cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
8cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
9cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
1069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// This file implements integer type expansion and promotion for LegalizeTypes.
1169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// Promotion is the act of changing a computation in an illegal type into a
1269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// computation in a larger type.  For example, implementing i8 arithmetic in an
1369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// i32 register (often needed on powerpc).
1469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// Expansion is the act of changing a computation in an illegal type into a
1578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// computation in two identical registers of a smaller type.  For example,
1669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// implementing i64 arithmetic in two i32 registers (often needed on 32-bit
1769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// targets).
18cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
19cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
20cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
21cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#include "LegalizeTypes.h"
22c82bf9b268eb63f7cf6f435d9ea222ddb8e3c5a8Mon P Wang#include "llvm/CodeGen/PseudoSourceValue.h"
237d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h"
24fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman#include "llvm/Support/raw_ostream.h"
25cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattnerusing namespace llvm;
26cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
27cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
2869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Result Promotion
29cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
30cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
3169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// PromoteIntegerResult - This method is called when a result of a node is
3269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// found to be in need of promotion to a larger type.  At this point, the node
3369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// may also have invalid operands or may have other results that need
3469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// expansion, we just know that (at least) one result needs promotion.
3569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
36d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Promote integer result: "; N->dump(&DAG); dbgs() << "\n");
379fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  SDValue Res = SDValue();
3869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
39126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands  // See if the target wants to custom expand this node.
40f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getValueType(ResNo), true))
411607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands    return;
42126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands
4369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (N->getOpcode()) {
4469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  default:
4569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands#ifndef NDEBUG
46d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "PromoteIntegerResult #" << ResNo << ": ";
47d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
4869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands#endif
49c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to promote this operator!");
509fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::AssertSext:  Res = PromoteIntRes_AssertSext(N); break;
519fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::AssertZext:  Res = PromoteIntRes_AssertZext(N); break;
52bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:     Res = PromoteIntRes_BITCAST(N); break;
539fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BSWAP:       Res = PromoteIntRes_BSWAP(N); break;
549fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BUILD_PAIR:  Res = PromoteIntRes_BUILD_PAIR(N); break;
559fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::Constant:    Res = PromoteIntRes_Constant(N); break;
5600ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  case ISD::CONVERT_RNDSAT:
579fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_CONVERT_RNDSAT(N); break;
589fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTLZ:        Res = PromoteIntRes_CTLZ(N); break;
599fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTPOP:       Res = PromoteIntRes_CTPOP(N); break;
609fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTTZ:        Res = PromoteIntRes_CTTZ(N); break;
61bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  case ISD::EXTRACT_VECTOR_ELT:
629fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break;
639fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::LOAD:        Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N));break;
649fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SELECT:      Res = PromoteIntRes_SELECT(N); break;
659fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SELECT_CC:   Res = PromoteIntRes_SELECT_CC(N); break;
669fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SETCC:       Res = PromoteIntRes_SETCC(N); break;
679fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SHL:         Res = PromoteIntRes_SHL(N); break;
688d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands  case ISD::SIGN_EXTEND_INREG:
699fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break;
709fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SRA:         Res = PromoteIntRes_SRA(N); break;
719fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SRL:         Res = PromoteIntRes_SRL(N); break;
729fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::TRUNCATE:    Res = PromoteIntRes_TRUNCATE(N); break;
739fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UNDEF:       Res = PromoteIntRes_UNDEF(N); break;
749fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::VAARG:       Res = PromoteIntRes_VAARG(N); break;
75bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
76fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::EXTRACT_SUBVECTOR:
77fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_EXTRACT_SUBVECTOR(N); break;
78fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::VECTOR_SHUFFLE:
79fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_VECTOR_SHUFFLE(N); break;
80fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::INSERT_VECTOR_ELT:
81fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_INSERT_VECTOR_ELT(N); break;
82fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::BUILD_VECTOR:
83fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_BUILD_VECTOR(N); break;
84fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::SCALAR_TO_VECTOR:
85fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_SCALAR_TO_VECTOR(N); break;
86fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
8769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SIGN_EXTEND:
8869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ZERO_EXTEND:
899fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::ANY_EXTEND:  Res = PromoteIntRes_INT_EXTEND(N); break;
90bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
9169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_SINT:
929fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::FP_TO_UINT:  Res = PromoteIntRes_FP_TO_XINT(N); break;
9369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
94927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  case ISD::FP32_TO_FP16:Res = PromoteIntRes_FP32_TO_FP16(N); break;
95927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
9669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::AND:
9769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::OR:
9869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::XOR:
9969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ADD:
10069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SUB:
1019fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::MUL:         Res = PromoteIntRes_SimpleIntBinOp(N); break;
10269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
10369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SDIV:
1049fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SREM:        Res = PromoteIntRes_SDIV(N); break;
10569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
10669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::UDIV:
1079fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UREM:        Res = PromoteIntRes_UDIV(N); break;
1088ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
109253174bf50c932abaa680f465e2888c0e5272267Bill Wendling  case ISD::SADDO:
1109fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SSUBO:       Res = PromoteIntRes_SADDSUBO(N, ResNo); break;
11174c376529101acbe141a256d0bf23a44eb454c84Bill Wendling  case ISD::UADDO:
1129fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::USUBO:       Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
11374c376529101acbe141a256d0bf23a44eb454c84Bill Wendling  case ISD::SMULO:
1149fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UMULO:       Res = PromoteIntRes_XMULO(N, ResNo); break;
115b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
1160b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_ADD:
1170b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_SUB:
1180b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_AND:
1190b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_OR:
1200b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_XOR:
1210b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_NAND:
1220b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_MIN:
1230b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_MAX:
1240b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_UMIN:
1250b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_UMAX:
1260b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_SWAP:
1279fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break;
128b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
1290b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_CMP_SWAP:
1309fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    Res = PromoteIntRes_Atomic2(cast<AtomicSDNode>(N)); break;
13169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
13269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1339fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  // If the result is null then the sub-method took care of registering it.
1349fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  if (Res.getNode())
1359fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    SetPromotedInteger(SDValue(N, ResNo), Res);
13669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
13769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
138475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
13995db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  // Sign-extend the new bits, and continue the assertion.
140c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = SExtPromotedInteger(N->getOperand(0));
141786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::AssertSext, N->getDebugLoc(),
142786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
14395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
14495db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
145475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
14695db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  // Zero the new bits, and continue the assertion.
147c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
148786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::AssertZext, N->getDebugLoc(),
149786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
15095db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
15195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
152b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
153b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
1547fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
155786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                              N->getMemoryVT(),
1560b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman                              N->getChain(), N->getBasePtr(),
1570531356e4da1451b1b0b9e8c85365c2a58ca8282Chris Lattner                              Op2, N->getMemOperand());
158b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
159b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // use the new one.
160b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
161b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  return Res;
162b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands}
163b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
164b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) {
165b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
166b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op3 = GetPromotedInteger(N->getOperand(3));
167fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
168f8d3ec2c5725a2010f11de4ba78f6127712a5fe7Dale Johannesen                              N->getMemoryVT(), N->getChain(), N->getBasePtr(),
1690531356e4da1451b1b0b9e8c85365c2a58ca8282Chris Lattner                              Op2, Op3, N->getMemOperand());
170b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
171b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // use the new one.
172b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
173b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  return Res;
174b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands}
175b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
176bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) {
177475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InOp = N->getOperand(0);
178e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT InVT = InOp.getValueType();
17923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
180e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OutVT = N->getValueType(0);
18123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
182786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
18369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
18469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (getTypeAction(InVT)) {
18569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  default:
18669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    assert(false && "Unknown type action!");
18769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
18896e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeLegal:
18969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
19096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypePromoteInteger:
19147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands    if (NOutVT.bitsEq(NInVT))
19269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands      // The input promotes to the same size.  Convert the promoted value.
193bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetPromotedInteger(InOp));
194fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    if (NInVT.isVector())
195fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      // Promote vector element via memory load/store.
196fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
197fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         CreateStackStoreLoad(InOp, OutVT));
19869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
19996e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeSoftenFloat:
20069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Promote the integer operand by hand.
201786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
20296e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeExpandInteger:
20396e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeExpandFloat:
20469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
20596e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeScalarizeVector:
20669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Convert the element to an integer and promote it by hand.
207786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
20869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                       BitConvertToInteger(GetScalarizedVector(InOp)));
20996e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeSplitVector: {
210bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // For example, i32 = BITCAST v2i16 on alpha.  Convert the split
21169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // pieces of the input into integers and reassemble in the final type.
212475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
21369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetSplitVector(N->getOperand(0), Lo, Hi);
21469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    Lo = BitConvertToInteger(Lo);
21569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    Hi = BitConvertToInteger(Hi);
21669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
21769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    if (TLI.isBigEndian())
21869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands      std::swap(Lo, Hi);
21969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
220786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    InOp = DAG.getNode(ISD::ANY_EXTEND, dl,
221adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                       EVT::getIntegerVT(*DAG.getContext(),
222adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                                         NOutVT.getSizeInBits()),
22369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                       JoinIntegers(Lo, Hi));
224bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return DAG.getNode(ISD::BITCAST, dl, NOutVT, InOp);
22569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
22696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeWidenVector:
22787c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang    if (OutVT.bitsEq(NInVT))
22887c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang      // The input is widened to the same size.  Convert to the widened value.
229bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      return DAG.getNode(ISD::BITCAST, dl, OutVT, GetWidenedVector(InOp));
23087c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang  }
23169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
232aad3460086a1b29c55f7490c6d8743ea4e53f07dEli Friedman  return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
233aad3460086a1b29c55f7490c6d8743ea4e53f07dEli Friedman                     CreateStackStoreLoad(InOp, OutVT));
23469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
23569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
236475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
237475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
238e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getValueType(0);
239e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Op.getValueType();
240786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
241c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands
242c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands  unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
243786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
24453dfa78e4133f6cdb5d860279adc337ea099ac15Duncan Sands                     DAG.getConstant(DiffBits, TLI.getPointerTy()));
245c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands}
246c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands
247475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
248bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The pair element type may be legal, or may not promote to the same type as
249bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // the result, for example i14 = BUILD_PAIR (i7, i7).  Handle all cases.
250786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(),
25154e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     TLI.getTypeToTransformTo(*DAG.getContext(),
25254e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     N->getValueType(0)), JoinIntegers(N->getOperand(0),
25354e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     N->getOperand(1)));
25469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
25569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
256475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
257e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
258b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  // FIXME there is no actual debug info here
259b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  DebugLoc dl = N->getDebugLoc();
260bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Zero extend things like i1, sign extend everything else.  It shouldn't
261bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // matter in theory which one we pick, but this tends to give better code?
262bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
26354e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher  SDValue Result = DAG.getNode(Opc, dl,
26454e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                               TLI.getTypeToTransformTo(*DAG.getContext(), VT),
265a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands                               SDValue(N, 0));
266bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
267bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return Result;
26869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
26969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
27000ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P WangSDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_RNDSAT(SDNode *N) {
27100ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
27200ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
27300ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
27400ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang           CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
27500ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang          "can only promote integers");
27623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OutVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
277c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen  return DAG.getConvertRndSat(OutVT, N->getDebugLoc(), N->getOperand(0),
27800ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang                              N->getOperand(1), N->getOperand(2),
27900ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang                              N->getOperand(3), N->getOperand(4), CvtCode);
28000ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang}
28100ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang
282475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
283c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  // Zero extend to the promoted type and do the count there.
284c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
285b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  DebugLoc dl = N->getDebugLoc();
286e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getValueType(0);
287e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Op.getValueType();
288b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  Op = DAG.getNode(ISD::CTLZ, dl, NVT, Op);
28969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Subtract off the extra leading bits in the bigger type.
290b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  return DAG.getNode(ISD::SUB, dl, NVT, Op,
29169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                     DAG.getConstant(NVT.getSizeInBits() -
29269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                     OVT.getSizeInBits(), NVT));
29369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
29469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
295475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
29669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Zero extend to the promoted type and do the count there.
297c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
298786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op);
29969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
30069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
301475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
302475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
303e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getValueType(0);
304e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Op.getValueType();
305786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
30669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // The count is the same in the promoted type except if the original
30769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // value was zero.  This can be handled by setting the bit just off
30869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // the top of the original type.
30903dc093a2e63d20984c8fd67809fa762f1e31f1aDuncan Sands  APInt TopBit(NVT.getSizeInBits(), 0);
3107a874ddda037349184fbeb22838cc11a1a9bb78fJay Foad  TopBit.setBit(OVT.getSizeInBits());
311786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
312786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::CTTZ, dl, NVT, Op);
31369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
31469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
315475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
316786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
31723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
318c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0),
319c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman                     N->getOperand(1));
32069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
32169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
322475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
32323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
324a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  unsigned NewOpc = N->getOpcode();
325786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
326d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands
3274c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is
3284c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // not Legal, check to see if we can use FP_TO_SINT instead.  (If both UINT
32954e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher  // and SINT conversions are Custom, there is no way to tell which is
33054e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher  // preferable. We choose SINT because that's the right thing on PPC.)
331a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  if (N->getOpcode() == ISD::FP_TO_UINT &&
3324c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen      !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
333f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman      TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
334a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands    NewOpc = ISD::FP_TO_SINT;
335a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands
336786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0));
337a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands
338a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // Assert that the converted value fits in the original type.  If it doesn't
339a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // (eg: because the value being converted is too big), then the result of the
340a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // original operation was undefined anyway, so the assert is still correct.
341a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ?
342786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     ISD::AssertZext : ISD::AssertSext, dl,
343a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands                     NVT, Res, DAG.getValueType(N->getValueType(0)));
344d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands}
345d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands
346927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton KorobeynikovSDValue DAGTypeLegalizer::PromoteIntRes_FP32_TO_FP16(SDNode *N) {
347927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
348927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  DebugLoc dl = N->getDebugLoc();
349927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
350927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
351927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
352927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  return DAG.getNode(ISD::AssertZext, dl,
353927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov                     NVT, Res, DAG.getValueType(N->getValueType(0)));
354927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov}
355927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
356475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
35723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
358786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
359be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands
36096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  if (getTypeAction(N->getOperand(0).getValueType())
36196e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem      == TargetLowering::TypePromoteInteger) {
362475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(N->getOperand(0));
3636959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands    assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!");
364126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands
365bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    // If the result and operand types are the same after promotion, simplify
366bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    // to an in-register extension.
367bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    if (NVT == Res.getValueType()) {
368bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      // The high bits are not guaranteed to be anything.  Insert an extend.
369bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      if (N->getOpcode() == ISD::SIGN_EXTEND)
370786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
371bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                           DAG.getValueType(N->getOperand(0).getValueType()));
372bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      if (N->getOpcode() == ISD::ZERO_EXTEND)
3734be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen        return DAG.getZeroExtendInReg(Res, dl, N->getOperand(0).getValueType());
374bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
375bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      return Res;
376126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands    }
37769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
37869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
379bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Otherwise, just extend the original operand all the way to the larger type.
380786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
381bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
38269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
383475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
384bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
38523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
386bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  ISD::LoadExtType ExtType =
387bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
388786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
389a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings  SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
3903d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                               N->getPointerInfo(),
39147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands                               N->getMemoryVT(), N->isVolatile(),
3921e559443a17d1b335f697551c6263ba60d5dd827David Greene                               N->isNonTemporal(), N->getAlignment());
39369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
394bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
395bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // use the new one.
396475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
397bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return Res;
39869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
39969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
400874ae251c317788391f9c3f113957802d390a063Dale Johannesen/// Promote the overflow flag of an overflowing arithmetic node.
401ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
402ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Simply change the return type of the boolean result.
40323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
404e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ValueVTs[] = { N->getValueType(0), NVT };
405ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
406786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
407786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                            DAG.getVTList(ValueVTs, 2), Ops, 2);
408ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
409ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Modified the sum result - switch anything that used the old sum to use
410ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the new one.
411ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 0), Res);
412ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
413ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return SDValue(Res.getNode(), 1);
414ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
415ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
416ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
417ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  if (ResNo == 1)
418ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands    return PromoteIntRes_Overflow(N);
419ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
420ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // The operation overflowed iff the result in the larger type is not the
421ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // sign extension of its truncation to the original type.
422ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
423ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
424e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getOperand(0).getValueType();
425e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = LHS.getValueType();
426786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
427ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
428ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Do the arithmetic in the larger type.
429ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
430786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
431ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
432ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Calculate the overflow flag: sign extend the arithmetic result from
433ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the original type.
434786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
435ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands                            DAG.getValueType(OVT));
436ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Overflowed if and only if this is not equal to Res.
437786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
438ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
439ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Use the calculated overflow everywhere.
440ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 1), Ofl);
441ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
442ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return Res;
443ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
444ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
445475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
446bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Sign extend the input.
447c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
448c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
449786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
450786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), LHS, RHS);
45169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
45269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
453475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
454475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(1));
455475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(2));
456786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
457786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), N->getOperand(0),LHS,RHS);
45869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
45969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
460475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
461475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(2));
462475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(3));
463786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
464786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), N->getOperand(0),
465bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     N->getOperand(1), LHS, RHS, N->getOperand(4));
46669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
46769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
468475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
469e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType());
4707e4982287591945c4e42ba8470a978e629789c76Duncan Sands  assert(isTypeLegal(SVT) && "Illegal SetCC type!");
471786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
4727e4982287591945c4e42ba8470a978e629789c76Duncan Sands
4737e4982287591945c4e42ba8470a978e629789c76Duncan Sands  // Get the SETCC result using the canonical SETCC type.
474786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0),
4757e4982287591945c4e42ba8470a978e629789c76Duncan Sands                              N->getOperand(1), N->getOperand(2));
4767e4982287591945c4e42ba8470a978e629789c76Duncan Sands
4777e4982287591945c4e42ba8470a978e629789c76Duncan Sands  // Convert to the expected type.
47823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4796959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands  assert(NVT.bitsLE(SVT) && "Integer type overpromoted?");
480786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC);
48169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
48269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
483475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
484786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SHL, N->getDebugLoc(),
485182465c589f95ff165331d06035ec53ff05bf1f5Evan Cheng                TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)),
486bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
48769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
48869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
489475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
490475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
491786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(),
492786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
4938d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands}
4948d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands
495475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
496bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input may have strange things in the top bits of the registers, but
497bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // these operations don't care.  They may have weird bits going out, but
498bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // that too is okay if they are integer operations.
499475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(0));
500475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(1));
501786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
502786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                    LHS.getValueType(), LHS, RHS);
50369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
50469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
505475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
506bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input value must be properly sign extended.
507c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Res = SExtPromotedInteger(N->getOperand(0));
508786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRA, N->getDebugLoc(),
509786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Res.getValueType(), Res, N->getOperand(1));
510bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
51169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
512475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
513bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input value must be properly zero extended.
514e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
51523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
516475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = ZExtPromotedInteger(N->getOperand(0));
517786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1));
51869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
51969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
520475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
52123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
522475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res;
52369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
524bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  switch (getTypeAction(N->getOperand(0).getValueType())) {
525c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown type action!");
52696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeLegal:
52796e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeExpandInteger:
528bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    Res = N->getOperand(0);
529bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    break;
53096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypePromoteInteger:
531bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    Res = GetPromotedInteger(N->getOperand(0));
532bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    break;
533bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  }
534bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
535bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Truncate to NVT instead of VT
536786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), NVT, Res);
53769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
53869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
539ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
540ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  if (ResNo == 1)
541ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands    return PromoteIntRes_Overflow(N);
542ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
543ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // The operation overflowed iff the result in the larger type is not the
544ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // zero extension of its truncation to the original type.
545c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
546c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
547e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getOperand(0).getValueType();
548e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = LHS.getValueType();
549786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
55069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
551ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Do the arithmetic in the larger type.
552ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
553786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
5548ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
555ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Calculate the overflow flag: zero extend the arithmetic result from
556ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the original type.
5574be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT);
558ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Overflowed if and only if this is not equal to Res.
559786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
5608ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
561ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Use the calculated overflow everywhere.
562ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 1), Ofl);
5638ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
564ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return Res;
565ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
566ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
5675c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris LattnerSDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
5685c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  // Promote the overflow bit trivially.
5695c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  if (ResNo == 1)
5705c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    return PromoteIntRes_Overflow(N);
571fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands
5725c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
5735c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  DebugLoc DL = N->getDebugLoc();
574fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands  EVT SmallVT = LHS.getValueType();
575fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands
576b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // To determine if the result overflowed in a larger type, we extend the
577b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // input to the larger type, do the multiply, then check the high bits of
578b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // the result to see if the overflow happened.
5795c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  if (N->getOpcode() == ISD::SMULO) {
5805c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    LHS = SExtPromotedInteger(LHS);
5815c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    RHS = SExtPromotedInteger(RHS);
5825c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  } else {
5835c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    LHS = ZExtPromotedInteger(LHS);
5845c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    RHS = ZExtPromotedInteger(RHS);
5855c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  }
5865c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
587fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands
588b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // Overflow occurred iff the high part of the result does not
589b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // zero/sign-extend the low part.
5905c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  SDValue Overflow;
5915c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  if (N->getOpcode() == ISD::UMULO) {
592fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    // Unsigned overflow occurred iff the high part is non-zero.
5935c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
594fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands                             DAG.getIntPtrConstant(SmallVT.getSizeInBits()));
5955c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
5965c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner                            DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
5975c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  } else {
598fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    // Signed overflow occurred iff the high part does not sign extend the low.
599fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
600fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands                               Mul, DAG.getValueType(SmallVT));
601fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
6025c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  }
6035c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner
6045c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  // Use the calculated overflow everywhere.
6055c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  ReplaceValueWith(SDValue(N, 1), Overflow);
6065c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  return Mul;
6075c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner}
6085c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner
609ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
610ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Zero extend the input.
611ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
612ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
613786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
614786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), LHS, RHS);
6158ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling}
6168ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
617475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
61853f6ed9560aa4586ba217fbf94acbfada52f561fEvan Cheng  return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
61953f6ed9560aa4586ba217fbf94acbfada52f561fEvan Cheng                                               N->getValueType(0)));
62069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
62169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
622475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
623475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = N->getOperand(0); // Get the chain.
624475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getOperand(1); // Get the pointer.
625e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
626786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
62769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
62823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT RegVT = TLI.getRegisterType(*DAG.getContext(), VT);
62923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), VT);
630d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // The argument is passed as NumRegs registers of type RegVT.
631d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands
632d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  SmallVector<SDValue, 8> Parts(NumRegs);
633d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  for (unsigned i = 0; i < NumRegs; ++i) {
634cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola    Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2),
635cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola                            N->getConstantOperandVal(3));
636d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    Chain = Parts[i].getValue(1);
637d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  }
63869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
639d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Handle endianness of the load.
640d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  if (TLI.isBigEndian())
641d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    std::reverse(Parts.begin(), Parts.end());
64269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
643d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Assemble the parts in the promoted type.
64423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
645786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]);
646d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  for (unsigned i = 1; i < NumRegs; ++i) {
647786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]);
648d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    // Shift it to the right position and "or" it in.
649786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
650d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands                       DAG.getConstant(i * RegVT.getSizeInBits(),
65192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
652786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
653d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  }
65469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
655d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Modified the chain result - switch anything that used the old chain to
656bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // use the new one.
657d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  ReplaceValueWith(SDValue(N, 1), Chain);
658d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands
659d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  return Res;
66069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
66169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
662bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//===----------------------------------------------------------------------===//
663bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//  Integer Operand Promotion
664bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//===----------------------------------------------------------------------===//
6657fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
666bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// PromoteIntegerOperand - This method is called when the specified operand of
667bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// the specified node is found to need promotion.  At this point, all of the
668bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// result types of the node are known to be legal, but other operands of the
669bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// node may need promotion or expansion as well as the specified one.
670bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sandsbool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
671d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG); dbgs() << "\n");
672475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = SDValue();
6737fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
674f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
675bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    return false;
67669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
677bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  switch (N->getOpcode()) {
678bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    default:
679bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  #ifndef NDEBUG
680d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "PromoteIntegerOperand Op #" << OpNo << ": ";
681d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
682bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  #endif
683c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to promote this operator's operand!");
684bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
685bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::ANY_EXTEND:   Res = PromoteIntOp_ANY_EXTEND(N); break;
686bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:      Res = PromoteIntOp_BITCAST(N); break;
687bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BR_CC:        Res = PromoteIntOp_BR_CC(N, OpNo); break;
688bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BRCOND:       Res = PromoteIntOp_BRCOND(N, OpNo); break;
689bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BUILD_PAIR:   Res = PromoteIntOp_BUILD_PAIR(N); break;
690bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
691fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::CONCAT_VECTORS: Res = PromoteIntOp_CONCAT_VECTORS(N); break;
692fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::EXTRACT_VECTOR_ELT: Res = PromoteIntOp_EXTRACT_VECTOR_ELT(N); break;
693bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::CONVERT_RNDSAT:
694bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                          Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
695bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::INSERT_VECTOR_ELT:
696bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                          Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
697bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::MEMBARRIER:   Res = PromoteIntOp_MEMBARRIER(N); break;
698aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang  case ISD::SCALAR_TO_VECTOR:
699aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang                          Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break;
700bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SELECT:       Res = PromoteIntOp_SELECT(N, OpNo); break;
701bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SELECT_CC:    Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
702bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SETCC:        Res = PromoteIntOp_SETCC(N, OpNo); break;
703bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SIGN_EXTEND:  Res = PromoteIntOp_SIGN_EXTEND(N); break;
704bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SINT_TO_FP:   Res = PromoteIntOp_SINT_TO_FP(N); break;
705bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::STORE:        Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
706bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                                                   OpNo); break;
707bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::TRUNCATE:     Res = PromoteIntOp_TRUNCATE(N); break;
708927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  case ISD::FP16_TO_FP32:
709bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::UINT_TO_FP:   Res = PromoteIntOp_UINT_TO_FP(N); break;
710bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::ZERO_EXTEND:  Res = PromoteIntOp_ZERO_EXTEND(N); break;
71155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
71255467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SHL:
71355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRA:
71455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRL:
71555467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTL:
71655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
717bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  }
7189fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands
719bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // If the result is null, the sub-method took care of registering results etc.
7209fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  if (!Res.getNode()) return false;
72147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
72247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // If the result is N, the sub-method updated N in place.  Tell the legalizer
72347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // core about this.
72447d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  if (Res.getNode() == N)
725bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    return true;
726bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
727bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
728bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands         "Invalid operand expansion");
729bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
730475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 0), Res);
731bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return false;
73269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
73369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
73469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
73569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// shared among BR_CC, SELECT_CC, and SETCC handlers.
736475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
73769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                            ISD::CondCode CCCode) {
738cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // We have to insert explicit sign or zero extends.  Note that we could
739cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // insert sign extends for ALL conditions, but zero extend is cheaper on
740cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // many machines (an AND instead of two shifts), so prefer it.
74169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (CCCode) {
742c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer comparison!");
74369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETEQ:
74469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETNE:
74569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETUGE:
74669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETUGT:
74769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETULE:
74869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETULT:
74969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // ALL of these operations will work if we either sign or zero extend
75069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // the operands (including the unsigned comparisons!).  Zero extend is
75169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // usually a simpler/cheaper operation, so prefer it.
752c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewLHS = ZExtPromotedInteger(NewLHS);
753c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewRHS = ZExtPromotedInteger(NewRHS);
75411ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    break;
75569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETGE:
75669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETGT:
75769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETLT:
75869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETLE:
759c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewLHS = SExtPromotedInteger(NewLHS);
760c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewRHS = SExtPromotedInteger(NewRHS);
76111ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    break;
76269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
76369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
76469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
765475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
766475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
767786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
768bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
76969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
770bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::PromoteIntOp_BITCAST(SDNode *N) {
77127759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  // This should only occur in unusual situations like bitcasting to an
77227759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  // x86_fp80, so just turn it into a store+load
77327759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
77427759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman}
77527759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman
776475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
777bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 2 && "Don't know how to promote this operand!");
77869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
779475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(2);
780475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(3);
781bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
78269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
783bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
784bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // legal types.
785027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
786027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(1), LHS, RHS, N->getOperand(4)),
787027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                 0);
788bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
789bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
790475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
791bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 1 && "only know how to promote condition");
792bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
793b6e223a9e806921183da972253c49082a2e07944Duncan Sands  // Promote all the way up to the canonical SetCC type.
794825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT SVT = TLI.getSetCCResultType(MVT::Other);
795b6e223a9e806921183da972253c49082a2e07944Duncan Sands  SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT);
796bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
797bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
798027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Cond,
799027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                        N->getOperand(2)), 0);
800bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
801bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
802475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
803bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Since the result type is legal, the operands must promote to it.
804e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getOperand(0).getValueType();
805c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
806475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Hi = GetPromotedInteger(N->getOperand(1));
807bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
808786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
809bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
810786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
81192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                   DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy()));
812786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
81369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
81469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
815475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
81669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // The vector type is legal but the element type is not.  This implies
81769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // that the vector is a power-of-two in length and that the element
81869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // type does not have a strange size (eg: it is not i1).
819e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VecVT = N->getValueType(0);
82069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  unsigned NumElts = VecVT.getVectorNumElements();
82169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  assert(!(NumElts & 1) && "Legal vector of one illegal element?");
82269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
823b1303d05a89972195de023fda432cc621375a27cBob Wilson  // Promote the inserted value.  The type does not need to match the
824b1303d05a89972195de023fda432cc621375a27cBob Wilson  // vector element type.  Check that any extra bits introduced will be
825b1303d05a89972195de023fda432cc621375a27cBob Wilson  // truncated away.
826b1303d05a89972195de023fda432cc621375a27cBob Wilson  assert(N->getOperand(0).getValueType().getSizeInBits() >=
827b1303d05a89972195de023fda432cc621375a27cBob Wilson         N->getValueType(0).getVectorElementType().getSizeInBits() &&
828b1303d05a89972195de023fda432cc621375a27cBob Wilson         "Type of inserted value narrower than vector element type!");
82969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
830b1303d05a89972195de023fda432cc621375a27cBob Wilson  SmallVector<SDValue, 16> NewOps;
831c885165e664f3b465403e1b6ce57ba63f57c5f0cBob Wilson  for (unsigned i = 0; i < NumElts; ++i)
832b1303d05a89972195de023fda432cc621375a27cBob Wilson    NewOps.push_back(GetPromotedInteger(N->getOperand(i)));
83369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
834027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, &NewOps[0], NumElts), 0);
83569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
83669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
83728088d3c049017a131aa7b07201c6e19c0227cefMon P WangSDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
83828088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
83928088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
84028088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
84128088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           CvtCode == ISD::CVT_FS || CvtCode == ISD::CVT_FU) &&
84228088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           "can only promote integer arguments");
84328088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  SDValue InOp = GetPromotedInteger(N->getOperand(0));
844c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen  return DAG.getConvertRndSat(N->getValueType(0), N->getDebugLoc(), InOp,
84528088d3c049017a131aa7b07201c6e19c0227cefMon P Wang                              N->getOperand(1), N->getOperand(2),
84628088d3c049017a131aa7b07201c6e19c0227cefMon P Wang                              N->getOperand(3), N->getOperand(4), CvtCode);
84728088d3c049017a131aa7b07201c6e19c0227cefMon P Wang}
84828088d3c049017a131aa7b07201c6e19c0227cefMon P Wang
849475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
850475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                         unsigned OpNo) {
85169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  if (OpNo == 1) {
85269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Promote the inserted value.  This is valid because the type does not
85369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // have to match the vector element type.
85469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
85569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Check that any extra bits introduced will be truncated away.
85669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    assert(N->getOperand(1).getValueType().getSizeInBits() >=
85769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands           N->getValueType(0).getVectorElementType().getSizeInBits() &&
85869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands           "Type of inserted value narrower than vector element type!");
859027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman    return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
86069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                  GetPromotedInteger(N->getOperand(1)),
861027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                  N->getOperand(2)),
862027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                   0);
86369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
86469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
86569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  assert(OpNo == 2 && "Different operand and result vector types?");
86669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
86769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Promote the index.
868c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Idx = ZExtPromotedInteger(N->getOperand(2));
869027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
870027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(1), Idx), 0);
87169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
87269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
873475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
874475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewOps[6];
8754be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  DebugLoc dl = N->getDebugLoc();
87669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  NewOps[0] = N->getOperand(0);
87769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
878475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Flag = GetPromotedInteger(N->getOperand(i));
879825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    NewOps[i] = DAG.getZeroExtendInReg(Flag, dl, MVT::i1);
88069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
881027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, NewOps, array_lengthof(NewOps)), 0);
88269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
88369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
884aa9df0b0c3cef33514095bde2eedead986677955Mon P WangSDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) {
885b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  // Integer SCALAR_TO_VECTOR operands are implicitly truncated, so just promote
886b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  // the operand in place.
887027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N,
888027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                GetPromotedInteger(N->getOperand(0))), 0);
889aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang}
890aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang
891475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
892bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Only know how to promote condition");
8937e4982287591945c4e42ba8470a978e629789c76Duncan Sands
894b6e223a9e806921183da972253c49082a2e07944Duncan Sands  // Promote all the way up to the canonical SetCC type.
895e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType());
896b6e223a9e806921183da972253c49082a2e07944Duncan Sands  SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT);
897bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
898027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, Cond,
899027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(1), N->getOperand(2)), 0);
900bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
901bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
902475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) {
903bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Don't know how to promote this operand!");
904bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
905475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(0);
906475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(1);
907bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get());
908bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
909bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The CC (#4) and the possible return values (#2 and #3) have legal types.
910027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2),
911027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(3), N->getOperand(4)), 0);
912bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
913bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
914475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
915bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Don't know how to promote this operand!");
916bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
917475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(0);
918475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(1);
919bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
920bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
921bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The CC (#2) is always legal.
922027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0);
923bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
924bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
92555467af31620c9d027e071ebcd9746b7593cff17Sanjiv GuptaSDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
926027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
927027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                ZExtPromotedInteger(N->getOperand(1))), 0);
92855467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta}
92955467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
930475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
931475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
932786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
933786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
934786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(),
935bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     Op, DAG.getValueType(N->getOperand(0).getValueType()));
936bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
937bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
938c08468774b65dc288c44076d428f4beddabe58e2Duncan SandsSDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
939027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N,
940027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                SExtPromotedInteger(N->getOperand(0))), 0);
941c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands}
942c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands
943475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
944bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
945475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
946bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  unsigned Alignment = N->getAlignment();
947bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  bool isVolatile = N->isVolatile();
9481e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = N->isNonTemporal();
949786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
950bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
951475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Val = GetPromotedInteger(N->getValue());  // Get promoted value.
952bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
953bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Truncate the value and store the result.
954ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getPointerInfo(),
955ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                           N->getMemoryVT(),
9561e559443a17d1b335f697551c6263ba60d5dd827David Greene                           isVolatile, isNonTemporal, Alignment);
957bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
958bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
959475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
960475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
961786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op);
962bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
963bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
964c08468774b65dc288c44076d428f4beddabe58e2Duncan SandsSDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
965027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N,
966027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                ZExtPromotedInteger(N->getOperand(0))), 0);
967c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands}
968c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands
969475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
9704be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  DebugLoc dl = N->getDebugLoc();
971475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
9724be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
9734be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  return DAG.getZeroExtendInReg(Op, dl, N->getOperand(0).getValueType());
974bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
975bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
97669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
97769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----------------------------------------------------------------------===//
97869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Result Expansion
97969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----------------------------------------------------------------------===//
98069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
98169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// ExpandIntegerResult - This method is called when the specified result of the
982cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// specified node is found to need expansion.  At this point, the node may also
983cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// have invalid operands or may have other results that need promotion, we just
984cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// know that (at least) one result needs expansion.
98569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
986d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Expand integer result: "; N->dump(&DAG); dbgs() << "\n");
987475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
988475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  Lo = Hi = SDValue();
989cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
990cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // See if the target wants to custom expand this node.
991f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getValueType(ResNo), true))
9921607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands    return;
993cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
994cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  switch (N->getOpcode()) {
995cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  default:
996cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#ifndef NDEBUG
997d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "ExpandIntegerResult #" << ResNo << ": ";
998d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
999cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#endif
1000c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to expand the result of this operator!");
100169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
100278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
100378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
100478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
100578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
100678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
1007bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:            ExpandRes_BITCAST(N, Lo, Hi); break;
100878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
10094a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
101078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
101121c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;
101278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
101369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ANY_EXTEND:  ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
101495db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  case ISD::AssertSext:  ExpandIntRes_AssertSext(N, Lo, Hi); break;
101569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::AssertZext:  ExpandIntRes_AssertZext(N, Lo, Hi); break;
101605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::BSWAP:       ExpandIntRes_BSWAP(N, Lo, Hi); break;
101705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::Constant:    ExpandIntRes_Constant(N, Lo, Hi); break;
101805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTLZ:        ExpandIntRes_CTLZ(N, Lo, Hi); break;
101905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTPOP:       ExpandIntRes_CTPOP(N, Lo, Hi); break;
102005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTTZ:        ExpandIntRes_CTTZ(N, Lo, Hi); break;
102169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_SINT:  ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
102269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_UINT:  ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
102369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::LOAD:        ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
102405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::MUL:         ExpandIntRes_MUL(N, Lo, Hi); break;
102505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SDIV:        ExpandIntRes_SDIV(N, Lo, Hi); break;
102605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
102705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
102805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SREM:        ExpandIntRes_SREM(N, Lo, Hi); break;
102905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::TRUNCATE:    ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
103005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::UDIV:        ExpandIntRes_UDIV(N, Lo, Hi); break;
103105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::UREM:        ExpandIntRes_UREM(N, Lo, Hi); break;
103205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
103369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
10348d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_ADD:
10358d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_SUB:
10368d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_AND:
10378d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_OR:
10388d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_XOR:
10398d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_NAND:
10408d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_MIN:
10418d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_MAX:
10428d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_UMIN:
10438d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_UMAX:
10448d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_SWAP: {
10458d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N);
10468d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    SplitInteger(Tmp.first, Lo, Hi);
10478d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    ReplaceValueWith(SDValue(N, 1), Tmp.second);
10488d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    break;
10498d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  }
10508d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher
1051cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::AND:
1052cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::OR:
105305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
105405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1055cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADD:
105605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
105705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1058cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADDC:
105905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
106005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1061cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADDE:
106205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
106305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1064cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SHL:
1065cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SRA:
106605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
1067268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1068268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::SADDO:
1069268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break;
1070268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::UADDO:
1071268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break;
1072cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1073d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
1074cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If Lo/Hi is null, the sub-method took care of registering results etc.
1075ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (Lo.getNode())
1076475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SetExpandedInteger(SDValue(N, ResNo), Lo, Hi);
1077cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1078cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
107993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher/// Lower an atomic node to the appropriate builtin call.
108093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopherstd::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
108193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  unsigned Opc = Node->getOpcode();
108293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
108393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  RTLIB::Libcall LC;
108493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher
108593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  switch (Opc) {
108693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  default:
108793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    llvm_unreachable("Unhandled atomic intrinsic Expand!");
108893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
108993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_SWAP:
109093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
109193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
109293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break;
109393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break;
109493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break;
109593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break;
109693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
109793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
109893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_CMP_SWAP:
109993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
110093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
110193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break;
110293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break;
110393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break;
110493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break;
110593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
110693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
110793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_ADD:
110893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
110993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
111093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_ADD_1; break;
111193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break;
111293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break;
111393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break;
111493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
111593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
111693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_SUB:
111793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
111893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
111993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_SUB_1; break;
112093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break;
112193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break;
112293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break;
112393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
112493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
112593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_AND:
112693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
112793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
112893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_AND_1; break;
112993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break;
113093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break;
113193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break;
113293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
113393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
113493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_OR:
113593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
113693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
113793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_OR_1; break;
113893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break;
113993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break;
114093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break;
114193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
114293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
114393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_XOR:
114493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
114593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
114693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_XOR_1; break;
114793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break;
114893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break;
114993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break;
115093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
115193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
115293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_NAND:
115393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
115493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
115593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_NAND_1; break;
115693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break;
115793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break;
115893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break;
115993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
116093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
116193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  }
116293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher
116393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  return ExpandChainLibCall(LC, Node, false);
116493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher}
116593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher
116605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
116705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// and the shift amount is a constant 'Amt'.  Expand the operation.
116805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
1169475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
1170e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner  DebugLoc DL = N->getDebugLoc();
117105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the incoming operand to be shifted, so that we have its parts
1172475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
117305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
1174cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1175e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = InL.getValueType();
117605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned VTBits = N->getValueType(0).getSizeInBits();
117705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
1178e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShTy = N->getOperand(1).getValueType();
1179cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
118005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::SHL) {
118105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (Amt > VTBits) {
118205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = Hi = DAG.getConstant(0, NVT);
118305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt > NVTBits) {
118405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
1185e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::SHL, DL,
1186915eeb488786379250808d47668c43e010efe566Chris Lattner                       NVT, InL, DAG.getConstant(Amt-NVTBits, ShTy));
118705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt == NVTBits) {
118805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
118905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = InL;
1190104de6cf7b80ec5e9beb502a069f376810a0a1e3Richard Osborne    } else if (Amt == 1 &&
1191f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman               TLI.isOperationLegalOrCustom(ISD::ADDC,
119254e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                              TLI.getTypeToExpandTo(*DAG.getContext(), NVT))) {
119305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      // Emit this X << 1 as X+X.
1194f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner      SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
1195475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue LoOps[2] = { InL, InL };
1196e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::ADDC, DL, VTList, LoOps, 2);
1197475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
1198e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::ADDE, DL, VTList, HiOps, 3);
119905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else {
1200e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::SHL, DL, NVT, InL, DAG.getConstant(Amt, ShTy));
1201e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::OR, DL, NVT,
1202e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SHL, DL, NVT, InH,
120305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(Amt, ShTy)),
1204e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SRL, DL, NVT, InL,
120505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(NVTBits-Amt, ShTy)));
120605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
120705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return;
1208cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1209cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
121005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::SRL) {
121105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (Amt > VTBits) {
121205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
121305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
121405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt > NVTBits) {
1215e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::SRL, DL,
1216786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
121705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
121805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt == NVTBits) {
121905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = InH;
122005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
122105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else {
1222e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::OR, DL, NVT,
1223e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SRL, DL, NVT, InL,
122405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(Amt, ShTy)),
1225e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SHL, DL, NVT, InH,
122605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(NVTBits-Amt, ShTy)));
1227e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::SRL, DL, NVT, InH, DAG.getConstant(Amt, ShTy));
122805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
122905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return;
1230cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1231d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands
123205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
123305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Amt > VTBits) {
1234e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
123505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                          DAG.getConstant(NVTBits-1, ShTy));
123605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else if (Amt > NVTBits) {
1237e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
123805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(Amt-NVTBits, ShTy));
1239e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
124005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(NVTBits-1, ShTy));
124105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else if (Amt == NVTBits) {
124205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Lo = InH;
1243e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
124405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(NVTBits-1, ShTy));
1245d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands  } else {
1246e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Lo = DAG.getNode(ISD::OR, DL, NVT,
1247e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                     DAG.getNode(ISD::SRL, DL, NVT, InL,
124805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(Amt, ShTy)),
1249e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                     DAG.getNode(ISD::SHL, DL, NVT, InH,
125005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(NVTBits-Amt, ShTy)));
1251e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, DAG.getConstant(Amt, ShTy));
1252d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands  }
1253d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands}
1254d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands
125505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
125605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// this shift based on knowledge of the high bit of the shift amount.  If we
125705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
125805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// shift amount.
125905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsbool DAGTypeLegalizer::
1260475871a144eb604ddaf37503397ba0941442e5fbDan GohmanExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
1261475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Amt = N->getOperand(1);
126223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1263e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShTy = Amt.getValueType();
12645b870aff81da0c07413f0241087bb3722954b83dDan Gohman  unsigned ShBits = ShTy.getScalarType().getSizeInBits();
12655b870aff81da0c07413f0241087bb3722954b83dDan Gohman  unsigned NVTBits = NVT.getScalarType().getSizeInBits();
126605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(isPowerOf2_32(NVTBits) &&
126705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Expanded integer type size not a power of two!");
1268786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1269cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
127005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
127105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  APInt KnownZero, KnownOne;
127205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
1273cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
127405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we don't know anything about the high bits, exit.
127505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (((KnownZero|KnownOne) & HighBitMask) == 0)
127605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return false;
1277cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
127805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Get the incoming operand to be shifted.
1279475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
128005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
1281be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands
128205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we know that any of the high bits of the shift amount are one, then we
128305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // can do this as a couple of simple shifts.
128405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (KnownOne.intersects(HighBitMask)) {
128505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Mask out the high bit, which we know is set.
1286786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
128705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                      DAG.getConstant(~HighBitMask, ShTy));
128805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
128905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    switch (N->getOpcode()) {
1290c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown shift");
129105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SHL:
129205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);              // Low part is zero.
1293786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
129405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
129505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRL:
129605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);              // Hi part is zero.
1297786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
129805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
129905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRA:
1300786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,       // Sign extend high part.
130105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                       DAG.getConstant(NVTBits-1, ShTy));
1302786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
130305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
130405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
130505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
130605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
130728dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman#if 0
130828dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman  // FIXME: This code is broken for shifts with a zero amount!
130905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we know that all of the high bits of the shift amount are zero, then we
131005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // can do this as a couple of simple shifts.
131105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if ((KnownZero & HighBitMask) == HighBitMask) {
131205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Compute 32-amt.
1313475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Amt2 = DAG.getNode(ISD::SUB, ShTy,
131405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(NVTBits, ShTy),
131505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 Amt);
131605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned Op1, Op2;
131705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    switch (N->getOpcode()) {
1318c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown shift");
131905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SHL:  Op1 = ISD::SHL; Op2 = ISD::SRL; break;
132005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRL:
132105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRA:  Op1 = ISD::SRL; Op2 = ISD::SHL; break;
132205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
132305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
132405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
132505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getNode(ISD::OR, NVT,
132605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getNode(Op1, NVT, InH, Amt),
132705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getNode(Op2, NVT, InL, Amt2));
132805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return true;
132905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
133028dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman#endif
133105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
133205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  return false;
133305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
133405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
13356fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift
13366fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng/// of any size.
13376fb2168aaed06e4685d064b6f63dc4c668b42728Evan Chengbool DAGTypeLegalizer::
13386fb2168aaed06e4685d064b6f63dc4c668b42728Evan ChengExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
13396fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue Amt = N->getOperand(1);
134023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1341e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShTy = Amt.getValueType();
13426fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  unsigned NVTBits = NVT.getSizeInBits();
13436fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  assert(isPowerOf2_32(NVTBits) &&
13446fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng         "Expanded integer type size not a power of two!");
13456fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  DebugLoc dl = N->getDebugLoc();
13466fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
13476fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  // Get the incoming operand to be shifted.
13486fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue InL, InH;
13496fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  GetExpandedInteger(N->getOperand(0), InL, InH);
13506fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
13516fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
13529993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
13539993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
13549993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue isShort = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy),
13559993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                                 Amt, NVBitsNode, ISD::SETULT);
13566fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
13579993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue LoS, HiS, LoL, HiL;
13586fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  switch (N->getOpcode()) {
1359c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown shift");
13606fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SHL:
13619993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Short: ShAmt < NVTBits
13629993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
13639993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiS = DAG.getNode(ISD::OR, dl, NVT,
13646fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
136536236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // FIXME: If Amt is zero, the following shift generates an undefined result
136636236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // on some architectures.
13679993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
13689993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
13699993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Long: ShAmt >= NVTBits
13709993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoL = DAG.getConstant(0, NVT);                        // Lo part is zero.
13719993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part.
13726fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
13739993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
13749993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
13756fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
13766fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SRL:
13779993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Short: ShAmt < NVTBits
13789993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
13799993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoS = DAG.getNode(ISD::OR, dl, NVT,
13809993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
138136236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // FIXME: If Amt is zero, the following shift generates an undefined result
138236236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // on some architectures.
13839993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
13849993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
13859993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Long: ShAmt >= NVTBits
13869993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiL = DAG.getConstant(0, NVT);                        // Hi part is zero.
13879993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
13889993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
13899993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
13909993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
13916fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
13926fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SRA:
13939993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Short: ShAmt < NVTBits
13949993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
13959993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoS = DAG.getNode(ISD::OR, dl, NVT,
13966fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
139736236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // FIXME: If Amt is zero, the following shift generates an undefined result
139836236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // on some architectures.
13999993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
14009993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
14019993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Long: ShAmt >= NVTBits
14029993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiL = DAG.getNode(ISD::SRA, dl, NVT, InH,             // Sign of Hi part.
14039993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getConstant(NVTBits-1, ShTy));
14049993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part.
14056fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14069993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
14079993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
14086fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
14096fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  }
14106fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14116fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  return false;
14126fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng}
14136fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
141405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
1415475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                           SDValue &Lo, SDValue &Hi) {
1416786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
141705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1418475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
141905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
142005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
142129a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands
1422e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = LHSL.getValueType();
1423475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[2] = { LHSL, RHSL };
1424475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
142505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
142629a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support
142729a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // them.  TODO: Teach operation legalization how to expand unsupported
142829a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // ADDC/ADDE/SUBC/SUBE.  The problem is that these operations generate
1429f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  // a carry of type MVT::Glue, but there doesn't seem to be any way to
143029a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // generate a value of this type in the expanded code sequence.
143129a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  bool hasCarry =
1432f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman    TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
1433f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman                                   ISD::ADDC : ISD::SUBC,
1434bc7a902713c4e3f13a93c383e647d2a18712f447Dan Gohman                                 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
143529a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands
143629a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  if (hasCarry) {
1437f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
143829a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    if (N->getOpcode() == ISD::ADD) {
1439786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
144029a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands      HiOps[2] = Lo.getValue(1);
1441786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
144229a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    } else {
1443786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
144429a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands      HiOps[2] = Lo.getValue(1);
1445786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
144629a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    }
1447c6d160bfa22fcb06c80c4c6cfc10ddbe7d8d28e4Owen Anderson    return;
14485078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner  }
1449c6d160bfa22fcb06c80c4c6cfc10ddbe7d8d28e4Owen Anderson
14505078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner  if (N->getOpcode() == ISD::ADD) {
14515078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2);
14525078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2);
14535078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0],
14545078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                ISD::SETULT);
14555078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1,
14565078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(1, NVT),
14575078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(0, NVT));
14585078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1],
14595078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                ISD::SETULT);
14605078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2,
14615078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(1, NVT), Carry1);
14625078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2);
146305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
14645078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2);
14655078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2);
14665078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Cmp =
14675078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner      DAG.getSetCC(dl, TLI.getSetCCResultType(LoOps[0].getValueType()),
14685078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                   LoOps[0], LoOps[1], ISD::SETULT);
14695078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp,
14705078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(1, NVT),
14715078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(0, NVT));
14725078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
147305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
147405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
147505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
147605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
1477475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
147805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1479475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
1480786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
148105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
148205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1483f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
1484475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[2] = { LHSL, RHSL };
1485475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
148605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
148705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::ADDC) {
1488786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
148905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    HiOps[2] = Lo.getValue(1);
1490786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
149105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
1492786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
149305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    HiOps[2] = Lo.getValue(1);
1494786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
149505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
149605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1497874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // Legalized the flag result - switch anything that used the old flag to
1498874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // use the new one.
1499475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
150005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
150105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
150205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
1503475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
150405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1505475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
1506786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
150705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
150805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1509f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
1510475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
1511475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
151205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1513786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3);
151405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  HiOps[2] = Lo.getValue(1);
1515786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
151605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1517874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // Legalized the flag result - switch anything that used the old flag to
1518874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // use the new one.
1519475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
152005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
152105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
152205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
1523475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
152423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1525786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1526475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
152705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
152805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The low part is any extension of the input (which degenerates to a copy).
1529786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
1530e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen    Hi = DAG.getUNDEF(NVT);   // The high part is undefined.
153105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
153205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
153305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
153496e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    assert(getTypeAction(Op.getValueType()) ==
153596e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem           TargetLowering::TypePromoteInteger &&
153605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
1537475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
153805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
153905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
154005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
154105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
154205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
154305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
154405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
154595db39a9de48f69f4d764335b492b83a698c7854Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
1546475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
1547786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
154895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1549e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
1550e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
155195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  unsigned NVTBits = NVT.getSizeInBits();
155295db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  unsigned EVTBits = EVT.getSizeInBits();
155395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
155495db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  if (NVTBits < EVTBits) {
1555786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
15564ff28527bb8e5ed4ae4b65f0fa6967eb79a05d4cEvan Cheng                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
15574ff28527bb8e5ed4ae4b65f0fa6967eb79a05d4cEvan Cheng                                                        EVTBits - NVTBits)));
155895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  } else {
1559786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
156095db39a9de48f69f4d764335b492b83a698c7854Duncan Sands    // The high part replicates the sign bit of Lo, make it explicit.
1561786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
156292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(NVTBits-1, TLI.getPointerTy()));
156395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  }
156495db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
156595db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
156605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
1567475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
1568786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
156905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1570e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
1571e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
157205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
157305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned EVTBits = EVT.getSizeInBits();
157405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
157505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (NVTBits < EVTBits) {
1576786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
1577285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
1578285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                                                        EVTBits - NVTBits)));
157905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
1580786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
158105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part must be zero, make it explicit.
158205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getConstant(0, NVT);
158305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
158405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
158505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
158605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
1587475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1588786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
158905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Hi, Lo);  // Note swapped operands.
1590786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
1591786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
159205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
159305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
159405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
1595475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
159623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
159705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NBitWidth = NVT.getSizeInBits();
159805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue();
159940f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad  Lo = DAG.getConstant(Cst.trunc(NBitWidth), NVT);
160005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
160105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
160205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
160305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
1604475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1605786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
160605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
160705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1608e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
160905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1610786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi,
1611ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   DAG.getConstant(0, NVT), ISD::SETNE);
161205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1613786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo);
1614786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi);
161505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1616786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ,
1617786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
161805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
161905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
162005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
162105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
162205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
1623475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1624786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
162505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
162605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1627e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
1628b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo),
1629786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
163005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
163105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
163205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
163305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
1634475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1635786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
163605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
163705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1638e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
163905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1640786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo,
1641ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   DAG.getConstant(0, NVT), ISD::SETNE);
164205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1643786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo);
1644786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi);
164505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1646786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ,
1647786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
164805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
164905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
165005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
165105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1652475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo,
1653475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Hi) {
1654c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1655e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
1656475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
1657b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT);
1658be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!");
1659c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi);
1660ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1661ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
1662475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo,
1663475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Hi) {
1664c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1665e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
1666475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
1667b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT);
1668be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!");
1669c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi);
1670ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1671ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
167269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
1673475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1674ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  if (ISD::isNormalLoad(N)) {
1675ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands    ExpandRes_NormalLoad(N, Lo, Hi);
167678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    return;
167778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
167878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
167978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
168078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
1681e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
168223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1683475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch  = N->getChain();
1684475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getBasePtr();
1685cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  ISD::LoadExtType ExtType = N->getExtensionType();
1686cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned Alignment = N->getAlignment();
1687cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  bool isVolatile = N->isVolatile();
16881e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = N->isNonTemporal();
1689786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1690cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
169178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
1692cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
169378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getMemoryVT().bitsLE(NVT)) {
16948a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman    EVT MemVT = N->getMemoryVT();
1695cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1696a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
16971e559443a17d1b335f697551c6263ba60d5dd827David Greene                        MemVT, isVolatile, isNonTemporal, Alignment);
1698cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1699cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Remember the chain.
1700cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    Ch = Lo.getValue(1);
1701cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1702cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    if (ExtType == ISD::SEXTLOAD) {
1703cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is obtained by SRA'ing all but one of the bits of the
1704cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // lo part.
170583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      unsigned LoSize = Lo.getValueType().getSizeInBits();
1706786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
170792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                       DAG.getConstant(LoSize-1, TLI.getPointerTy()));
1708cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    } else if (ExtType == ISD::ZEXTLOAD) {
1709cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is just a zero.
1710cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Hi = DAG.getConstant(0, NVT);
1711cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    } else {
1712cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
1713cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is undefined.
1714e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen      Hi = DAG.getUNDEF(NVT);
1715cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1716cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else if (TLI.isLittleEndian()) {
1717cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Little-endian - low bits are at low addresses.
1718ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getPointerInfo(),
17191e559443a17d1b335f697551c6263ba60d5dd827David Greene                     isVolatile, isNonTemporal, Alignment);
1720cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1721cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits =
172283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
172323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
1724cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1725cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
172683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
1727786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
17280bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
1729a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr,
1730ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                        N->getPointerInfo().getWithOffset(IncrementSize), NEVT,
17311e559443a17d1b335f697551c6263ba60d5dd827David Greene                        isVolatile, isNonTemporal,
17321e559443a17d1b335f697551c6263ba60d5dd827David Greene                        MinAlign(Alignment, IncrementSize));
1733cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1734cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Build a factor node to remember that this load is independent of the
1735cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // other one.
1736825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1737cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     Hi.getValue(1));
1738cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else {
1739cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Big-endian - high bits are at low addresses.  Favor aligned loads at
1740cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // the cost of some bit-fiddling.
17418a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman    EVT MemVT = N->getMemoryVT();
17424e918b2c8ca81edd63f6708e08835b2c14648615Dan Gohman    unsigned EBytes = MemVT.getStoreSize();
174383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
1744cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits = (EBytes - IncrementSize)*8;
1745cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1746cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Load both the high bits and maybe some of the low bits.
1747a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
17488a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman                        EVT::getIntegerVT(*DAG.getContext(),
17498a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman                                          MemVT.getSizeInBits() - ExcessBits),
17501e559443a17d1b335f697551c6263ba60d5dd827David Greene                        isVolatile, isNonTemporal, Alignment);
1751cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1752cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
1753786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
17540bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
1755cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Load the rest of the low bits.
1756a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr,
1757ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                        N->getPointerInfo().getWithOffset(IncrementSize),
175823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                        EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
17591e559443a17d1b335f697551c6263ba60d5dd827David Greene                        isVolatile, isNonTemporal,
17601e559443a17d1b335f697551c6263ba60d5dd827David Greene                        MinAlign(Alignment, IncrementSize));
1761cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1762cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Build a factor node to remember that this load is independent of the
1763cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // other one.
1764825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1765cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     Hi.getValue(1));
1766cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
176783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    if (ExcessBits < NVT.getSizeInBits()) {
1768cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Transfer low bits from the bottom of Hi to the top of Lo.
1769786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::OR, dl, NVT, Lo,
1770786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SHL, dl, NVT, Hi,
1771cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                   DAG.getConstant(ExcessBits,
177292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                                   TLI.getPointerTy())));
1773cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Move high bits to the right position in Hi.
17747fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands      Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl,
1775786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, Hi,
177683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
177792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
1778cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1779cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1780cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1781cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Legalized the chain result - switch anything that used the old chain to
1782cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // use the new one.
1783475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Ch);
1784cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1785cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
178669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
1787475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
1788786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1789475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LL, LH, RL, RH;
179069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(0), LL, LH);
179169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(1), RL, RH);
1792786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL);
1793786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH);
1794cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1795cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
179605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
1797475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                        SDValue &Lo, SDValue &Hi) {
1798e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
179923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1800c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
180169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1802f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT);
1803f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT);
1804f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT);
1805f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT);
1806cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
1807475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue LL, LH, RL, RH;
180869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(0), LL, LH);
180969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(1), RL, RH);
181083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned OuterBitSize = VT.getSizeInBits();
1811e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    unsigned InnerBitSize = NVT.getSizeInBits();
1812cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
1813cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
181469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1815e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
1816e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
1817e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands        DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
1818cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The inputs are both zero-extended.
1819cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasUMUL_LOHI) {
1820cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a umul_lohi.
1821786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
1822ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        Hi = SDValue(Lo.getNode(), 1);
1823cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1824cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1825cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasMULHU) {
1826cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a mulhu+mul.
1827786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1828786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
1829cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1830cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1831cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1832e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
1833cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The input values are both sign-extended.
1834cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasSMUL_LOHI) {
1835cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a smul_lohi.
1836786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
1837ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        Hi = SDValue(Lo.getNode(), 1);
1838cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1839cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1840cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasMULHS) {
1841cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a mulhs+mul.
1842786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1843786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL);
1844cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1845cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1846cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1847cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    if (HasUMUL_LOHI) {
1848cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Lo,Hi = umul LHS, RHS.
1849786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl,
1850cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                       DAG.getVTList(NVT, NVT), LL, RL);
1851cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Lo = UMulLOHI;
1852cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Hi = UMulLOHI.getValue(1);
1853786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
1854786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
1855786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
1856786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
1857cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      return;
1858cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1859e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (HasMULHU) {
1860786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1861786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
1862786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
1863786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
1864786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
1865786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
1866e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands      return;
1867e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    }
1868cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
186941edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
1870cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If nothing else, we can make a libcall.
18715ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1872825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
187315c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    LC = RTLIB::MUL_I16;
1874825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
18755ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::MUL_I32;
1876825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
1877e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    LC = RTLIB::MUL_I64;
1878825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
18795ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::MUL_I128;
18805ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!");
1881e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands
1882475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1883c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi);
188441edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands}
1885cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1886268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedmanvoid DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
1887268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                             SDValue &Lo, SDValue &Hi) {
1888268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue LHS = Node->getOperand(0);
1889268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue RHS = Node->getOperand(1);
1890268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  DebugLoc dl = Node->getDebugLoc();
1891268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1892268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Expand the result by simply replacing it with the equivalent
1893268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // non-overflow-checking operation.
1894268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
1895268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
1896268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            LHS, RHS);
1897268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SplitInteger(Sum, Lo, Hi);
1898268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1899268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Compute the overflow.
1900268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //
1901268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   LHSSign -> LHS >= 0
1902268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   RHSSign -> RHS >= 0
1903268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   SumSign -> Sum >= 0
1904268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //
1905268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Add:
1906268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
1907268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Sub:
1908268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
1909268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //
1910268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  EVT OType = Node->getValueType(1);
1911268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Zero = DAG.getConstant(0, LHS.getValueType());
1912268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1913268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
1914268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
1915268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
1916268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                    Node->getOpcode() == ISD::SADDO ?
1917268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                    ISD::SETEQ : ISD::SETNE);
1918268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1919268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
1920268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
1921268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1922268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
1923268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1924268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Use the calculated overflow everywhere.
1925268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  ReplaceValueWith(SDValue(Node, 1), Cmp);
1926268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman}
1927268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
192869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
1929475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1930e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
1931c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
19325ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands
19335ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1934825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
1935a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::SDIV_I16;
1936825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
19375ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I32;
1938825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
19395ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I64;
1940825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
19415ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I128;
19425ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
19435ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands
1944475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1945c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
1946ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1947ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
194869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
1949475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1950e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
1951c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
195269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
195369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // If we can emit an efficient shift operation, do so now.  Check to see if
1954cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // the RHS is a constant.
1955cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
1956f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi);
1957cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1958cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If we can determine that the high bit of the shift is zero or one, even if
1959cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // the low bits are variable, emit this shift in an optimized form.
1960cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
1961cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
196269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1963cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If this target supports shift_PARTS, use it.  First, map to the _PARTS opc.
1964cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned PartsOpc;
196541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  if (N->getOpcode() == ISD::SHL) {
1966cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SHL_PARTS;
196741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else if (N->getOpcode() == ISD::SRL) {
1968cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SRL_PARTS;
196941edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else {
1970cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
1971cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SRA_PARTS;
1972cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
197369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1974cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Next check to see if the target supports this SHL_PARTS operation or if it
1975cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // will custom expand it.
197623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1977cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
1978cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
1979cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Action == TargetLowering::Custom) {
1980cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Expand the subcomponents.
1981475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue LHSL, LHSH;
198269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
198369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1984475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) };
1985e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = LHSL.getValueType();
1986fc1665793e62eb4f26d24b8a19eecf59cd872e2aDan Gohman    Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops, 3);
1987cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    Hi = Lo.getValue(1);
1988cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
1989cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
199041edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
1991cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Otherwise, emit a libcall.
1992dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
199341edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  bool isSigned;
199441edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  if (N->getOpcode() == ISD::SHL) {
199541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = false; /*sign irrelevant*/
1996825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (VT == MVT::i16)
199715c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SHL_I16;
1998825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i32)
1999dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I32;
2000825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i64)
2001dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I64;
2002825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i128)
2003dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I128;
200441edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else if (N->getOpcode() == ISD::SRL) {
200541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = false;
2006825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (VT == MVT::i16)
200715c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SRL_I16;
2008825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i32)
2009dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I32;
2010825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i64)
2011dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I64;
2012825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i128)
2013dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I128;
201441edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else {
201541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
201641edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = true;
2017825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (VT == MVT::i16)
201815c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SRA_I16;
2019825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i32)
2020dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I32;
2021825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i64)
2022dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I64;
2023825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i128)
2024dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I128;
202541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  }
20268c899ee031481dbece5f111379a274c848cb5902Duncan Sands
20276fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
20286fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
20296fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi);
20306fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return;
20316fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  }
203241edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
20336fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
2034c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported shift!");
203541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands}
2036cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
203705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
2038475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                SDValue &Lo, SDValue &Hi) {
203923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2040786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2041475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
204205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
2043b3bc6352defdf1a5c6b1b0770d0c4d603f6524a8Duncan Sands    // The low part is sign extension of the input (degenerates to a copy).
2044786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
204505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part is obtained by SRA'ing all but one of the bits of low part.
204605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned LoSize = NVT.getSizeInBits();
2047786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
204892abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(LoSize-1, TLI.getPointerTy()));
204905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
205005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
205105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
205296e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    assert(getTypeAction(Op.getValueType()) ==
205396e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem           TargetLowering::TypePromoteInteger &&
205405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
2055475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
205605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
205705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
205805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
205905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
206005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
206105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
2062786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
2063285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
2064285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                                                        ExcessBits)));
206505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
206605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
206705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
206805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::
2069475871a144eb604ddaf37503397ba0941442e5fbDan GohmanExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
2070786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
207169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
2072e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
2073d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
207405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (EVT.bitsLE(Lo.getValueType())) {
207505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // sext_inreg the low part if needed.
2076786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
207705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     N->getOperand(1));
2078d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
207905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part gets the sign extension from the lo-part.  This handles
208005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // things like sextinreg V:i64 from i8.
2081786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
208205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
208392abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                     TLI.getPointerTy()));
208405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
208505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  Leave the low part alone,
208605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // sext_inreg the high part.
208705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
208805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
2089786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
209054e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
209154e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                                                        ExcessBits)));
209205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
209305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
2094d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
209505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
2096475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2097e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2098c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
209905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
210005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2102a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::SREM_I16;
2103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
210405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I32;
2105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
210605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I64;
2107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
210805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I128;
210905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
211005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2111475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2112c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
2113d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
2114d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
211505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
2116475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
211723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2118786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2119786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
2120786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::SRL, dl,
2121786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   N->getOperand(0).getValueType(), N->getOperand(0),
212292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                   DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy()));
2123786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
2124d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
2125d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
2126268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedmanvoid DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N,
2127268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                             SDValue &Lo, SDValue &Hi) {
2128268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue LHS = N->getOperand(0);
2129268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue RHS = N->getOperand(1);
2130268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  DebugLoc dl = N->getDebugLoc();
2131268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2132268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Expand the result by simply replacing it with the equivalent
2133268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // non-overflow-checking operation.
2134268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Sum = DAG.getNode(N->getOpcode() == ISD::UADDO ?
2135268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
2136268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            LHS, RHS);
2137268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SplitInteger(Sum, Lo, Hi);
2138268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2139268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Calculate the overflow: addition overflows iff a + b < a, and subtraction
2140268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // overflows iff a - b > a.
2141268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Sum, LHS,
2142268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                             N->getOpcode () == ISD::UADDO ?
2143268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                             ISD::SETULT : ISD::SETUGT);
2144268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2145268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Use the calculated overflow everywhere.
2146268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  ReplaceValueWith(SDValue(N, 1), Ofl);
2147268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman}
2148268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
214905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
2150475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2151e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2152c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2153d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
215405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2155825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2156a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::UDIV_I16;
2157825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
215805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I32;
2159825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
216005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I64;
2161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
216205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I128;
216305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
2164d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
2165475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2166c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
2167d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
2168cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
216905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
2170475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2171e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2172c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
217369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
217405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2175825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2176a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::UREM_I16;
2177825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
217805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I32;
2179825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
218005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I64;
2181825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
218205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I128;
218305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
2184cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2185475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2186c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
2187cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2188cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
218905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
2190475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                SDValue &Lo, SDValue &Hi) {
219123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2192786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2193475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
219405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
2195b3bc6352defdf1a5c6b1b0770d0c4d603f6524a8Duncan Sands    // The low part is zero extension of the input (degenerates to a copy).
2196786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
219705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getConstant(0, NVT);   // The high part is just a zero.
219805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
219905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
220005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
220196e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    assert(getTypeAction(Op.getValueType()) ==
220296e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem           TargetLowering::TypePromoteInteger &&
220305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
2204475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
220505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
220605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
220705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
220805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
220905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
221005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
2211adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng    Hi = DAG.getZeroExtendInReg(Hi, dl,
221254e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                                EVT::getIntegerVT(*DAG.getContext(),
221354e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                                                  ExcessBits));
22149e255b7df5a0a629920706e086e78ef89bf2f183Dan Gohman  }
2215cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2216cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2217cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2218cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
221969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Operand Expansion
2220cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
2221cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
222205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandIntegerOperand - This method is called when the specified operand of
222305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// the specified node is found to need expansion.  At this point, all of the
222405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// result types of the node are known to be legal, but other operands of the
222505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// node may need promotion or expansion as well as the specified one.
222605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsbool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
2227d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG); dbgs() << "\n");
2228475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = SDValue();
2229051bb7b07504be9f848f7cce802e62ed24980bc5Duncan Sands
2230f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
2231bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    return false;
223211ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands
2233bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  switch (N->getOpcode()) {
2234bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  default:
223505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  #ifndef NDEBUG
2236d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
2237d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
223805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  #endif
2239c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to expand this operator's operand!");
2240bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta
2241bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:           Res = ExpandOp_BITCAST(N); break;
224292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::BR_CC:             Res = ExpandIntOp_BR_CC(N); break;
224392abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::BUILD_VECTOR:      Res = ExpandOp_BUILD_VECTOR(N); break;
2244bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::EXTRACT_ELEMENT:   Res = ExpandOp_EXTRACT_ELEMENT(N); break;
2245bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
2246bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SCALAR_TO_VECTOR:  Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
224792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SELECT_CC:         Res = ExpandIntOp_SELECT_CC(N); break;
224892abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SETCC:             Res = ExpandIntOp_SETCC(N); break;
224992abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SINT_TO_FP:        Res = ExpandIntOp_SINT_TO_FP(N); break;
225092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::STORE:   Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
225192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::TRUNCATE:          Res = ExpandIntOp_TRUNCATE(N); break;
225292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::UINT_TO_FP:        Res = ExpandIntOp_UINT_TO_FP(N); break;
225355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
225455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SHL:
225555467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRA:
225655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRL:
225755467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTL:
22581c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  case ISD::ROTR:              Res = ExpandIntOp_Shift(N); break;
22591c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  case ISD::RETURNADDR:
22601c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  case ISD::FRAMEADDR:         Res = ExpandIntOp_RETURNADDR(N); break;
226105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
226269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
226305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If the result is null, the sub-method took care of registering results etc.
2264ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Res.getNode()) return false;
226547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
226647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // If the result is N, the sub-method updated N in place.  Tell the legalizer
226747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // core about this.
226847d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  if (Res.getNode() == N)
226905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return true;
2270cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
227105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
227205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Invalid operand expansion");
227305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2274475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 0), Res);
227505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  return false;
2276cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2277cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
227811ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands/// IntegerExpandSetCCOperands - Expand the operands of a comparison.  This code
227911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
2280475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
2281475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                  SDValue &NewRHS,
2282c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen                                                  ISD::CondCode &CCCode,
2283c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen                                                  DebugLoc dl) {
2284475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSLo, LHSHi, RHSLo, RHSHi;
228569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(NewLHS, LHSLo, LHSHi);
228669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(NewRHS, RHSLo, RHSHi);
228741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
2288cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
228911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    if (RHSLo == RHSHi) {
229011ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands      if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
2291cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        if (RHSCST->isAllOnesValue()) {
2292cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          // Equality comparison to -1.
22937fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands          NewLHS = DAG.getNode(ISD::AND, dl,
2294786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                               LHSLo.getValueType(), LHSLo, LHSHi);
2295cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          NewRHS = RHSLo;
2296cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          return;
2297cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        }
229811ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands      }
229911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    }
230069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2301786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
2302786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
2303786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
2304cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
2305cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2306cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
230769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2308cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If this is a comparison of the sign bit, just look at the top part.
2309cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // X > -1,  x < 0
2310cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
2311002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman    if ((CCCode == ISD::SETLT && CST->isNullValue()) ||     // X < 0
2312cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        (CCCode == ISD::SETGT && CST->isAllOnesValue())) {  // X > -1
2313cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      NewLHS = LHSHi;
2314cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      NewRHS = RHSHi;
2315cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      return;
2316cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
231769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2318cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // FIXME: This generated code sucks.
2319cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  ISD::CondCode LowCC;
2320cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  switch (CCCode) {
2321c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer setcc!");
2322cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETLT:
2323cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETULT: LowCC = ISD::SETULT; break;
2324cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETGT:
2325cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETUGT: LowCC = ISD::SETUGT; break;
2326cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETLE:
2327cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETULE: LowCC = ISD::SETULE; break;
2328cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETGE:
2329cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETUGE: LowCC = ISD::SETUGE; break;
2330cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
233169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2332cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Tmp1 = lo(op1) < lo(op2)   // Always unsigned comparison
2333cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Tmp2 = hi(op1) < hi(op2)   // Signedness depends on operands
2334cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
233569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2336cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // NOTE: on targets without efficient SELECT of bools, we can always use
2337cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
233878d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen  TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, true, NULL);
2339475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Tmp1, Tmp2;
23405480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
2341ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                           LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl);
2342ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Tmp1.getNode())
2343786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
23445480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                        LHSLo, RHSLo, LowCC);
23455480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
2346ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                           LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl);
2347ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Tmp2.getNode())
2348786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Tmp2 = DAG.getNode(ISD::SETCC, dl,
2349786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       TLI.getSetCCResultType(LHSHi.getValueType()),
23505480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                       LHSHi, RHSHi, DAG.getCondCode(CCCode));
235169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2352ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
2353ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode());
2354002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman  if ((Tmp1C && Tmp1C->isNullValue()) ||
2355002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman      (Tmp2C && Tmp2C->isNullValue() &&
2356cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner       (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
2357cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
2358002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman      (Tmp2C && Tmp2C->getAPIntValue() == 1 &&
2359cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner       (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
2360cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
2361cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // low part is known false, returns high part.
2362cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // For LE / GE, if high part is known false, ignore the low part.
2363cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // For LT / GT, if high part is known true, ignore the low part.
2364cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    NewLHS = Tmp2;
2365475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    NewRHS = SDValue();
2366cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2367cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
236869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
23695480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
2370fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel                             LHSHi, RHSHi, ISD::SETEQ, false,
2371ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                             DagCombineInfo, dl);
2372ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!NewLHS.getNode())
2373786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
23745480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                          LHSHi, RHSHi, ISD::SETEQ);
2375786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(),
2376cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                       NewLHS, Tmp1, Tmp2);
2377475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  NewRHS = SDValue();
2378cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2379cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2380475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
2381475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
238205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
2383c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
238405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
238505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, we need to compare the result
238605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // against zero to select between true and false values.
2387ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
238805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
238905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    CCCode = ISD::SETNE;
239005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
239105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
239205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Update N to have the operands specified.
2393027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
239405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
2395027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(4)), 0);
239605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
239705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2398475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
2399475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
240005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
2401c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
240205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
240305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, we need to compare the result
240405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // against zero to select between true and false values.
2405ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
240605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
240705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    CCCode = ISD::SETNE;
240805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
240905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
241005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Update N to have the operands specified.
2411027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
241205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                N->getOperand(2), N->getOperand(3),
2413027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                DAG.getCondCode(CCCode)), 0);
241405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
241505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2416475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
2417475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
241805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
2419c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
242005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
242105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, use it.
2422ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
242305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(NewLHS.getValueType() == N->getValueType(0) &&
242405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Unexpected setcc expansion!");
242505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return NewLHS;
242605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
242705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
242805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Otherwise, update N to have the operands specified.
2429027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
2430027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                DAG.getCondCode(CCCode)), 0);
243105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
243205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
243355467af31620c9d027e071ebcd9746b7593cff17Sanjiv GuptaSDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
243455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // The value being shifted is legal, but the shift amount is too big.
243555467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // It follows that either the result of the shift is undefined, or the
243655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // upper half of the shift amount is zero.  Just use the lower half.
243755467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  SDValue Lo, Hi;
243855467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  GetExpandedInteger(N->getOperand(1), Lo, Hi);
2439027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
244055467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta}
244155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
24421c3436a67afcfaee5f972836ff1ffff2985adce1Anton KorobeynikovSDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
24431c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant.  This
24441c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  // surely makes pretty nice problems on 8/16 bit targets. Just truncate this
24451c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  // constant to valid type.
24461c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  SDValue Lo, Hi;
24471c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  GetExpandedInteger(N->getOperand(0), Lo, Hi);
2448027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, Lo), 0);
24491c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov}
24501c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov
2451475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
2452475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
2453e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT DstVT = N->getValueType(0);
2454b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT);
245505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
245605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Don't know how to expand this SINT_TO_FP!");
2457c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc());
245805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
245905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2460475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
2461ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  if (ISD::isNormalStore(N))
2462ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands    return ExpandOp_NormalStore(N, OpNo);
246378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
246478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
2465cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  assert(OpNo == 1 && "Can only expand the stored value so far");
2466cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2467e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getOperand(1).getValueType();
246823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2469475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch  = N->getChain();
2470475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getBasePtr();
2471cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned Alignment = N->getAlignment();
2472cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  bool isVolatile = N->isVolatile();
24731e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = N->isNonTemporal();
2474786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2475475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
2476cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2477a1ace76c70ae5332d6f33fce5c0c1e2fdb8cca11Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
2478cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
247978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getMemoryVT().bitsLE(NVT)) {
248069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2481ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
24821e559443a17d1b335f697551c6263ba60d5dd827David Greene                             N->getMemoryVT(), isVolatile, isNonTemporal,
24831e559443a17d1b335f697551c6263ba60d5dd827David Greene                             Alignment);
2484ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  }
2485bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2486ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  if (TLI.isLittleEndian()) {
2487cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Little-endian - low bits are at low addresses.
248869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2489cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2490ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
24911e559443a17d1b335f697551c6263ba60d5dd827David Greene                      isVolatile, isNonTemporal, Alignment);
2492cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2493cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits =
249483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
249523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
2496cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2497cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
249883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
2499786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
25000bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
2501ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
2502ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                           N->getPointerInfo().getWithOffset(IncrementSize),
2503ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                           NEVT, isVolatile, isNonTemporal,
25041e559443a17d1b335f697551c6263ba60d5dd827David Greene                           MinAlign(Alignment, IncrementSize));
2505825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2506ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  }
2507cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2508ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Big-endian - high bits are at low addresses.  Favor aligned stores at
2509ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // the cost of some bit-fiddling.
2510ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  GetExpandedInteger(N->getValue(), Lo, Hi);
2511ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2512ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  EVT ExtVT = N->getMemoryVT();
2513ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  unsigned EBytes = ExtVT.getStoreSize();
2514ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  unsigned IncrementSize = NVT.getSizeInBits()/8;
2515ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  unsigned ExcessBits = (EBytes - IncrementSize)*8;
2516ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  EVT HiVT = EVT::getIntegerVT(*DAG.getContext(),
2517ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                               ExtVT.getSizeInBits() - ExcessBits);
2518ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2519ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  if (ExcessBits < NVT.getSizeInBits()) {
2520ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    // Transfer high bits from the top of Lo to the bottom of Hi.
2521ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
2522ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                     DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
2523ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                                     TLI.getPointerTy()));
2524ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Hi = DAG.getNode(ISD::OR, dl, NVT, Hi,
2525ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                     DAG.getNode(ISD::SRL, dl, NVT, Lo,
2526ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                                 DAG.getConstant(ExcessBits,
2527ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                                                 TLI.getPointerTy())));
2528cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
2529ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2530ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Store both the high bits and maybe some of the low bits.
2531ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(),
2532ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         HiVT, isVolatile, isNonTemporal, Alignment);
2533ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2534ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Increment the pointer to the other half.
2535ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2536ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                    DAG.getIntPtrConstant(IncrementSize));
2537ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Store the lowest ExcessBits bits in the second half.
2538ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
2539ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         N->getPointerInfo().getWithOffset(IncrementSize),
2540ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
2541ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         isVolatile, isNonTemporal,
2542ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         MinAlign(Alignment, IncrementSize));
2543ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2544cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
254505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2546475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
2547475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
254805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
254905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Just truncate the low part of the source.
2550786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL);
255105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
255205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
25538d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesenstatic const fltSemantics *EVTToAPFloatSemantics(EVT VT) {
25548d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  switch (VT.getSimpleVT().SimpleTy) {
25558d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  default: llvm_unreachable("Unknown FP format");
25568d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f32:     return &APFloat::IEEEsingle;
25578d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f64:     return &APFloat::IEEEdouble;
25588d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f80:     return &APFloat::x87DoubleExtended;
25598d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f128:    return &APFloat::IEEEquad;
25608d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::ppcf128: return &APFloat::PPCDoubleDouble;
25618d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  }
25628d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen}
25638d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen
2564475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
2565475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
2566e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT SrcVT = Op.getValueType();
2567e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT DstVT = N->getValueType(0);
2568c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
256905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
25708d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  // The following optimization is valid only if every value in SrcVT (when
25718d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  // treated as signed) is representable in DstVT.  Check that the mantissa
25728d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  // size of DstVT is >= than the number of bits in SrcVT -1.
25738d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  const fltSemantics *sem = EVTToAPFloatSemantics(DstVT);
25748d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  if (APFloat::semanticsPrecision(*sem) >= SrcVT.getSizeInBits()-1 &&
25758d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen      TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
257605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Do a signed conversion then adjust the result.
2577786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);
257805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SignedConv = TLI.LowerOperation(SignedConv, DAG);
257905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
258005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The result of the signed conversion needs adjusting if the 'sign bit' of
258105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // the incoming integer was set.  To handle this, we dynamically test to see
258205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // if it is set, and, if so, add a fudge factor.
258305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
258405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE32  = 0x4F800000ULL;
258505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE64  = 0x5F800000ULL;
258605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE128 = 0x7F800000ULL;
258705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
258805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    APInt FF(32, 0);
2589825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (SrcVT == MVT::i32)
259005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE32);
2591825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (SrcVT == MVT::i64)
259205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE64);
2593825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (SrcVT == MVT::i128)
259405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE128);
259505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    else
259605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      assert(false && "Unsupported UINT_TO_FP!");
259705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
259805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Check whether the sign bit is set.
2599475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
260005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    GetExpandedInteger(Op, Lo, Hi);
26017fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands    SDValue SignSet = DAG.getSetCC(dl,
2602786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                                   TLI.getSetCCResultType(Hi.getValueType()),
26035480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                                   Hi, DAG.getConstant(0, Hi.getValueType()),
2604ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   ISD::SETLT);
260505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
260605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.
2607001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson    SDValue FudgePtr = DAG.getConstantPool(
2608eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson                               ConstantInt::get(*DAG.getContext(), FF.zext(64)),
260949c18cce976c158e86f54c681dff21bb81640fb8Duncan Sands                                           TLI.getPointerTy());
261005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
261105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
2612475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Zero = DAG.getIntPtrConstant(0);
2613475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Four = DAG.getIntPtrConstant(4);
261405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (TLI.isBigEndian()) std::swap(Zero, Four);
2615786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet,
2616ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                 Zero, Four);
26171606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment();
2618786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset);
261987a0f10dc7eff8cf5e83a754f75adf9cb3991435Dan Gohman    Alignment = std::min(Alignment, 4u);
262005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
262105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Load the value out, extending it from f32 to the destination float type.
262205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // FIXME: Avoid the extend by constructing the right constant pool?
2623a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
26243d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                                   FudgePtr,
26253d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                                   MachinePointerInfo::getConstantPool(),
26263d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                                   MVT::f32,
26271e559443a17d1b335f697551c6263ba60d5dd827David Greene                                   false, false, Alignment);
2628786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
262905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
263005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
263105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Otherwise, use a libcall.
2632b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT);
263305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
263405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Don't know how to expand this UINT_TO_FP!");
2635c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  return MakeLibCall(LC, DstVT, &Op, 1, true, dl);
263605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
2637fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2638fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
2639fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue InOp0 = N->getOperand(0);
2640fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT InVT = InOp0.getValueType();
2641fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
2642fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2643fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2644fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2645fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2646fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  unsigned OutNumElems = N->getValueType(0).getVectorNumElements();
2647fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2648fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2649fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2650fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue BaseIdx = N->getOperand(1);
2651fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2652fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<SDValue, 8> Ops;
2653fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned i = 0; i != OutNumElems; ++i) {
2654fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2655fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    // Extract the element from the original vector.
2656fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(),
2657fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      BaseIdx, DAG.getIntPtrConstant(i));
2658fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2659fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      InVT.getVectorElementType(), N->getOperand(0), Index);
2660fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2661fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, Ext);
2662fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    // Insert the converted element to the new vector.
2663fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    Ops.push_back(Op);
2664fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2665fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2666fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size());
2667fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2668fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2669fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2670fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) {
2671fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2672fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N);
2673fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT VT = N->getValueType(0);
2674fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2675fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2676fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  unsigned NumElts = VT.getVectorNumElements();
2677fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<int, 8> NewMask;
2678fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned i = 0; i != NumElts; ++i) {
2679fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    NewMask.push_back(SV->getMaskElt(i));
2680fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2681fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2682fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V0 = GetPromotedInteger(N->getOperand(0));
2683fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V1 = GetPromotedInteger(N->getOperand(1));
2684fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2685fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2686fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getVectorShuffle(OutVT, dl, V0,V1, &NewMask[0]);
2687fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2688fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2689fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2690fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
2691fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2692fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue InOp0 = N->getOperand(0);
2693fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT InVT = InOp0.getValueType();
2694fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
2695fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2696fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2697fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2698fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2699fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  unsigned NumElems = N->getNumOperands();
2700fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2701fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2702fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2703fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2704fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<SDValue, 8> Ops;
2705fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned i = 0; i != NumElems; ++i) {
2706fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(i));
2707fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    Ops.push_back(Op);
2708fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2709fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2710fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size());
2711fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2712fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2713fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N) {
2714fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2715fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2716fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2717fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue InOp0 = N->getOperand(0);
2718fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT InVT = InOp0.getValueType();
2719fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
2720fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(!InVT.isVector() && "Input must not be a scalar");
2721fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2722fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2723fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2724fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2725fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2726fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2727fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(0));
2728fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2729fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NOutVT, Op);
2730fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2731fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2732fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) {
2733fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2734fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue InOp0 = N->getOperand(0);
2735fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT InVT = InOp0.getValueType();
2736fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT InElVT = InVT.getVectorElementType();
2737fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
2738fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2739fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2740fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2741fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2742fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2743fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2744fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2745fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2746fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2747fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue ConvertedVector = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, InOp0);
2748fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2749fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl,
2750fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    NOutVTElem, N->getOperand(1));
2751fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,NOutVT,
2752fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    ConvertedVector, ConvElem, N->getOperand(2));
2753fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2754fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2755fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
2756fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2757fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V0 = GetPromotedInteger(N->getOperand(0));
2758fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V1 = N->getOperand(1);
2759fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2760fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    V0->getValueType(0).getScalarType(), V0, V1);
2761fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2762fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), Ext);
2763fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2764fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2765fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2766fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
2767fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2768fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2769fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2770fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT RetSclrTy = N->getValueType(0).getVectorElementType();
2771fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2772fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<SDValue, 8> NewOps;
2773fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2774fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  // For each incoming vector
2775fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned VecIdx = 0, E = N->getNumOperands(); VecIdx!= E; ++VecIdx) {
2776fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx));
2777fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    EVT SclrTy = Incoming->getValueType(0).getVectorElementType();
2778fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    unsigned NumElem = Incoming->getValueType(0).getVectorNumElements();
2779fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2780fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    for (unsigned i=0; i<NumElem; ++i) {
2781fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      // Extract element from incoming vector
2782fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy,
2783fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      Incoming, DAG.getIntPtrConstant(i));
2784fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex);
2785fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      NewOps.push_back(Tr);
2786fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    }
2787fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2788fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2789fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::BUILD_VECTOR, dl,  N->getValueType(0),
2790fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    &NewOps[0], NewOps.size());
2791fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2792