LegalizeIntegerTypes.cpp revision 331120b1a482b782e8dffce63033bb8514ba2a96
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"
22362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher#include "llvm/DerivedTypes.h"
23c82bf9b268eb63f7cf6f435d9ea222ddb8e3c5a8Mon P Wang#include "llvm/CodeGen/PseudoSourceValue.h"
247d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h"
25fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman#include "llvm/Support/raw_ostream.h"
26cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattnerusing namespace llvm;
27cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
28cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
2969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Result Promotion
30cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
31cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
3269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// PromoteIntegerResult - This method is called when a result of a node is
3369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// found to be in need of promotion to a larger type.  At this point, the node
3469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// may also have invalid operands or may have other results that need
3569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// expansion, we just know that (at least) one result needs promotion.
3669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
37d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Promote integer result: "; N->dump(&DAG); dbgs() << "\n");
389fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  SDValue Res = SDValue();
3969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
40126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands  // See if the target wants to custom expand this node.
41f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getValueType(ResNo), true))
421607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands    return;
43126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands
4469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (N->getOpcode()) {
4569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  default:
4669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands#ifndef NDEBUG
47d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "PromoteIntegerResult #" << ResNo << ": ";
48d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
4969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands#endif
50c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to promote this operator!");
5162bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  case ISD::MERGE_VALUES:Res = PromoteIntRes_MERGE_VALUES(N); break;
529fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::AssertSext:  Res = PromoteIntRes_AssertSext(N); break;
539fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::AssertZext:  Res = PromoteIntRes_AssertZext(N); break;
54bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:     Res = PromoteIntRes_BITCAST(N); break;
559fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BSWAP:       Res = PromoteIntRes_BSWAP(N); break;
569fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BUILD_PAIR:  Res = PromoteIntRes_BUILD_PAIR(N); break;
579fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::Constant:    Res = PromoteIntRes_Constant(N); break;
5800ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  case ISD::CONVERT_RNDSAT:
599fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_CONVERT_RNDSAT(N); break;
609fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTLZ:        Res = PromoteIntRes_CTLZ(N); break;
619fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTPOP:       Res = PromoteIntRes_CTPOP(N); break;
629fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTTZ:        Res = PromoteIntRes_CTTZ(N); break;
63bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  case ISD::EXTRACT_VECTOR_ELT:
649fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break;
659fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::LOAD:        Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N));break;
669fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SELECT:      Res = PromoteIntRes_SELECT(N); break;
67436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem  case ISD::VSELECT:     Res = PromoteIntRes_VSELECT(N); break;
689fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SELECT_CC:   Res = PromoteIntRes_SELECT_CC(N); break;
699fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SETCC:       Res = PromoteIntRes_SETCC(N); break;
709fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SHL:         Res = PromoteIntRes_SHL(N); break;
718d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands  case ISD::SIGN_EXTEND_INREG:
729fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break;
739fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SRA:         Res = PromoteIntRes_SRA(N); break;
749fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SRL:         Res = PromoteIntRes_SRL(N); break;
759fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::TRUNCATE:    Res = PromoteIntRes_TRUNCATE(N); break;
769fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UNDEF:       Res = PromoteIntRes_UNDEF(N); break;
779fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::VAARG:       Res = PromoteIntRes_VAARG(N); break;
78bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
79fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::EXTRACT_SUBVECTOR:
80fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_EXTRACT_SUBVECTOR(N); break;
81fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::VECTOR_SHUFFLE:
82fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_VECTOR_SHUFFLE(N); break;
83fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::INSERT_VECTOR_ELT:
84fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_INSERT_VECTOR_ELT(N); break;
85fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::BUILD_VECTOR:
86fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_BUILD_VECTOR(N); break;
87fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::SCALAR_TO_VECTOR:
88fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem                         Res = PromoteIntRes_SCALAR_TO_VECTOR(N); break;
89fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
9069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SIGN_EXTEND:
9169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ZERO_EXTEND:
929fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::ANY_EXTEND:  Res = PromoteIntRes_INT_EXTEND(N); break;
93bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
9469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_SINT:
959fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::FP_TO_UINT:  Res = PromoteIntRes_FP_TO_XINT(N); break;
9669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
97927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  case ISD::FP32_TO_FP16:Res = PromoteIntRes_FP32_TO_FP16(N); break;
98927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
9969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::AND:
10069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::OR:
10169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::XOR:
10269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ADD:
10369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SUB:
1049fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::MUL:         Res = PromoteIntRes_SimpleIntBinOp(N); break;
10569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
10669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SDIV:
1079fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SREM:        Res = PromoteIntRes_SDIV(N); break;
10869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
10969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::UDIV:
1109fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UREM:        Res = PromoteIntRes_UDIV(N); break;
1118ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
112253174bf50c932abaa680f465e2888c0e5272267Bill Wendling  case ISD::SADDO:
1139fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SSUBO:       Res = PromoteIntRes_SADDSUBO(N, ResNo); break;
11474c376529101acbe141a256d0bf23a44eb454c84Bill Wendling  case ISD::UADDO:
1159fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::USUBO:       Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
11674c376529101acbe141a256d0bf23a44eb454c84Bill Wendling  case ISD::SMULO:
1179fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UMULO:       Res = PromoteIntRes_XMULO(N, ResNo); break;
118b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
119331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  case ISD::ATOMIC_LOAD:
120331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman    Res = PromoteIntRes_Atomic0(cast<AtomicSDNode>(N)); break;
121331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman
1220b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_ADD:
1230b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_SUB:
1240b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_AND:
1250b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_OR:
1260b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_XOR:
1270b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_NAND:
1280b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_MIN:
1290b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_MAX:
1300b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_UMIN:
1310b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_UMAX:
1320b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_SWAP:
1339fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break;
134b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
1350b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_CMP_SWAP:
1369fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    Res = PromoteIntRes_Atomic2(cast<AtomicSDNode>(N)); break;
13769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
13869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1399fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  // If the result is null then the sub-method took care of registering it.
1409fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  if (Res.getNode())
1419fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    SetPromotedInteger(SDValue(N, ResNo), Res);
14269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
14369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
14462bb16cfd10dd271eab6c31d982bca4d79138602Eli FriedmanSDValue DAGTypeLegalizer::PromoteIntRes_MERGE_VALUES(SDNode *N) {
14562bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  SDValue Op = DecomposeMERGE_VALUES(N);
14662bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  return GetPromotedInteger(Op);
14762bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman}
14862bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman
149475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
15095db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  // Sign-extend the new bits, and continue the assertion.
151c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = SExtPromotedInteger(N->getOperand(0));
152786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::AssertSext, N->getDebugLoc(),
153786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
15495db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
15595db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
156475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
15795db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  // Zero the new bits, and continue the assertion.
158c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
159786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::AssertZext, N->getDebugLoc(),
160786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
16195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
16295db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
163331120b1a482b782e8dffce63033bb8514ba2a96Eli FriedmanSDValue DAGTypeLegalizer::PromoteIntRes_Atomic0(AtomicSDNode *N) {
164331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  EVT ResVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
165331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
166331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman                              N->getMemoryVT(), ResVT,
167331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman                              N->getChain(), N->getBasePtr(),
168331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman                              N->getMemOperand(), N->getOrdering(),
169331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman                              N->getSynchScope());
170331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  // Legalized the chain result - switch anything that used the old chain to
171331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  // use the new one.
172331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
173331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  return Res;
174331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman}
175331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman
176b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
177b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
1787fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
179786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                              N->getMemoryVT(),
1800b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman                              N->getChain(), N->getBasePtr(),
18155ba816883842e793cdeb32fcb805c4e011b527fEli Friedman                              Op2, N->getMemOperand(), N->getOrdering(),
18255ba816883842e793cdeb32fcb805c4e011b527fEli Friedman                              N->getSynchScope());
183b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
184b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // use the new one.
185b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
186b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  return Res;
187b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands}
188b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
189b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) {
190b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
191b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op3 = GetPromotedInteger(N->getOperand(3));
192fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
193f8d3ec2c5725a2010f11de4ba78f6127712a5fe7Dale Johannesen                              N->getMemoryVT(), N->getChain(), N->getBasePtr(),
19455ba816883842e793cdeb32fcb805c4e011b527fEli Friedman                              Op2, Op3, N->getMemOperand(), N->getOrdering(),
19555ba816883842e793cdeb32fcb805c4e011b527fEli Friedman                              N->getSynchScope());
196b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
197b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // use the new one.
198b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
199b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  return Res;
200b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands}
201b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
202bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) {
203475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InOp = N->getOperand(0);
204e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT InVT = InOp.getValueType();
20523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
206e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OutVT = N->getValueType(0);
20723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
208786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
20969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
21069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (getTypeAction(InVT)) {
21169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  default:
21269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    assert(false && "Unknown type action!");
21369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
21496e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeLegal:
21569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
21696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypePromoteInteger:
21747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands    if (NOutVT.bitsEq(NInVT))
21869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands      // The input promotes to the same size.  Convert the promoted value.
219bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetPromotedInteger(InOp));
22069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
22196e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeSoftenFloat:
22269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Promote the integer operand by hand.
223786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
22496e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeExpandInteger:
22596e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeExpandFloat:
22669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
22796e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeScalarizeVector:
22869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Convert the element to an integer and promote it by hand.
229c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem    if (!NOutVT.isVector())
230c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem      return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
231c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem                         BitConvertToInteger(GetScalarizedVector(InOp)));
232c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem    break;
23396e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeSplitVector: {
234bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // For example, i32 = BITCAST v2i16 on alpha.  Convert the split
23569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // pieces of the input into integers and reassemble in the final type.
236475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
23769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetSplitVector(N->getOperand(0), Lo, Hi);
23869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    Lo = BitConvertToInteger(Lo);
23969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    Hi = BitConvertToInteger(Hi);
24069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
24169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    if (TLI.isBigEndian())
24269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands      std::swap(Lo, Hi);
24369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
244786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    InOp = DAG.getNode(ISD::ANY_EXTEND, dl,
245adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                       EVT::getIntegerVT(*DAG.getContext(),
246adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                                         NOutVT.getSizeInBits()),
24769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                       JoinIntegers(Lo, Hi));
248bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return DAG.getNode(ISD::BITCAST, dl, NOutVT, InOp);
24969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
25096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeWidenVector:
25187c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang    if (OutVT.bitsEq(NInVT))
25287c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang      // The input is widened to the same size.  Convert to the widened value.
253bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      return DAG.getNode(ISD::BITCAST, dl, OutVT, GetWidenedVector(InOp));
25487c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang  }
25569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
256aad3460086a1b29c55f7490c6d8743ea4e53f07dEli Friedman  return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
257aad3460086a1b29c55f7490c6d8743ea4e53f07dEli Friedman                     CreateStackStoreLoad(InOp, OutVT));
25869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
25969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
260475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
261475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
262e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getValueType(0);
263e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Op.getValueType();
264786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
265c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands
266c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands  unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
267786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
26853dfa78e4133f6cdb5d860279adc337ea099ac15Duncan Sands                     DAG.getConstant(DiffBits, TLI.getPointerTy()));
269c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands}
270c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands
271475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
272bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The pair element type may be legal, or may not promote to the same type as
273bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // the result, for example i14 = BUILD_PAIR (i7, i7).  Handle all cases.
274786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(),
27554e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     TLI.getTypeToTransformTo(*DAG.getContext(),
27654e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     N->getValueType(0)), JoinIntegers(N->getOperand(0),
27754e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     N->getOperand(1)));
27869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
27969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
280475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
281e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
282b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  // FIXME there is no actual debug info here
283b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  DebugLoc dl = N->getDebugLoc();
284bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Zero extend things like i1, sign extend everything else.  It shouldn't
285bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // matter in theory which one we pick, but this tends to give better code?
286bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
28754e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher  SDValue Result = DAG.getNode(Opc, dl,
28854e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                               TLI.getTypeToTransformTo(*DAG.getContext(), VT),
289a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands                               SDValue(N, 0));
290bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
291bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return Result;
29269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
29369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
29400ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P WangSDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_RNDSAT(SDNode *N) {
29500ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
29600ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
29700ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
29800ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang           CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
29900ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang          "can only promote integers");
30023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OutVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
301c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen  return DAG.getConvertRndSat(OutVT, N->getDebugLoc(), N->getOperand(0),
30200ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang                              N->getOperand(1), N->getOperand(2),
30300ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang                              N->getOperand(3), N->getOperand(4), CvtCode);
30400ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang}
30500ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang
306475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
307c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  // Zero extend to the promoted type and do the count there.
308c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
309b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  DebugLoc dl = N->getDebugLoc();
310e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getValueType(0);
311e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Op.getValueType();
312b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  Op = DAG.getNode(ISD::CTLZ, dl, NVT, Op);
31369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Subtract off the extra leading bits in the bigger type.
314b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  return DAG.getNode(ISD::SUB, dl, NVT, Op,
31569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                     DAG.getConstant(NVT.getSizeInBits() -
31669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                     OVT.getSizeInBits(), NVT));
31769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
31869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
319475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
32069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Zero extend to the promoted type and do the count there.
321c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
322786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op);
32369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
32469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
325475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
326475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
327e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getValueType(0);
328e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Op.getValueType();
329786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
33069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // The count is the same in the promoted type except if the original
33169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // value was zero.  This can be handled by setting the bit just off
33269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // the top of the original type.
33303dc093a2e63d20984c8fd67809fa762f1e31f1aDuncan Sands  APInt TopBit(NVT.getSizeInBits(), 0);
3347a874ddda037349184fbeb22838cc11a1a9bb78fJay Foad  TopBit.setBit(OVT.getSizeInBits());
335786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
336786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::CTTZ, dl, NVT, Op);
33769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
33869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
339475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
340786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
34123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
342c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0),
343c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman                     N->getOperand(1));
34469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
34569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
346475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
34723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
348a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  unsigned NewOpc = N->getOpcode();
349786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
350d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands
3514c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is
3524c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // not Legal, check to see if we can use FP_TO_SINT instead.  (If both UINT
35354e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher  // and SINT conversions are Custom, there is no way to tell which is
35454e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher  // preferable. We choose SINT because that's the right thing on PPC.)
355a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  if (N->getOpcode() == ISD::FP_TO_UINT &&
3564c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen      !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
357f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman      TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
358a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands    NewOpc = ISD::FP_TO_SINT;
359a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands
360786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0));
361a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands
362a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // Assert that the converted value fits in the original type.  If it doesn't
363a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // (eg: because the value being converted is too big), then the result of the
364a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // original operation was undefined anyway, so the assert is still correct.
365a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ?
3660928c9e18a1decd856501beeea1bd12453a366b3Nadav Rotem                     ISD::AssertZext : ISD::AssertSext, dl, NVT, Res,
3670928c9e18a1decd856501beeea1bd12453a366b3Nadav Rotem                     DAG.getValueType(N->getValueType(0).getScalarType()));
368d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands}
369d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands
370927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton KorobeynikovSDValue DAGTypeLegalizer::PromoteIntRes_FP32_TO_FP16(SDNode *N) {
371927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
372927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  DebugLoc dl = N->getDebugLoc();
373927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
374927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
375927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
376927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  return DAG.getNode(ISD::AssertZext, dl,
377927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov                     NVT, Res, DAG.getValueType(N->getValueType(0)));
378927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov}
379927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov
380475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
38123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
382786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
383be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands
38496e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  if (getTypeAction(N->getOperand(0).getValueType())
38596e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem      == TargetLowering::TypePromoteInteger) {
386475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(N->getOperand(0));
3876959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands    assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!");
388126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands
389bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    // If the result and operand types are the same after promotion, simplify
390bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    // to an in-register extension.
391bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    if (NVT == Res.getValueType()) {
392bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      // The high bits are not guaranteed to be anything.  Insert an extend.
393bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      if (N->getOpcode() == ISD::SIGN_EXTEND)
394786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
395bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                           DAG.getValueType(N->getOperand(0).getValueType()));
396bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      if (N->getOpcode() == ISD::ZERO_EXTEND)
3970928c9e18a1decd856501beeea1bd12453a366b3Nadav Rotem        return DAG.getZeroExtendInReg(Res, dl,
3980928c9e18a1decd856501beeea1bd12453a366b3Nadav Rotem                      N->getOperand(0).getValueType().getScalarType());
399bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
400bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      return Res;
401126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands    }
40269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
40369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
404bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Otherwise, just extend the original operand all the way to the larger type.
405786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
406bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
40769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
408475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
409bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
41023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
411bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  ISD::LoadExtType ExtType =
412bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
413786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
414a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings  SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
4153d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                               N->getPointerInfo(),
41647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands                               N->getMemoryVT(), N->isVolatile(),
4171e559443a17d1b335f697551c6263ba60d5dd827David Greene                               N->isNonTemporal(), N->getAlignment());
41869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
419bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
420bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // use the new one.
421475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
422bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return Res;
42369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
42469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
425874ae251c317788391f9c3f113957802d390a063Dale Johannesen/// Promote the overflow flag of an overflowing arithmetic node.
426ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
427ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Simply change the return type of the boolean result.
42823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1));
429e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ValueVTs[] = { N->getValueType(0), NVT };
430ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
431786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
432786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                            DAG.getVTList(ValueVTs, 2), Ops, 2);
433ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
434ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Modified the sum result - switch anything that used the old sum to use
435ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the new one.
436ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 0), Res);
437ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
438ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return SDValue(Res.getNode(), 1);
439ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
440ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
441ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
442ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  if (ResNo == 1)
443ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands    return PromoteIntRes_Overflow(N);
444ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
445ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // The operation overflowed iff the result in the larger type is not the
446ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // sign extension of its truncation to the original type.
447ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
448ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
449e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getOperand(0).getValueType();
450e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = LHS.getValueType();
451786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
452ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
453ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Do the arithmetic in the larger type.
454ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
455786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
456ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
457ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Calculate the overflow flag: sign extend the arithmetic result from
458ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the original type.
459786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
460ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands                            DAG.getValueType(OVT));
461ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Overflowed if and only if this is not equal to Res.
462786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
463ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
464ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Use the calculated overflow everywhere.
465ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 1), Ofl);
466ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
467ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return Res;
468ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
469ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
470475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
471bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Sign extend the input.
472c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
473c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
474786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
475786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), LHS, RHS);
47669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
47769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
478475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
479475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(1));
480475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(2));
481786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
482786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), N->getOperand(0),LHS,RHS);
48369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
48469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
485436fe8498a0a3368d2690290e805213a0f114d0dNadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_VSELECT(SDNode *N) {
486436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem  SDValue Mask = GetPromotedInteger(N->getOperand(0));
487436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem  SDValue LHS = GetPromotedInteger(N->getOperand(1));
488436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem  SDValue RHS = GetPromotedInteger(N->getOperand(2));
489436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem  return DAG.getNode(ISD::VSELECT, N->getDebugLoc(),
490436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem                     LHS.getValueType(), Mask, LHS, RHS);
491436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem}
492436fe8498a0a3368d2690290e805213a0f114d0dNadav Rotem
493475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
494475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(2));
495475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(3));
496786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
497786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), N->getOperand(0),
498bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     N->getOperand(1), LHS, RHS, N->getOperand(4));
49969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
50069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
501475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
502e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType());
50328b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands
504786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
50528b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  assert(SVT.isVector() == N->getOperand(0).getValueType().isVector() &&
50628b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands         "Vector compare must return a vector result!");
5077e4982287591945c4e42ba8470a978e629789c76Duncan Sands
5087e4982287591945c4e42ba8470a978e629789c76Duncan Sands  // Get the SETCC result using the canonical SETCC type.
50928b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  SDValue SetCC = DAG.getNode(N->getOpcode(), dl, SVT, N->getOperand(0),
5107e4982287591945c4e42ba8470a978e629789c76Duncan Sands                              N->getOperand(1), N->getOperand(2));
5117e4982287591945c4e42ba8470a978e629789c76Duncan Sands
5127e4982287591945c4e42ba8470a978e629789c76Duncan Sands  // Convert to the expected type.
51323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5146959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands  assert(NVT.bitsLE(SVT) && "Integer type overpromoted?");
515786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC);
51669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
51769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
518475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
519786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SHL, N->getDebugLoc(),
520182465c589f95ff165331d06035ec53ff05bf1f5Evan Cheng                TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)),
521bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
52269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
52369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
524475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
525475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
526786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(),
527786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
5288d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands}
5298d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands
530475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
531bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input may have strange things in the top bits of the registers, but
532bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // these operations don't care.  They may have weird bits going out, but
533bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // that too is okay if they are integer operations.
534475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(0));
535475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(1));
536786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
537786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                    LHS.getValueType(), LHS, RHS);
53869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
53969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
540475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
541bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input value must be properly sign extended.
542c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Res = SExtPromotedInteger(N->getOperand(0));
543786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRA, N->getDebugLoc(),
544786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Res.getValueType(), Res, N->getOperand(1));
545bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
54669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
547475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
548bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input value must be properly zero extended.
549e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
55023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
551475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = ZExtPromotedInteger(N->getOperand(0));
552786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1));
55369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
55469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
555475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
55623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
557475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res;
5584720611025276f01b158a1522620391332ffdc32Nadav Rotem  SDValue InOp = N->getOperand(0);
5594720611025276f01b158a1522620391332ffdc32Nadav Rotem  DebugLoc dl = N->getDebugLoc();
56069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
5614720611025276f01b158a1522620391332ffdc32Nadav Rotem  switch (getTypeAction(InOp.getValueType())) {
562c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown type action!");
56396e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeLegal:
56496e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypeExpandInteger:
5654720611025276f01b158a1522620391332ffdc32Nadav Rotem    Res = InOp;
566bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    break;
56796e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem  case TargetLowering::TypePromoteInteger:
5684720611025276f01b158a1522620391332ffdc32Nadav Rotem    Res = GetPromotedInteger(InOp);
569bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    break;
5704720611025276f01b158a1522620391332ffdc32Nadav Rotem  case TargetLowering::TypeSplitVector:
5714720611025276f01b158a1522620391332ffdc32Nadav Rotem    EVT InVT = InOp.getValueType();
5724720611025276f01b158a1522620391332ffdc32Nadav Rotem    assert(InVT.isVector() && "Cannot split scalar types");
5734720611025276f01b158a1522620391332ffdc32Nadav Rotem    unsigned NumElts = InVT.getVectorNumElements();
5744720611025276f01b158a1522620391332ffdc32Nadav Rotem    assert(NumElts == NVT.getVectorNumElements() &&
5754720611025276f01b158a1522620391332ffdc32Nadav Rotem           "Dst and Src must have the same number of elements");
5764720611025276f01b158a1522620391332ffdc32Nadav Rotem    EVT EltVT = InVT.getScalarType();
5774720611025276f01b158a1522620391332ffdc32Nadav Rotem    assert(isPowerOf2_32(NumElts) &&
5784720611025276f01b158a1522620391332ffdc32Nadav Rotem           "Promoted vector type must be a power of two");
5794720611025276f01b158a1522620391332ffdc32Nadav Rotem
5804720611025276f01b158a1522620391332ffdc32Nadav Rotem    EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts/2);
5814720611025276f01b158a1522620391332ffdc32Nadav Rotem    EVT HalfNVT = EVT::getVectorVT(*DAG.getContext(), NVT.getScalarType(),
5824720611025276f01b158a1522620391332ffdc32Nadav Rotem                                   NumElts/2);
5834720611025276f01b158a1522620391332ffdc32Nadav Rotem
5844720611025276f01b158a1522620391332ffdc32Nadav Rotem    SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfVT, InOp,
5854720611025276f01b158a1522620391332ffdc32Nadav Rotem                               DAG.getIntPtrConstant(0));
5864720611025276f01b158a1522620391332ffdc32Nadav Rotem    SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfVT, InOp,
5874720611025276f01b158a1522620391332ffdc32Nadav Rotem                               DAG.getIntPtrConstant(NumElts/2));
5884720611025276f01b158a1522620391332ffdc32Nadav Rotem    EOp1 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp1);
5894720611025276f01b158a1522620391332ffdc32Nadav Rotem    EOp2 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp2);
5904720611025276f01b158a1522620391332ffdc32Nadav Rotem
5914720611025276f01b158a1522620391332ffdc32Nadav Rotem    return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, EOp1, EOp2);
592bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  }
593bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
594bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Truncate to NVT instead of VT
5954720611025276f01b158a1522620391332ffdc32Nadav Rotem  return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res);
59669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
59769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
598ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
599ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  if (ResNo == 1)
600ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands    return PromoteIntRes_Overflow(N);
601ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
602ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // The operation overflowed iff the result in the larger type is not the
603ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // zero extension of its truncation to the original type.
604c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
605c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
606e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getOperand(0).getValueType();
607e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = LHS.getValueType();
608786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
60969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
610ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Do the arithmetic in the larger type.
611ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
612786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
6138ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
614ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Calculate the overflow flag: zero extend the arithmetic result from
615ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the original type.
6164be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT);
617ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Overflowed if and only if this is not equal to Res.
618786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
6198ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
620ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Use the calculated overflow everywhere.
621ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 1), Ofl);
6228ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
623ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return Res;
624ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
625ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
6265c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris LattnerSDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
6275c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  // Promote the overflow bit trivially.
6285c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  if (ResNo == 1)
6295c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    return PromoteIntRes_Overflow(N);
630fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands
6315c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
6325c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  DebugLoc DL = N->getDebugLoc();
633fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands  EVT SmallVT = LHS.getValueType();
634fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands
635b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // To determine if the result overflowed in a larger type, we extend the
636b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // input to the larger type, do the multiply, then check the high bits of
637b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // the result to see if the overflow happened.
6385c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  if (N->getOpcode() == ISD::SMULO) {
6395c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    LHS = SExtPromotedInteger(LHS);
6405c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    RHS = SExtPromotedInteger(RHS);
6415c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  } else {
6425c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    LHS = ZExtPromotedInteger(LHS);
6435c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    RHS = ZExtPromotedInteger(RHS);
6445c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  }
6455c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
646fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands
647b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // Overflow occurred iff the high part of the result does not
648b3e009a165a423536acfa5861c12ef631239d9e4Eric Christopher  // zero/sign-extend the low part.
6495c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  SDValue Overflow;
6505c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  if (N->getOpcode() == ISD::UMULO) {
651fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    // Unsigned overflow occurred iff the high part is non-zero.
6525c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
653fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands                             DAG.getIntPtrConstant(SmallVT.getSizeInBits()));
6545c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner    Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
6555c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner                            DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
6565c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  } else {
657fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    // Signed overflow occurred iff the high part does not sign extend the low.
658fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
659fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands                               Mul, DAG.getValueType(SmallVT));
660fbd53f79f5d475d103fba9303a4aa7e88567dd1aDuncan Sands    Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
6615c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  }
6625c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner
6635c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  // Use the calculated overflow everywhere.
6645c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  ReplaceValueWith(SDValue(N, 1), Overflow);
6655c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner  return Mul;
6665c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner}
6675c3d4f0fc90c86a6c4ee9871835d70c9ff3833d5Chris Lattner
668ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
669ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Zero extend the input.
670ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
671ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
672786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
673786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), LHS, RHS);
6748ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling}
6758ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
676475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
67753f6ed9560aa4586ba217fbf94acbfada52f561fEvan Cheng  return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
67853f6ed9560aa4586ba217fbf94acbfada52f561fEvan Cheng                                               N->getValueType(0)));
67969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
68069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
681475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
682475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = N->getOperand(0); // Get the chain.
683475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getOperand(1); // Get the pointer.
684e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
685786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
68669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
68723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT RegVT = TLI.getRegisterType(*DAG.getContext(), VT);
68823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), VT);
689d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // The argument is passed as NumRegs registers of type RegVT.
690d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands
691d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  SmallVector<SDValue, 8> Parts(NumRegs);
692d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  for (unsigned i = 0; i < NumRegs; ++i) {
693cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola    Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2),
694cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola                            N->getConstantOperandVal(3));
695d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    Chain = Parts[i].getValue(1);
696d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  }
69769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
698d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Handle endianness of the load.
699d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  if (TLI.isBigEndian())
700d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    std::reverse(Parts.begin(), Parts.end());
70169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
702d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Assemble the parts in the promoted type.
70323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
704786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]);
705d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  for (unsigned i = 1; i < NumRegs; ++i) {
706786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]);
707d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    // Shift it to the right position and "or" it in.
708786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
709d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands                       DAG.getConstant(i * RegVT.getSizeInBits(),
71092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
711786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
712d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  }
71369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
714d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Modified the chain result - switch anything that used the old chain to
715bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // use the new one.
716d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  ReplaceValueWith(SDValue(N, 1), Chain);
717d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands
718d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  return Res;
71969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
72069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
721bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//===----------------------------------------------------------------------===//
722bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//  Integer Operand Promotion
723bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//===----------------------------------------------------------------------===//
7247fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
725bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// PromoteIntegerOperand - This method is called when the specified operand of
726bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// the specified node is found to need promotion.  At this point, all of the
727bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// result types of the node are known to be legal, but other operands of the
728bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// node may need promotion or expansion as well as the specified one.
729bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sandsbool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
730d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG); dbgs() << "\n");
731475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = SDValue();
7327fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
733f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
734bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    return false;
73569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
736bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  switch (N->getOpcode()) {
737bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    default:
738bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  #ifndef NDEBUG
739d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "PromoteIntegerOperand Op #" << OpNo << ": ";
740d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
741bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  #endif
742c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to promote this operator's operand!");
743bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
744bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::ANY_EXTEND:   Res = PromoteIntOp_ANY_EXTEND(N); break;
745331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  case ISD::ATOMIC_STORE:
746331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman    Res = PromoteIntOp_ATOMIC_STORE(cast<AtomicSDNode>(N));
747331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman    break;
748bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:      Res = PromoteIntOp_BITCAST(N); break;
749bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BR_CC:        Res = PromoteIntOp_BR_CC(N, OpNo); break;
750bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BRCOND:       Res = PromoteIntOp_BRCOND(N, OpNo); break;
751bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BUILD_PAIR:   Res = PromoteIntOp_BUILD_PAIR(N); break;
752bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
753fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::CONCAT_VECTORS: Res = PromoteIntOp_CONCAT_VECTORS(N); break;
754fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  case ISD::EXTRACT_VECTOR_ELT: Res = PromoteIntOp_EXTRACT_VECTOR_ELT(N); break;
755bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::CONVERT_RNDSAT:
756bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                          Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
757bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::INSERT_VECTOR_ELT:
758bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                          Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
759bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::MEMBARRIER:   Res = PromoteIntOp_MEMBARRIER(N); break;
760aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang  case ISD::SCALAR_TO_VECTOR:
761aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang                          Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break;
76228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  case ISD::VSELECT:
763bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SELECT:       Res = PromoteIntOp_SELECT(N, OpNo); break;
764bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SELECT_CC:    Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
765bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SETCC:        Res = PromoteIntOp_SETCC(N, OpNo); break;
766bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SIGN_EXTEND:  Res = PromoteIntOp_SIGN_EXTEND(N); break;
767bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SINT_TO_FP:   Res = PromoteIntOp_SINT_TO_FP(N); break;
768bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::STORE:        Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
769bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                                                   OpNo); break;
770bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::TRUNCATE:     Res = PromoteIntOp_TRUNCATE(N); break;
771927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov  case ISD::FP16_TO_FP32:
772bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::UINT_TO_FP:   Res = PromoteIntOp_UINT_TO_FP(N); break;
773bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::ZERO_EXTEND:  Res = PromoteIntOp_ZERO_EXTEND(N); break;
77455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
77555467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SHL:
77655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRA:
77755467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRL:
77855467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTL:
77955467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
780bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  }
7819fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands
782bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // If the result is null, the sub-method took care of registering results etc.
7839fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  if (!Res.getNode()) return false;
78447d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
78547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // If the result is N, the sub-method updated N in place.  Tell the legalizer
78647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // core about this.
78747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  if (Res.getNode() == N)
788bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    return true;
789bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
790bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
791bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands         "Invalid operand expansion");
792bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
793475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 0), Res);
794bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return false;
79569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
79669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
79769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
79869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// shared among BR_CC, SELECT_CC, and SETCC handlers.
799475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
80069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                            ISD::CondCode CCCode) {
801cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // We have to insert explicit sign or zero extends.  Note that we could
802cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // insert sign extends for ALL conditions, but zero extend is cheaper on
803cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // many machines (an AND instead of two shifts), so prefer it.
80469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (CCCode) {
805c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer comparison!");
80669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETEQ:
80769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETNE:
80869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETUGE:
80969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETUGT:
81069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETULE:
81169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETULT:
81269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // ALL of these operations will work if we either sign or zero extend
81369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // the operands (including the unsigned comparisons!).  Zero extend is
81469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // usually a simpler/cheaper operation, so prefer it.
815c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewLHS = ZExtPromotedInteger(NewLHS);
816c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewRHS = ZExtPromotedInteger(NewRHS);
81711ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    break;
81869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETGE:
81969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETGT:
82069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETLT:
82169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETLE:
822c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewLHS = SExtPromotedInteger(NewLHS);
823c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewRHS = SExtPromotedInteger(NewRHS);
82411ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    break;
82569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
82669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
82769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
828475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
829475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
830786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
831bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
83269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
833331120b1a482b782e8dffce63033bb8514ba2a96Eli FriedmanSDValue DAGTypeLegalizer::PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N) {
834331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
835331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman  return DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), N->getMemoryVT(),
836331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman                       N->getChain(), N->getBasePtr(), Op2, N->getMemOperand(),
837331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman                       N->getOrdering(), N->getSynchScope());
838331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman}
839331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman
840bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::PromoteIntOp_BITCAST(SDNode *N) {
84127759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  // This should only occur in unusual situations like bitcasting to an
84227759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  // x86_fp80, so just turn it into a store+load
84327759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
84427759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman}
84527759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman
846475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
847bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 2 && "Don't know how to promote this operand!");
84869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
849475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(2);
850475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(3);
851bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
85269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
853bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
854bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // legal types.
855027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
856027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(1), LHS, RHS, N->getOperand(4)),
857027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                 0);
858bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
859bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
860475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
861bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 1 && "only know how to promote condition");
862bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
863b6e223a9e806921183da972253c49082a2e07944Duncan Sands  // Promote all the way up to the canonical SetCC type.
864825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT SVT = TLI.getSetCCResultType(MVT::Other);
865b6e223a9e806921183da972253c49082a2e07944Duncan Sands  SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT);
866bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
867bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
868027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Cond,
869027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                        N->getOperand(2)), 0);
870bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
871bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
872475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
873bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Since the result type is legal, the operands must promote to it.
874e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OVT = N->getOperand(0).getValueType();
875c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
876475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Hi = GetPromotedInteger(N->getOperand(1));
877bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
878786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
879bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
880786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
88192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                   DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy()));
882786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
88369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
88469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
885475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
88669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // The vector type is legal but the element type is not.  This implies
88769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // that the vector is a power-of-two in length and that the element
88869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // type does not have a strange size (eg: it is not i1).
889e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VecVT = N->getValueType(0);
89069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  unsigned NumElts = VecVT.getVectorNumElements();
89169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  assert(!(NumElts & 1) && "Legal vector of one illegal element?");
89269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
893b1303d05a89972195de023fda432cc621375a27cBob Wilson  // Promote the inserted value.  The type does not need to match the
894b1303d05a89972195de023fda432cc621375a27cBob Wilson  // vector element type.  Check that any extra bits introduced will be
895b1303d05a89972195de023fda432cc621375a27cBob Wilson  // truncated away.
896b1303d05a89972195de023fda432cc621375a27cBob Wilson  assert(N->getOperand(0).getValueType().getSizeInBits() >=
897b1303d05a89972195de023fda432cc621375a27cBob Wilson         N->getValueType(0).getVectorElementType().getSizeInBits() &&
898b1303d05a89972195de023fda432cc621375a27cBob Wilson         "Type of inserted value narrower than vector element type!");
89969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
900b1303d05a89972195de023fda432cc621375a27cBob Wilson  SmallVector<SDValue, 16> NewOps;
901c885165e664f3b465403e1b6ce57ba63f57c5f0cBob Wilson  for (unsigned i = 0; i < NumElts; ++i)
902b1303d05a89972195de023fda432cc621375a27cBob Wilson    NewOps.push_back(GetPromotedInteger(N->getOperand(i)));
90369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
904027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, &NewOps[0], NumElts), 0);
90569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
90669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
90728088d3c049017a131aa7b07201c6e19c0227cefMon P WangSDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
90828088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
90928088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
91028088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
91128088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           CvtCode == ISD::CVT_FS || CvtCode == ISD::CVT_FU) &&
91228088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           "can only promote integer arguments");
91328088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  SDValue InOp = GetPromotedInteger(N->getOperand(0));
914c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen  return DAG.getConvertRndSat(N->getValueType(0), N->getDebugLoc(), InOp,
91528088d3c049017a131aa7b07201c6e19c0227cefMon P Wang                              N->getOperand(1), N->getOperand(2),
91628088d3c049017a131aa7b07201c6e19c0227cefMon P Wang                              N->getOperand(3), N->getOperand(4), CvtCode);
91728088d3c049017a131aa7b07201c6e19c0227cefMon P Wang}
91828088d3c049017a131aa7b07201c6e19c0227cefMon P Wang
919475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
920475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                         unsigned OpNo) {
92169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  if (OpNo == 1) {
92269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Promote the inserted value.  This is valid because the type does not
92369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // have to match the vector element type.
92469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
92569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Check that any extra bits introduced will be truncated away.
92669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    assert(N->getOperand(1).getValueType().getSizeInBits() >=
92769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands           N->getValueType(0).getVectorElementType().getSizeInBits() &&
92869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands           "Type of inserted value narrower than vector element type!");
929027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman    return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
93069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                  GetPromotedInteger(N->getOperand(1)),
931027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                  N->getOperand(2)),
932027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                   0);
93369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
93469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
93569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  assert(OpNo == 2 && "Different operand and result vector types?");
93669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
93769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Promote the index.
938c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Idx = ZExtPromotedInteger(N->getOperand(2));
939027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
940027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(1), Idx), 0);
94169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
94269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
943475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
944475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewOps[6];
9454be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  DebugLoc dl = N->getDebugLoc();
94669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  NewOps[0] = N->getOperand(0);
94769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
948475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Flag = GetPromotedInteger(N->getOperand(i));
949825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    NewOps[i] = DAG.getZeroExtendInReg(Flag, dl, MVT::i1);
95069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
951027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, NewOps, array_lengthof(NewOps)), 0);
95269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
95369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
954aa9df0b0c3cef33514095bde2eedead986677955Mon P WangSDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) {
955b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  // Integer SCALAR_TO_VECTOR operands are implicitly truncated, so just promote
956b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  // the operand in place.
957027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N,
958027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                GetPromotedInteger(N->getOperand(0))), 0);
959aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang}
960aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang
961475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
96228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  assert(OpNo == 0 && "Only know how to promote the condition!");
96328b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  SDValue Cond = N->getOperand(0);
96428b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  EVT OpTy = N->getOperand(1).getValueType();
9657e4982287591945c4e42ba8470a978e629789c76Duncan Sands
966b6e223a9e806921183da972253c49082a2e07944Duncan Sands  // Promote all the way up to the canonical SetCC type.
96728b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  EVT SVT = TLI.getSetCCResultType(N->getOpcode() == ISD::SELECT ?
96828b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands                                   OpTy.getScalarType() : OpTy);
96928b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  Cond = PromoteTargetBoolean(Cond, SVT);
970bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
97128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1),
97228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands                                        N->getOperand(2)), 0);
973bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
974bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
975475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) {
976bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Don't know how to promote this operand!");
977bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
978475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(0);
979475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(1);
980bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get());
981bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
982bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The CC (#4) and the possible return values (#2 and #3) have legal types.
983027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2),
984027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(3), N->getOperand(4)), 0);
985bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
986bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
987475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
988bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Don't know how to promote this operand!");
989bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
990475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(0);
991475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(1);
992bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
993bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
994bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The CC (#2) is always legal.
995027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0);
996bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
997bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
99855467af31620c9d027e071ebcd9746b7593cff17Sanjiv GuptaSDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
999027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1000027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                ZExtPromotedInteger(N->getOperand(1))), 0);
100155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta}
100255467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
1003475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
1004475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
1005786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1006786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
1007786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(),
1008bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     Op, DAG.getValueType(N->getOperand(0).getValueType()));
1009bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
1010bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
1011c08468774b65dc288c44076d428f4beddabe58e2Duncan SandsSDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
1012027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N,
1013027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                SExtPromotedInteger(N->getOperand(0))), 0);
1014c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands}
1015c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands
1016475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
1017bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
1018475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
1019bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  unsigned Alignment = N->getAlignment();
1020bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  bool isVolatile = N->isVolatile();
10211e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = N->isNonTemporal();
1022786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1023bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
1024475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Val = GetPromotedInteger(N->getValue());  // Get promoted value.
1025bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
1026bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Truncate the value and store the result.
1027ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getPointerInfo(),
1028ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                           N->getMemoryVT(),
10291e559443a17d1b335f697551c6263ba60d5dd827David Greene                           isVolatile, isNonTemporal, Alignment);
1030bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
1031bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
1032475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
1033475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
1034786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op);
1035bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
1036bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
1037c08468774b65dc288c44076d428f4beddabe58e2Duncan SandsSDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
1038027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N,
1039027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                ZExtPromotedInteger(N->getOperand(0))), 0);
1040c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands}
1041c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands
1042475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
10434be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1044475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
10454be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
10468e614322498f9b38995a6bf41100ca617180eacbNadav Rotem  return DAG.getZeroExtendInReg(Op, dl,
10478e614322498f9b38995a6bf41100ca617180eacbNadav Rotem                                N->getOperand(0).getValueType().getScalarType());
1048bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
1049bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
105069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
105169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----------------------------------------------------------------------===//
105269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Result Expansion
105369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----------------------------------------------------------------------===//
105469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
105569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// ExpandIntegerResult - This method is called when the specified result of the
1056cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// specified node is found to need expansion.  At this point, the node may also
1057cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// have invalid operands or may have other results that need promotion, we just
1058cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// know that (at least) one result needs expansion.
105969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
1060d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Expand integer result: "; N->dump(&DAG); dbgs() << "\n");
1061475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
1062475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  Lo = Hi = SDValue();
1063cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1064cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // See if the target wants to custom expand this node.
1065f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getValueType(ResNo), true))
10661607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands    return;
1067cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1068cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  switch (N->getOpcode()) {
1069cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  default:
1070cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#ifndef NDEBUG
1071d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "ExpandIntegerResult #" << ResNo << ": ";
1072d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
1073cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#endif
1074c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to expand the result of this operator!");
107569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
107678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
107778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
107878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
107978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
108078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
1081bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:            ExpandRes_BITCAST(N, Lo, Hi); break;
108278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
10834a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
108478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
108521c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;
108678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
108769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ANY_EXTEND:  ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
108895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  case ISD::AssertSext:  ExpandIntRes_AssertSext(N, Lo, Hi); break;
108969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::AssertZext:  ExpandIntRes_AssertZext(N, Lo, Hi); break;
109005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::BSWAP:       ExpandIntRes_BSWAP(N, Lo, Hi); break;
109105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::Constant:    ExpandIntRes_Constant(N, Lo, Hi); break;
109205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTLZ:        ExpandIntRes_CTLZ(N, Lo, Hi); break;
109305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTPOP:       ExpandIntRes_CTPOP(N, Lo, Hi); break;
109405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTTZ:        ExpandIntRes_CTTZ(N, Lo, Hi); break;
109569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_SINT:  ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
109669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_UINT:  ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
109769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::LOAD:        ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
109805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::MUL:         ExpandIntRes_MUL(N, Lo, Hi); break;
109905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SDIV:        ExpandIntRes_SDIV(N, Lo, Hi); break;
110005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
110105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
110205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SREM:        ExpandIntRes_SREM(N, Lo, Hi); break;
110305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::TRUNCATE:    ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
110405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::UDIV:        ExpandIntRes_UDIV(N, Lo, Hi); break;
110505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::UREM:        ExpandIntRes_UREM(N, Lo, Hi); break;
110605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
1107ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  case ISD::ATOMIC_LOAD: ExpandIntRes_ATOMIC_LOAD(N, Lo, Hi); break;
110869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
11098d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_ADD:
11108d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_SUB:
11118d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_AND:
11128d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_OR:
11138d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_XOR:
11148d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_NAND:
11158d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_MIN:
11168d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_MAX:
11178d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_UMIN:
11188d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_LOAD_UMAX:
11198d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  case ISD::ATOMIC_SWAP: {
11208d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N);
11218d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    SplitInteger(Tmp.first, Lo, Hi);
11228d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    ReplaceValueWith(SDValue(N, 1), Tmp.second);
11238d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher    break;
11248d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher  }
11258d93d19076fb6a67eeb63cb0ba79d00c3aa8478aEric Christopher
1126cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::AND:
1127cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::OR:
112805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
112905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1130cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADD:
113105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
113205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1133cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADDC:
113405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
113505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1136cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADDE:
113705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
113805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1139cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SHL:
1140cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SRA:
114105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
1142268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1143268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::SADDO:
1144268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break;
1145268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::UADDO:
1146268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break;
1147362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  case ISD::UMULO:
1148362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  case ISD::SMULO: ExpandIntRes_XMULO(N, Lo, Hi); break;
1149cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1150d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
1151cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If Lo/Hi is null, the sub-method took care of registering results etc.
1152ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (Lo.getNode())
1153475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SetExpandedInteger(SDValue(N, ResNo), Lo, Hi);
1154cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1155cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
115693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher/// Lower an atomic node to the appropriate builtin call.
115793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopherstd::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
115893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  unsigned Opc = Node->getOpcode();
115993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
116093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  RTLIB::Libcall LC;
116193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher
116293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  switch (Opc) {
116393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  default:
116493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    llvm_unreachable("Unhandled atomic intrinsic Expand!");
116593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
116693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_SWAP:
116793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
116893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
116993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break;
117093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break;
117193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break;
117293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break;
117393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
117493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
117593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_CMP_SWAP:
117693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
117793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
117893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break;
117993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break;
118093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break;
118193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break;
118293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
118393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
118493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_ADD:
118593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
118693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
118793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_ADD_1; break;
118893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break;
118993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break;
119093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break;
119193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
119293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
119393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_SUB:
119493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
119593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
119693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_SUB_1; break;
119793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break;
119893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break;
119993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break;
120093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
120193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
120293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_AND:
120393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
120493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
120593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_AND_1; break;
120693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break;
120793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break;
120893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break;
120993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
121093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
121193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_OR:
121293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
121393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
121493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_OR_1; break;
121593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break;
121693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break;
121793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break;
121893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
121993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
122093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_XOR:
122193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
122293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
122393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_XOR_1; break;
122493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break;
122593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break;
122693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break;
122793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
122893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
122993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  case ISD::ATOMIC_LOAD_NAND:
123093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    switch (VT.SimpleTy) {
123193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    default: llvm_unreachable("Unexpected value type for atomic!");
123293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i8:  LC = RTLIB::SYNC_FETCH_AND_NAND_1; break;
123393c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break;
123493c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break;
123593c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break;
123693c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    }
123793c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher    break;
123893c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  }
123993c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher
124093c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher  return ExpandChainLibCall(LC, Node, false);
124193c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher}
124293c70426f581859f197df1b05fdb1b3664d361a0Eric Christopher
124305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
124405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// and the shift amount is a constant 'Amt'.  Expand the operation.
124505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
1246475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
1247e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner  DebugLoc DL = N->getDebugLoc();
124805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the incoming operand to be shifted, so that we have its parts
1249475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
125005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
1251cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1252e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = InL.getValueType();
125305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned VTBits = N->getValueType(0).getSizeInBits();
125405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
1255e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShTy = N->getOperand(1).getValueType();
1256cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
125705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::SHL) {
125805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (Amt > VTBits) {
125905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = Hi = DAG.getConstant(0, NVT);
126005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt > NVTBits) {
126105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
1262e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::SHL, DL,
1263915eeb488786379250808d47668c43e010efe566Chris Lattner                       NVT, InL, DAG.getConstant(Amt-NVTBits, ShTy));
126405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt == NVTBits) {
126505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
126605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = InL;
1267104de6cf7b80ec5e9beb502a069f376810a0a1e3Richard Osborne    } else if (Amt == 1 &&
1268f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman               TLI.isOperationLegalOrCustom(ISD::ADDC,
126954e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                              TLI.getTypeToExpandTo(*DAG.getContext(), NVT))) {
127005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      // Emit this X << 1 as X+X.
1271f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner      SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
1272475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue LoOps[2] = { InL, InL };
1273e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::ADDC, DL, VTList, LoOps, 2);
1274475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
1275e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::ADDE, DL, VTList, HiOps, 3);
127605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else {
1277e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::SHL, DL, NVT, InL, DAG.getConstant(Amt, ShTy));
1278e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::OR, DL, NVT,
1279e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SHL, DL, NVT, InH,
128005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(Amt, ShTy)),
1281e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SRL, DL, NVT, InL,
128205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(NVTBits-Amt, ShTy)));
128305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
128405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return;
1285cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1286cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
128705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::SRL) {
128805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (Amt > VTBits) {
128905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
129005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
129105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt > NVTBits) {
1292e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::SRL, DL,
1293786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
129405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
129505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt == NVTBits) {
129605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = InH;
129705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
129805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else {
1299e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Lo = DAG.getNode(ISD::OR, DL, NVT,
1300e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SRL, DL, NVT, InL,
130105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(Amt, ShTy)),
1302e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                       DAG.getNode(ISD::SHL, DL, NVT, InH,
130305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(NVTBits-Amt, ShTy)));
1304e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner      Hi = DAG.getNode(ISD::SRL, DL, NVT, InH, DAG.getConstant(Amt, ShTy));
130505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
130605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return;
1307cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1308d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands
130905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
131005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Amt > VTBits) {
1311e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
131205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                          DAG.getConstant(NVTBits-1, ShTy));
131305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else if (Amt > NVTBits) {
1314e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Lo = DAG.getNode(ISD::SRA, DL, NVT, InH,
131505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(Amt-NVTBits, ShTy));
1316e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
131705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(NVTBits-1, ShTy));
131805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else if (Amt == NVTBits) {
131905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Lo = InH;
1320e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = DAG.getNode(ISD::SRA, DL, NVT, InH,
132105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(NVTBits-1, ShTy));
1322d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands  } else {
1323e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Lo = DAG.getNode(ISD::OR, DL, NVT,
1324e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                     DAG.getNode(ISD::SRL, DL, NVT, InL,
132505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(Amt, ShTy)),
1326e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner                     DAG.getNode(ISD::SHL, DL, NVT, InH,
132705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(NVTBits-Amt, ShTy)));
1328e075118489baf15a7cea2e7f155b4799b93d6d02Chris Lattner    Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, DAG.getConstant(Amt, ShTy));
1329d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands  }
1330d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands}
1331d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands
133205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
133305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// this shift based on knowledge of the high bit of the shift amount.  If we
133405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
133505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// shift amount.
133605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsbool DAGTypeLegalizer::
1337475871a144eb604ddaf37503397ba0941442e5fbDan GohmanExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
1338475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Amt = N->getOperand(1);
133923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1340e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShTy = Amt.getValueType();
13415b870aff81da0c07413f0241087bb3722954b83dDan Gohman  unsigned ShBits = ShTy.getScalarType().getSizeInBits();
13425b870aff81da0c07413f0241087bb3722954b83dDan Gohman  unsigned NVTBits = NVT.getScalarType().getSizeInBits();
134305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(isPowerOf2_32(NVTBits) &&
134405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Expanded integer type size not a power of two!");
1345786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1346cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
134705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
134805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  APInt KnownZero, KnownOne;
134905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
1350cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
135105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we don't know anything about the high bits, exit.
135205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (((KnownZero|KnownOne) & HighBitMask) == 0)
135305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return false;
1354cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
135505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Get the incoming operand to be shifted.
1356475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
135705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
1358be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands
135905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we know that any of the high bits of the shift amount are one, then we
136005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // can do this as a couple of simple shifts.
136105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (KnownOne.intersects(HighBitMask)) {
136205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Mask out the high bit, which we know is set.
1363786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
136405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                      DAG.getConstant(~HighBitMask, ShTy));
136505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
136605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    switch (N->getOpcode()) {
1367c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown shift");
136805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SHL:
136905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);              // Low part is zero.
1370786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
137105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
137205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRL:
137305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);              // Hi part is zero.
1374786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
137505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
137605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRA:
1377786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,       // Sign extend high part.
137805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                       DAG.getConstant(NVTBits-1, ShTy));
1379786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
138005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
138105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
138205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
138305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
138428dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman#if 0
138528dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman  // FIXME: This code is broken for shifts with a zero amount!
138605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we know that all of the high bits of the shift amount are zero, then we
138705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // can do this as a couple of simple shifts.
138805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if ((KnownZero & HighBitMask) == HighBitMask) {
138905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Compute 32-amt.
1390475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Amt2 = DAG.getNode(ISD::SUB, ShTy,
139105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(NVTBits, ShTy),
139205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 Amt);
139305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned Op1, Op2;
139405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    switch (N->getOpcode()) {
1395c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown shift");
139605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SHL:  Op1 = ISD::SHL; Op2 = ISD::SRL; break;
139705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRL:
139805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRA:  Op1 = ISD::SRL; Op2 = ISD::SHL; break;
139905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
140005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
140105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
140205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getNode(ISD::OR, NVT,
140305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getNode(Op1, NVT, InH, Amt),
140405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getNode(Op2, NVT, InL, Amt2));
140505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return true;
140605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
140728dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman#endif
140805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
140905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  return false;
141005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
141105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
14126fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift
14136fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng/// of any size.
14146fb2168aaed06e4685d064b6f63dc4c668b42728Evan Chengbool DAGTypeLegalizer::
14156fb2168aaed06e4685d064b6f63dc4c668b42728Evan ChengExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
14166fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue Amt = N->getOperand(1);
141723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1418e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShTy = Amt.getValueType();
14196fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  unsigned NVTBits = NVT.getSizeInBits();
14206fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  assert(isPowerOf2_32(NVTBits) &&
14216fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng         "Expanded integer type size not a power of two!");
14226fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  DebugLoc dl = N->getDebugLoc();
14236fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14246fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  // Get the incoming operand to be shifted.
14256fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue InL, InH;
14266fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  GetExpandedInteger(N->getOperand(0), InL, InH);
14276fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14286fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
14299993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode);
14309993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
14319993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue isShort = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy),
14329993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                                 Amt, NVBitsNode, ISD::SETULT);
14336fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14349993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands  SDValue LoS, HiS, LoL, HiL;
14356fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  switch (N->getOpcode()) {
1436c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown shift");
14376fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SHL:
14389993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Short: ShAmt < NVTBits
14399993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
14409993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiS = DAG.getNode(ISD::OR, dl, NVT,
14416fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
144236236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // FIXME: If Amt is zero, the following shift generates an undefined result
144336236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // on some architectures.
14449993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack));
14459993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
14469993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Long: ShAmt >= NVTBits
14479993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoL = DAG.getConstant(0, NVT);                        // Lo part is zero.
14489993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part.
14496fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14509993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
14519993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
14526fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
14536fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SRL:
14549993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Short: ShAmt < NVTBits
14559993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
14569993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoS = DAG.getNode(ISD::OR, dl, NVT,
14579993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
145836236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // FIXME: If Amt is zero, the following shift generates an undefined result
145936236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // on some architectures.
14609993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
14619993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
14629993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Long: ShAmt >= NVTBits
14639993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiL = DAG.getConstant(0, NVT);                        // Hi part is zero.
14649993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part.
14659993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
14669993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
14679993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
14686fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
14696fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SRA:
14709993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Short: ShAmt < NVTBits
14719993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
14729993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoS = DAG.getNode(ISD::OR, dl, NVT,
14736fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
147436236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // FIXME: If Amt is zero, the following shift generates an undefined result
147536236b76a45be2a50315d1926c49bd3c63786b49Duncan Sands    // on some architectures.
14769993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack));
14779993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands
14789993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    // Long: ShAmt >= NVTBits
14799993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    HiL = DAG.getNode(ISD::SRA, dl, NVT, InH,             // Sign of Hi part.
14809993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands                      DAG.getConstant(NVTBits-1, ShTy));
14819993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part.
14826fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14839993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL);
14849993b88f06fd54c0be31d35f0970ada70a4c0439Duncan Sands    Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL);
14856fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
14866fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  }
14876fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
14886fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  return false;
14896fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng}
14906fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
149105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
1492475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                           SDValue &Lo, SDValue &Hi) {
1493786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
149405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1495475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
149605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
149705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
149829a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands
1499e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = LHSL.getValueType();
1500475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[2] = { LHSL, RHSL };
1501475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
150205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
150329a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support
150429a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // them.  TODO: Teach operation legalization how to expand unsupported
150529a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // ADDC/ADDE/SUBC/SUBE.  The problem is that these operations generate
1506f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  // a carry of type MVT::Glue, but there doesn't seem to be any way to
150729a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // generate a value of this type in the expanded code sequence.
150829a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  bool hasCarry =
1509f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman    TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
1510f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman                                   ISD::ADDC : ISD::SUBC,
1511bc7a902713c4e3f13a93c383e647d2a18712f447Dan Gohman                                 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
151229a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands
151329a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  if (hasCarry) {
1514f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTList = DAG.getVTList(NVT, MVT::Glue);
151529a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    if (N->getOpcode() == ISD::ADD) {
1516786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
151729a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands      HiOps[2] = Lo.getValue(1);
1518786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
151929a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    } else {
1520786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
152129a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands      HiOps[2] = Lo.getValue(1);
1522786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
152329a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    }
1524c6d160bfa22fcb06c80c4c6cfc10ddbe7d8d28e4Owen Anderson    return;
15255078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner  }
1526c6d160bfa22fcb06c80c4c6cfc10ddbe7d8d28e4Owen Anderson
15275078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner  if (N->getOpcode() == ISD::ADD) {
15285078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2);
15295078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2);
15305078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0],
15315078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                ISD::SETULT);
15325078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1,
15335078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(1, NVT),
15345078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(0, NVT));
15355078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1],
15365078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                ISD::SETULT);
15375078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2,
15385078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(1, NVT), Carry1);
15395078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2);
154005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
15415078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2);
15425078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2);
15435078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Cmp =
15445078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner      DAG.getSetCC(dl, TLI.getSetCCResultType(LoOps[0].getValueType()),
15455078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                   LoOps[0], LoOps[1], ISD::SETULT);
15465078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp,
15475078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(1, NVT),
15485078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner                                 DAG.getConstant(0, NVT));
15495078293cc28dd03236384fa0a3b6c8347e0701fbChris Lattner    Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
155005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
155105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
155205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
155305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
1554475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
155505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1556475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
1557786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
155805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
155905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1560f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
1561475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[2] = { LHSL, RHSL };
1562475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
156305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
156405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::ADDC) {
1565786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
156605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    HiOps[2] = Lo.getValue(1);
1567786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
156805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
1569786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
157005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    HiOps[2] = Lo.getValue(1);
1571786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
157205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
157305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1574874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // Legalized the flag result - switch anything that used the old flag to
1575874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // use the new one.
1576475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
157705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
157805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
157905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
1580475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
158105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1582475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
1583786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
158405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
158505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1586f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue);
1587475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
1588475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
158905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1590786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3);
159105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  HiOps[2] = Lo.getValue(1);
1592786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
159305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1594874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // Legalized the flag result - switch anything that used the old flag to
1595874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // use the new one.
1596475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
159705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
1598fcd75e5efb482f35cfc22fd4b64e047930130fd6Eli Friedman
159962bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedmanvoid DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N,
1600fcd75e5efb482f35cfc22fd4b64e047930130fd6Eli Friedman                                                 SDValue &Lo, SDValue &Hi) {
160162bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  SDValue Res = DecomposeMERGE_VALUES(N);
160262bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  SplitInteger(Res, Lo, Hi);
160362bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman}
160405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
160505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
1606475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
160723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1608786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1609475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
161005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
161105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The low part is any extension of the input (which degenerates to a copy).
1612786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
1613e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen    Hi = DAG.getUNDEF(NVT);   // The high part is undefined.
161405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
161505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
161605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
161796e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    assert(getTypeAction(Op.getValueType()) ==
161896e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem           TargetLowering::TypePromoteInteger &&
161905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
1620475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
162105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
162205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
162305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
162405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
162505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
162605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
162705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
162895db39a9de48f69f4d764335b492b83a698c7854Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
1629475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
1630786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
163195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1632e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
1633e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
163495db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  unsigned NVTBits = NVT.getSizeInBits();
163595db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  unsigned EVTBits = EVT.getSizeInBits();
163695db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
163795db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  if (NVTBits < EVTBits) {
1638786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
16394ff28527bb8e5ed4ae4b65f0fa6967eb79a05d4cEvan Cheng                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
16404ff28527bb8e5ed4ae4b65f0fa6967eb79a05d4cEvan Cheng                                                        EVTBits - NVTBits)));
164195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  } else {
1642786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
164395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands    // The high part replicates the sign bit of Lo, make it explicit.
1644786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
164592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(NVTBits-1, TLI.getPointerTy()));
164695db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  }
164795db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
164895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
164905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
1650475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
1651786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
165205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1653e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
1654e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
165505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
165605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned EVTBits = EVT.getSizeInBits();
165705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
165805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (NVTBits < EVTBits) {
1659786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
1660285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
1661285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                                                        EVTBits - NVTBits)));
166205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
1663786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
166405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part must be zero, make it explicit.
166505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getConstant(0, NVT);
166605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
166705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
166805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
166905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
1670475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1671786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
167205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Hi, Lo);  // Note swapped operands.
1673786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
1674786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
167505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
167605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
167705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
1678475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
167923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
168005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NBitWidth = NVT.getSizeInBits();
168105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue();
168240f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad  Lo = DAG.getConstant(Cst.trunc(NBitWidth), NVT);
168305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
168405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
168505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
168605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
1687475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1688786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
168905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
169005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1691e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
169205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1693786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi,
1694ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   DAG.getConstant(0, NVT), ISD::SETNE);
169505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1696786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo);
1697786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi);
169805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1699786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ,
1700786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
170105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
170205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
170305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
170405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
170505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
1706475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1707786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
170805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
170905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1710e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
1711b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo),
1712786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
171305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
171405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
171505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
171605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
1717475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1718786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
171905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
172005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
1721e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT NVT = Lo.getValueType();
172205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1723786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo,
1724ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   DAG.getConstant(0, NVT), ISD::SETNE);
172505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1726786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo);
1727786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi);
172805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1729786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ,
1730786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
173105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
173205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
173305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
173405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1735475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo,
1736475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Hi) {
1737c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1738e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
1739475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
1740b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT);
1741be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!");
1742c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi);
1743ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1744ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
1745475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo,
1746475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Hi) {
1747c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1748e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
1749475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
1750b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT);
1751be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!");
1752c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi);
1753ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1754ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
175569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
1756475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1757ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  if (ISD::isNormalLoad(N)) {
1758ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands    ExpandRes_NormalLoad(N, Lo, Hi);
175978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    return;
176078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
176178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
176278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
176378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
1764e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
176523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1766475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch  = N->getChain();
1767475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getBasePtr();
1768cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  ISD::LoadExtType ExtType = N->getExtensionType();
1769cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned Alignment = N->getAlignment();
1770cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  bool isVolatile = N->isVolatile();
17711e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = N->isNonTemporal();
1772786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1773cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
177478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
1775cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
177678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getMemoryVT().bitsLE(NVT)) {
17778a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman    EVT MemVT = N->getMemoryVT();
1778cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1779a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
17801e559443a17d1b335f697551c6263ba60d5dd827David Greene                        MemVT, isVolatile, isNonTemporal, Alignment);
1781cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1782cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Remember the chain.
1783cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    Ch = Lo.getValue(1);
1784cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1785cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    if (ExtType == ISD::SEXTLOAD) {
1786cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is obtained by SRA'ing all but one of the bits of the
1787cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // lo part.
178883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      unsigned LoSize = Lo.getValueType().getSizeInBits();
1789786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
179092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                       DAG.getConstant(LoSize-1, TLI.getPointerTy()));
1791cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    } else if (ExtType == ISD::ZEXTLOAD) {
1792cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is just a zero.
1793cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Hi = DAG.getConstant(0, NVT);
1794cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    } else {
1795cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
1796cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is undefined.
1797e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen      Hi = DAG.getUNDEF(NVT);
1798cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1799cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else if (TLI.isLittleEndian()) {
1800cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Little-endian - low bits are at low addresses.
1801ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getPointerInfo(),
18021e559443a17d1b335f697551c6263ba60d5dd827David Greene                     isVolatile, isNonTemporal, Alignment);
1803cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1804cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits =
180583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
180623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
1807cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1808cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
180983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
1810786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
18110bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
1812a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr,
1813ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                        N->getPointerInfo().getWithOffset(IncrementSize), NEVT,
18141e559443a17d1b335f697551c6263ba60d5dd827David Greene                        isVolatile, isNonTemporal,
18151e559443a17d1b335f697551c6263ba60d5dd827David Greene                        MinAlign(Alignment, IncrementSize));
1816cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1817cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Build a factor node to remember that this load is independent of the
1818cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // other one.
1819825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1820cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     Hi.getValue(1));
1821cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else {
1822cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Big-endian - high bits are at low addresses.  Favor aligned loads at
1823cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // the cost of some bit-fiddling.
18248a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman    EVT MemVT = N->getMemoryVT();
18254e918b2c8ca81edd63f6708e08835b2c14648615Dan Gohman    unsigned EBytes = MemVT.getStoreSize();
182683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
1827cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits = (EBytes - IncrementSize)*8;
1828cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1829cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Load both the high bits and maybe some of the low bits.
1830a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(),
18318a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman                        EVT::getIntegerVT(*DAG.getContext(),
18328a55ce4a392f07ac1f3c183100ac591b7ad7c693Dan Gohman                                          MemVT.getSizeInBits() - ExcessBits),
18331e559443a17d1b335f697551c6263ba60d5dd827David Greene                        isVolatile, isNonTemporal, Alignment);
1834cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1835cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
1836786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
18370bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
1838cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Load the rest of the low bits.
1839a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr,
1840ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                        N->getPointerInfo().getWithOffset(IncrementSize),
184123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                        EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
18421e559443a17d1b335f697551c6263ba60d5dd827David Greene                        isVolatile, isNonTemporal,
18431e559443a17d1b335f697551c6263ba60d5dd827David Greene                        MinAlign(Alignment, IncrementSize));
1844cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1845cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Build a factor node to remember that this load is independent of the
1846cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // other one.
1847825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1848cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     Hi.getValue(1));
1849cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
185083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    if (ExcessBits < NVT.getSizeInBits()) {
1851cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Transfer low bits from the bottom of Hi to the top of Lo.
1852786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::OR, dl, NVT, Lo,
1853786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SHL, dl, NVT, Hi,
1854cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                   DAG.getConstant(ExcessBits,
185592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                                   TLI.getPointerTy())));
1856cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Move high bits to the right position in Hi.
18577fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands      Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl,
1858786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, Hi,
185983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
186092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
1861cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1862cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1863cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1864cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Legalized the chain result - switch anything that used the old chain to
1865cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // use the new one.
1866475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Ch);
1867cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1868cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
186969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
1870475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
1871786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1872475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LL, LH, RL, RH;
187369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(0), LL, LH);
187469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(1), RL, RH);
1875786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL);
1876786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH);
1877cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1878cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
187905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
1880475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                        SDValue &Lo, SDValue &Hi) {
1881e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
188223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1883c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
188469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1885f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT);
1886f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT);
1887f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT);
1888f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT);
1889cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
1890475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue LL, LH, RL, RH;
189169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(0), LL, LH);
189269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(1), RL, RH);
189383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned OuterBitSize = VT.getSizeInBits();
1894e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    unsigned InnerBitSize = NVT.getSizeInBits();
1895cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
1896cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
189769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1898e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
1899e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
1900e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands        DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
1901cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The inputs are both zero-extended.
1902cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasUMUL_LOHI) {
1903cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a umul_lohi.
1904786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
1905ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        Hi = SDValue(Lo.getNode(), 1);
1906cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1907cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1908cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasMULHU) {
1909cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a mulhu+mul.
1910786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1911786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
1912cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1913cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1914cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1915e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
1916cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The input values are both sign-extended.
1917cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasSMUL_LOHI) {
1918cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a smul_lohi.
1919786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
1920ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        Hi = SDValue(Lo.getNode(), 1);
1921cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1922cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1923cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasMULHS) {
1924cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a mulhs+mul.
1925786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1926786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL);
1927cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1928cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1929cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1930cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    if (HasUMUL_LOHI) {
1931cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Lo,Hi = umul LHS, RHS.
1932786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl,
1933cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                       DAG.getVTList(NVT, NVT), LL, RL);
1934cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Lo = UMulLOHI;
1935cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Hi = UMulLOHI.getValue(1);
1936786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
1937786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
1938786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
1939786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
1940cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      return;
1941cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1942e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (HasMULHU) {
1943786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1944786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
1945786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
1946786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
1947786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
1948786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
1949e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands      return;
1950e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    }
1951cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
195241edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
1953cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If nothing else, we can make a libcall.
19545ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1955825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
195615c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    LC = RTLIB::MUL_I16;
1957825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
19585ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::MUL_I32;
1959825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
1960e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    LC = RTLIB::MUL_I64;
1961825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
19625ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::MUL_I128;
19635ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!");
1964e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands
1965475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1966c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi);
196741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands}
1968cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1969268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedmanvoid DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node,
1970268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                             SDValue &Lo, SDValue &Hi) {
1971268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue LHS = Node->getOperand(0);
1972268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue RHS = Node->getOperand(1);
1973268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  DebugLoc dl = Node->getDebugLoc();
1974268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1975268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Expand the result by simply replacing it with the equivalent
1976268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // non-overflow-checking operation.
1977268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
1978268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
1979268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            LHS, RHS);
1980268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SplitInteger(Sum, Lo, Hi);
1981268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1982268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Compute the overflow.
1983268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //
1984268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   LHSSign -> LHS >= 0
1985268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   RHSSign -> RHS >= 0
1986268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   SumSign -> Sum >= 0
1987268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //
1988268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Add:
1989268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
1990268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Sub:
1991268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //   Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
1992268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  //
1993268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  EVT OType = Node->getValueType(1);
1994268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Zero = DAG.getConstant(0, LHS.getValueType());
1995268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
1996268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
1997268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
1998268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
1999268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                    Node->getOpcode() == ISD::SADDO ?
2000268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                    ISD::SETEQ : ISD::SETNE);
2001268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2002268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
2003268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
2004268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2005268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
2006268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2007268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Use the calculated overflow everywhere.
2008268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  ReplaceValueWith(SDValue(Node, 1), Cmp);
2009268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman}
2010268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
201169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
2012475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2013e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2014c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
20155ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands
20165ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2017825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2018a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::SDIV_I16;
2019825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
20205ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I32;
2021825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
20225ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I64;
2023825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
20245ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I128;
20255ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
20265ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands
2027475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2028c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
2029ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
2030ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
203169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
2032475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
2033e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2034c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
203569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
203669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // If we can emit an efficient shift operation, do so now.  Check to see if
2037cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // the RHS is a constant.
2038cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
2039f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi);
2040cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2041cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If we can determine that the high bit of the shift is zero or one, even if
2042cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // the low bits are variable, emit this shift in an optimized form.
2043cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
2044cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
204569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2046cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If this target supports shift_PARTS, use it.  First, map to the _PARTS opc.
2047cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned PartsOpc;
204841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  if (N->getOpcode() == ISD::SHL) {
2049cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SHL_PARTS;
205041edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else if (N->getOpcode() == ISD::SRL) {
2051cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SRL_PARTS;
205241edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else {
2053cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
2054cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SRA_PARTS;
2055cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
205669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2057cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Next check to see if the target supports this SHL_PARTS operation or if it
2058cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // will custom expand it.
205923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2060cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
2061cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
2062cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Action == TargetLowering::Custom) {
2063cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Expand the subcomponents.
2064475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue LHSL, LHSH;
206569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
206669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2067475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) };
2068e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = LHSL.getValueType();
2069fc1665793e62eb4f26d24b8a19eecf59cd872e2aDan Gohman    Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops, 3);
2070cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    Hi = Lo.getValue(1);
2071cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2072cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
207341edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
2074cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Otherwise, emit a libcall.
2075dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
207641edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  bool isSigned;
207741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  if (N->getOpcode() == ISD::SHL) {
207841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = false; /*sign irrelevant*/
2079825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (VT == MVT::i16)
208015c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SHL_I16;
2081825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i32)
2082dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I32;
2083825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i64)
2084dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I64;
2085825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i128)
2086dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I128;
208741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else if (N->getOpcode() == ISD::SRL) {
208841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = false;
2089825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (VT == MVT::i16)
209015c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SRL_I16;
2091825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i32)
2092dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I32;
2093825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i64)
2094dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I64;
2095825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i128)
2096dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I128;
209741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else {
209841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
209941edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = true;
2100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (VT == MVT::i16)
210115c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SRA_I16;
2102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i32)
2103dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I32;
2104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i64)
2105dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I64;
2106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (VT == MVT::i128)
2107dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I128;
210841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  }
21098c899ee031481dbece5f111379a274c848cb5902Duncan Sands
21106fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
21116fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
21126fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi);
21136fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return;
21146fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  }
211541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
21166fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
2117c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported shift!");
211841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands}
2119cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
212005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
2121475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                SDValue &Lo, SDValue &Hi) {
212223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2123786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2124475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
212505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
2126b3bc6352defdf1a5c6b1b0770d0c4d603f6524a8Duncan Sands    // The low part is sign extension of the input (degenerates to a copy).
2127786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
212805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part is obtained by SRA'ing all but one of the bits of low part.
212905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned LoSize = NVT.getSizeInBits();
2130786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
213192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(LoSize-1, TLI.getPointerTy()));
213205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
213305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
213405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
213596e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    assert(getTypeAction(Op.getValueType()) ==
213696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem           TargetLowering::TypePromoteInteger &&
213705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
2138475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
213905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
214005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
214105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
214205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
214305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
214405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
2145786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
2146285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
2147285fb1cc4a7ea924b4d94e9c2cb890125d56a7e0Evan Cheng                                                        ExcessBits)));
214805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
214905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
215005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
215105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::
2152475871a144eb604ddaf37503397ba0941442e5fbDan GohmanExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
2153786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
215469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
2155e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
2156d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
215705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (EVT.bitsLE(Lo.getValueType())) {
215805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // sext_inreg the low part if needed.
2159786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
216005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     N->getOperand(1));
2161d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
216205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part gets the sign extension from the lo-part.  This handles
216305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // things like sextinreg V:i64 from i8.
2164786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
216505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
216692abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                     TLI.getPointerTy()));
216705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
216805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  Leave the low part alone,
216905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // sext_inreg the high part.
217005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
217105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
2172786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
217354e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                     DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(),
217454e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                                                        ExcessBits)));
217505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
217605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
2177d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
217805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
2179475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2180e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2181c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
218205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
218305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2185a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::SREM_I16;
2186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
218705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I32;
2188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
218905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I64;
2190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
219105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I128;
219205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
219305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2194475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2195c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
2196d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
2197d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
219805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
2199475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
220023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2201786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2202786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
2203786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::SRL, dl,
2204786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   N->getOperand(0).getValueType(), N->getOperand(0),
220592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                   DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy()));
2206786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
2207d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
2208d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
2209268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedmanvoid DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N,
2210268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                                             SDValue &Lo, SDValue &Hi) {
2211268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue LHS = N->getOperand(0);
2212268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue RHS = N->getOperand(1);
2213268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  DebugLoc dl = N->getDebugLoc();
2214268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2215268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Expand the result by simply replacing it with the equivalent
2216268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // non-overflow-checking operation.
2217268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Sum = DAG.getNode(N->getOpcode() == ISD::UADDO ?
2218268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
2219268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                            LHS, RHS);
2220268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SplitInteger(Sum, Lo, Hi);
2221268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2222268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Calculate the overflow: addition overflows iff a + b < a, and subtraction
2223268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // overflows iff a - b > a.
2224268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Sum, LHS,
2225268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                             N->getOpcode () == ISD::UADDO ?
2226268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman                             ISD::SETULT : ISD::SETUGT);
2227268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2228268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  // Use the calculated overflow everywhere.
2229268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman  ReplaceValueWith(SDValue(N, 1), Ofl);
2230268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman}
2231268637ed0f34e10e4125e94c44ff3e2975a19166Eli Friedman
2232362fee90b9a1d64ac091755466caf6a94ade22ebEric Christophervoid DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
2233362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher                                          SDValue &Lo, SDValue &Hi) {
2234362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  EVT VT = N->getValueType(0);
2235db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *RetTy = VT.getTypeForEVT(*DAG.getContext());
2236362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  EVT PtrVT = TLI.getPointerTy();
2237db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());
2238362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  DebugLoc dl = N->getDebugLoc();
2239362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
2240a3071455e540530ecb644a2e59098129f70ce705Eric Christopher  // A divide for UMULO should be faster than a function call.
2241a3071455e540530ecb644a2e59098129f70ce705Eric Christopher  if (N->getOpcode() == ISD::UMULO) {
2242a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
2243a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    DebugLoc DL = N->getDebugLoc();
2244a3071455e540530ecb644a2e59098129f70ce705Eric Christopher
2245a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SDValue MUL = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
2246a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SplitInteger(MUL, Lo, Hi);
2247a3071455e540530ecb644a2e59098129f70ce705Eric Christopher
2248a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    // A divide for UMULO will be faster than a function call. Select to
2249a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    // make sure we aren't using 0.
2250a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SDValue isZero = DAG.getSetCC(dl, TLI.getSetCCResultType(VT),
2251a3071455e540530ecb644a2e59098129f70ce705Eric Christopher				  RHS, DAG.getConstant(0, VT), ISD::SETNE);
2252a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SDValue NotZero = DAG.getNode(ISD::SELECT, dl, VT, isZero,
2253a3071455e540530ecb644a2e59098129f70ce705Eric Christopher				  DAG.getConstant(1, VT), RHS);
2254a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SDValue DIV = DAG.getNode(ISD::UDIV, DL, LHS.getValueType(), MUL, NotZero);
2255a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    SDValue Overflow;
2256a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    Overflow = DAG.getSetCC(DL, N->getValueType(1), DIV, LHS, ISD::SETNE);
2257a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    ReplaceValueWith(SDValue(N, 1), Overflow);
2258a3071455e540530ecb644a2e59098129f70ce705Eric Christopher    return;
2259a3071455e540530ecb644a2e59098129f70ce705Eric Christopher  }
2260a3071455e540530ecb644a2e59098129f70ce705Eric Christopher
22615e687ac6158bc28f1831699d7dbfa39d3120b892Eric Christopher  // Replace this with a libcall that will check overflow.
2262362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2263362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  if (VT == MVT::i32)
2264362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    LC = RTLIB::MULO_I32;
2265362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  else if (VT == MVT::i64)
2266362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    LC = RTLIB::MULO_I64;
2267362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  else if (VT == MVT::i128)
2268362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    LC = RTLIB::MULO_I128;
2269362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XMULO!");
2270362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
2271362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  SDValue Temp = DAG.CreateStackTemporary(PtrVT);
2272362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  // Temporary for the overflow value, default it to zero.
2273362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl,
2274362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher			       DAG.getConstant(0, PtrVT), Temp,
2275362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher			       MachinePointerInfo(), false, false, 0);
2276362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
2277362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  TargetLowering::ArgListTy Args;
2278362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  TargetLowering::ArgListEntry Entry;
2279362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
2280362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    EVT ArgVT = N->getOperand(i).getValueType();
2281db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
2282362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    Entry.Node = N->getOperand(i);
2283362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    Entry.Ty = ArgTy;
2284362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    Entry.isSExt = true;
2285362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    Entry.isZExt = false;
2286362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    Args.push_back(Entry);
2287362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  }
2288362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
2289362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  // Also pass the address of the overflow check.
2290362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  Entry.Node = Temp;
2291362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  Entry.Ty = PtrTy->getPointerTo();
2292362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  Entry.isSExt = true;
2293362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  Entry.isZExt = false;
2294362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  Args.push_back(Entry);
2295362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
2296362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT);
2297362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  std::pair<SDValue, SDValue> CallInfo =
2298362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher    TLI.LowerCallTo(Chain, RetTy, true, false, false, false,
2299362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher		    0, TLI.getLibcallCallingConv(LC), false,
2300362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher		    true, Func, Args, DAG, dl);
2301362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
2302362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  SplitInteger(CallInfo.first, Lo, Hi);
2303362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  SDValue Temp2 = DAG.getLoad(PtrVT, dl, CallInfo.second, Temp,
2304362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher			      MachinePointerInfo(), false, false, 0);
2305362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Temp2,
2306362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher                             DAG.getConstant(0, PtrVT),
2307362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher                             ISD::SETNE);
2308362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  // Use the overflow from the libcall everywhere.
2309362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher  ReplaceValueWith(SDValue(N, 1), Ofl);
2310362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher}
2311362fee90b9a1d64ac091755466caf6a94ade22ebEric Christopher
231205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
2313475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2314e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2315c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2316d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
231705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2318825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2319a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::UDIV_I16;
2320825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
232105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I32;
2322825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
232305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I64;
2324825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
232505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I128;
232605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
2327d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
2328475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2329c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
2330d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
2331cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
233205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
2333475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
2334e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
2335c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
233669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
233705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2338825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  if (VT == MVT::i16)
2339a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::UREM_I16;
2340825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i32)
234105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I32;
2342825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i64)
234305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I64;
2344825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  else if (VT == MVT::i128)
234505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I128;
234605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
2347cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2348475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
2349c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
2350cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2351cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
235205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
2353475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                SDValue &Lo, SDValue &Hi) {
235423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2355786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2356475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
235705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
2358b3bc6352defdf1a5c6b1b0770d0c4d603f6524a8Duncan Sands    // The low part is zero extension of the input (degenerates to a copy).
2359786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
236005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getConstant(0, NVT);   // The high part is just a zero.
236105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
236205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
236305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
236496e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    assert(getTypeAction(Op.getValueType()) ==
236596e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem           TargetLowering::TypePromoteInteger &&
236605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
2367475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
236805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
236905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
237005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
237105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
237205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
237305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
2374adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng    Hi = DAG.getZeroExtendInReg(Hi, dl,
237554e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                                EVT::getIntegerVT(*DAG.getContext(),
237654e1791e4ba30867bda603acadda77fa85de6aa1Eric Christopher                                                  ExcessBits));
23779e255b7df5a0a629920706e086e78ef89bf2f183Dan Gohman  }
2378cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2379cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2380ba567d670d32e102a70b106fbfe284835085cb3fEli Friedmanvoid DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N,
2381ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                                                SDValue &Lo, SDValue &Hi) {
2382ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  DebugLoc dl = N->getDebugLoc();
2383ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  EVT VT = cast<AtomicSDNode>(N)->getMemoryVT();
2384ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  SDValue Zero = DAG.getConstant(0, VT);
2385ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  SDValue Swap = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, VT,
2386ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               N->getOperand(0),
2387ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               N->getOperand(1), Zero, Zero,
2388ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getMemOperand(),
2389ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getOrdering(),
2390ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getSynchScope());
2391ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  ReplaceValueWith(SDValue(N, 0), Swap.getValue(0));
2392ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  ReplaceValueWith(SDValue(N, 1), Swap.getValue(1));
2393ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman}
2394cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2395cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
239669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Operand Expansion
2397cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
2398cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
239905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandIntegerOperand - This method is called when the specified operand of
240005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// the specified node is found to need expansion.  At this point, all of the
240105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// result types of the node are known to be legal, but other operands of the
240205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// node may need promotion or expansion as well as the specified one.
240305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsbool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
2404d765353da89988e949fd4c021d8860f36ab7c392David Greene  DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG); dbgs() << "\n");
2405475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = SDValue();
2406051bb7b07504be9f848f7cce802e62ed24980bc5Duncan Sands
2407f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
2408bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    return false;
240911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands
2410bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  switch (N->getOpcode()) {
2411bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  default:
241205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  #ifndef NDEBUG
2413d765353da89988e949fd4c021d8860f36ab7c392David Greene    dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
2414d765353da89988e949fd4c021d8860f36ab7c392David Greene    N->dump(&DAG); dbgs() << "\n";
241505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  #endif
2416c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to expand this operator's operand!");
2417bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta
2418bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  case ISD::BITCAST:           Res = ExpandOp_BITCAST(N); break;
241992abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::BR_CC:             Res = ExpandIntOp_BR_CC(N); break;
242092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::BUILD_VECTOR:      Res = ExpandOp_BUILD_VECTOR(N); break;
2421bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::EXTRACT_ELEMENT:   Res = ExpandOp_EXTRACT_ELEMENT(N); break;
2422bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
2423bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SCALAR_TO_VECTOR:  Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
242492abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SELECT_CC:         Res = ExpandIntOp_SELECT_CC(N); break;
242592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SETCC:             Res = ExpandIntOp_SETCC(N); break;
242692abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SINT_TO_FP:        Res = ExpandIntOp_SINT_TO_FP(N); break;
242792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::STORE:   Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
242892abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::TRUNCATE:          Res = ExpandIntOp_TRUNCATE(N); break;
242992abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::UINT_TO_FP:        Res = ExpandIntOp_UINT_TO_FP(N); break;
243055467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
243155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SHL:
243255467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRA:
243355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRL:
243455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTL:
24351c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  case ISD::ROTR:              Res = ExpandIntOp_Shift(N); break;
24361c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  case ISD::RETURNADDR:
24371c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  case ISD::FRAMEADDR:         Res = ExpandIntOp_RETURNADDR(N); break;
2438ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman
2439ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  case ISD::ATOMIC_STORE:      Res = ExpandIntOp_ATOMIC_STORE(N); break;
244005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
244169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
244205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If the result is null, the sub-method took care of registering results etc.
2443ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Res.getNode()) return false;
244447d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
244547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // If the result is N, the sub-method updated N in place.  Tell the legalizer
244647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // core about this.
244747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  if (Res.getNode() == N)
244805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return true;
2449cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
245005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
245105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Invalid operand expansion");
245205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2453475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 0), Res);
245405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  return false;
2455cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2456cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
245711ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands/// IntegerExpandSetCCOperands - Expand the operands of a comparison.  This code
245811ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
2459475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
2460475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                  SDValue &NewRHS,
2461c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen                                                  ISD::CondCode &CCCode,
2462c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen                                                  DebugLoc dl) {
2463475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSLo, LHSHi, RHSLo, RHSHi;
246469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(NewLHS, LHSLo, LHSHi);
246569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(NewRHS, RHSLo, RHSHi);
246641edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
2467cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
246811ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    if (RHSLo == RHSHi) {
246911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands      if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
2470cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        if (RHSCST->isAllOnesValue()) {
2471cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          // Equality comparison to -1.
24727fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands          NewLHS = DAG.getNode(ISD::AND, dl,
2473786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                               LHSLo.getValueType(), LHSLo, LHSHi);
2474cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          NewRHS = RHSLo;
2475cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          return;
2476cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        }
247711ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands      }
247811ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    }
247969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2480786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
2481786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
2482786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
2483cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
2484cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2485cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
248669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2487cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If this is a comparison of the sign bit, just look at the top part.
2488cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // X > -1,  x < 0
2489cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
2490002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman    if ((CCCode == ISD::SETLT && CST->isNullValue()) ||     // X < 0
2491cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        (CCCode == ISD::SETGT && CST->isAllOnesValue())) {  // X > -1
2492cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      NewLHS = LHSHi;
2493cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      NewRHS = RHSHi;
2494cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      return;
2495cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
249669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2497cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // FIXME: This generated code sucks.
2498cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  ISD::CondCode LowCC;
2499cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  switch (CCCode) {
2500c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer setcc!");
2501cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETLT:
2502cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETULT: LowCC = ISD::SETULT; break;
2503cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETGT:
2504cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETUGT: LowCC = ISD::SETUGT; break;
2505cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETLE:
2506cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETULE: LowCC = ISD::SETULE; break;
2507cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETGE:
2508cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETUGE: LowCC = ISD::SETUGE; break;
2509cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
251069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2511cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Tmp1 = lo(op1) < lo(op2)   // Always unsigned comparison
2512cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Tmp2 = hi(op1) < hi(op2)   // Signedness depends on operands
2513cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
251469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2515cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // NOTE: on targets without efficient SELECT of bools, we can always use
2516cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
251778d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen  TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, true, NULL);
2518475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Tmp1, Tmp2;
25195480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
2520ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                           LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl);
2521ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Tmp1.getNode())
2522786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
25235480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                        LHSLo, RHSLo, LowCC);
25245480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
2525ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                           LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl);
2526ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Tmp2.getNode())
2527786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Tmp2 = DAG.getNode(ISD::SETCC, dl,
2528786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       TLI.getSetCCResultType(LHSHi.getValueType()),
25295480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                       LHSHi, RHSHi, DAG.getCondCode(CCCode));
253069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2531ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
2532ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode());
2533002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman  if ((Tmp1C && Tmp1C->isNullValue()) ||
2534002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman      (Tmp2C && Tmp2C->isNullValue() &&
2535cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner       (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
2536cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
2537002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman      (Tmp2C && Tmp2C->getAPIntValue() == 1 &&
2538cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner       (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
2539cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
2540cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // low part is known false, returns high part.
2541cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // For LE / GE, if high part is known false, ignore the low part.
2542cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // For LT / GT, if high part is known true, ignore the low part.
2543cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    NewLHS = Tmp2;
2544475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    NewRHS = SDValue();
2545cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2546cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
254769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
25485480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
2549fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel                             LHSHi, RHSHi, ISD::SETEQ, false,
2550ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                             DagCombineInfo, dl);
2551ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!NewLHS.getNode())
2552786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
25535480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                          LHSHi, RHSHi, ISD::SETEQ);
2554786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(),
2555cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                       NewLHS, Tmp1, Tmp2);
2556475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  NewRHS = SDValue();
2557cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2558cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2559475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
2560475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
256105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
2562c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
256305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
256405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, we need to compare the result
256505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // against zero to select between true and false values.
2566ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
256705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
256805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    CCCode = ISD::SETNE;
256905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
257005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
257105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Update N to have the operands specified.
2572027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
257305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
2574027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                N->getOperand(4)), 0);
257505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
257605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2577475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
2578475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
257905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
2580c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
258105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
258205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, we need to compare the result
258305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // against zero to select between true and false values.
2584ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
258505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
258605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    CCCode = ISD::SETNE;
258705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
258805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
258905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Update N to have the operands specified.
2590027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
259105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                N->getOperand(2), N->getOperand(3),
2592027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                DAG.getCondCode(CCCode)), 0);
259305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
259405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2595475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
2596475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
259705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
2598c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
259905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
260005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, use it.
2601ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
260205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(NewLHS.getValueType() == N->getValueType(0) &&
260305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Unexpected setcc expansion!");
260405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return NewLHS;
260505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
260605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
260705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Otherwise, update N to have the operands specified.
2608027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
2609027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman                                DAG.getCondCode(CCCode)), 0);
261005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
261105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
261255467af31620c9d027e071ebcd9746b7593cff17Sanjiv GuptaSDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
261355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // The value being shifted is legal, but the shift amount is too big.
261455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // It follows that either the result of the shift is undefined, or the
261555467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // upper half of the shift amount is zero.  Just use the lower half.
261655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  SDValue Lo, Hi;
261755467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  GetExpandedInteger(N->getOperand(1), Lo, Hi);
2618027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
261955467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta}
262055467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
26211c3436a67afcfaee5f972836ff1ffff2985adce1Anton KorobeynikovSDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
26221c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant.  This
26231c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  // surely makes pretty nice problems on 8/16 bit targets. Just truncate this
26241c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  // constant to valid type.
26251c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  SDValue Lo, Hi;
26261c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov  GetExpandedInteger(N->getOperand(0), Lo, Hi);
2627027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman  return SDValue(DAG.UpdateNodeOperands(N, Lo), 0);
26281c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov}
26291c3436a67afcfaee5f972836ff1ffff2985adce1Anton Korobeynikov
2630475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
2631475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
2632e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT DstVT = N->getValueType(0);
2633b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT);
263405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
263505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Don't know how to expand this SINT_TO_FP!");
2636c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc());
263705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
263805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2639475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
2640ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  if (ISD::isNormalStore(N))
2641ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands    return ExpandOp_NormalStore(N, OpNo);
264278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
264378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
2644cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  assert(OpNo == 1 && "Can only expand the stored value so far");
2645cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2646e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getOperand(1).getValueType();
264723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2648475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch  = N->getChain();
2649475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getBasePtr();
2650cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned Alignment = N->getAlignment();
2651cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  bool isVolatile = N->isVolatile();
26521e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = N->isNonTemporal();
2653786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2654475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
2655cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2656a1ace76c70ae5332d6f33fce5c0c1e2fdb8cca11Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
2657cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
265878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getMemoryVT().bitsLE(NVT)) {
265969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2660ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
26611e559443a17d1b335f697551c6263ba60d5dd827David Greene                             N->getMemoryVT(), isVolatile, isNonTemporal,
26621e559443a17d1b335f697551c6263ba60d5dd827David Greene                             Alignment);
2663ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  }
2664bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
2665ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  if (TLI.isLittleEndian()) {
2666cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Little-endian - low bits are at low addresses.
266769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2668cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2669ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(),
26701e559443a17d1b335f697551c6263ba60d5dd827David Greene                      isVolatile, isNonTemporal, Alignment);
2671cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2672cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits =
267383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
267423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits);
2675cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2676cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
267783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
2678786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
26790bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
2680ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
2681ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                           N->getPointerInfo().getWithOffset(IncrementSize),
2682ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                           NEVT, isVolatile, isNonTemporal,
26831e559443a17d1b335f697551c6263ba60d5dd827David Greene                           MinAlign(Alignment, IncrementSize));
2684825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2685ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  }
2686cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2687ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Big-endian - high bits are at low addresses.  Favor aligned stores at
2688ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // the cost of some bit-fiddling.
2689ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  GetExpandedInteger(N->getValue(), Lo, Hi);
2690ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2691ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  EVT ExtVT = N->getMemoryVT();
2692ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  unsigned EBytes = ExtVT.getStoreSize();
2693ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  unsigned IncrementSize = NVT.getSizeInBits()/8;
2694ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  unsigned ExcessBits = (EBytes - IncrementSize)*8;
2695ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  EVT HiVT = EVT::getIntegerVT(*DAG.getContext(),
2696ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                               ExtVT.getSizeInBits() - ExcessBits);
2697ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2698ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  if (ExcessBits < NVT.getSizeInBits()) {
2699ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    // Transfer high bits from the top of Lo to the bottom of Hi.
2700ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
2701ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                     DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
2702ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                                     TLI.getPointerTy()));
2703ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner    Hi = DAG.getNode(ISD::OR, dl, NVT, Hi,
2704ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                     DAG.getNode(ISD::SRL, dl, NVT, Lo,
2705ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                                 DAG.getConstant(ExcessBits,
2706ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                                                 TLI.getPointerTy())));
2707cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
2708ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2709ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Store both the high bits and maybe some of the low bits.
2710ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(),
2711ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         HiVT, isVolatile, isNonTemporal, Alignment);
2712ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner
2713ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Increment the pointer to the other half.
2714ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2715ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                    DAG.getIntPtrConstant(IncrementSize));
2716ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  // Store the lowest ExcessBits bits in the second half.
2717ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr,
2718ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         N->getPointerInfo().getWithOffset(IncrementSize),
2719ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         EVT::getIntegerVT(*DAG.getContext(), ExcessBits),
2720ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         isVolatile, isNonTemporal,
2721ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                         MinAlign(Alignment, IncrementSize));
2722ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2723cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
272405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2725475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
2726475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
272705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
272805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Just truncate the low part of the source.
2729786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL);
273005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
273105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
27328d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesenstatic const fltSemantics *EVTToAPFloatSemantics(EVT VT) {
27338d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  switch (VT.getSimpleVT().SimpleTy) {
27348d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  default: llvm_unreachable("Unknown FP format");
27358d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f32:     return &APFloat::IEEEsingle;
27368d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f64:     return &APFloat::IEEEdouble;
27378d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f80:     return &APFloat::x87DoubleExtended;
27388d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::f128:    return &APFloat::IEEEquad;
27398d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  case MVT::ppcf128: return &APFloat::PPCDoubleDouble;
27408d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  }
27418d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen}
27428d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen
2743475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
2744475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
2745e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT SrcVT = Op.getValueType();
2746e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT DstVT = N->getValueType(0);
2747c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
274805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
27498d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  // The following optimization is valid only if every value in SrcVT (when
27508d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  // treated as signed) is representable in DstVT.  Check that the mantissa
27518d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  // size of DstVT is >= than the number of bits in SrcVT -1.
27528d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  const fltSemantics *sem = EVTToAPFloatSemantics(DstVT);
27538d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen  if (APFloat::semanticsPrecision(*sem) >= SrcVT.getSizeInBits()-1 &&
27548d908ebd1926d00ff47d8284e52657705efb7f9bDale Johannesen      TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
275505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Do a signed conversion then adjust the result.
2756786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);
275705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SignedConv = TLI.LowerOperation(SignedConv, DAG);
275805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
275905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The result of the signed conversion needs adjusting if the 'sign bit' of
276005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // the incoming integer was set.  To handle this, we dynamically test to see
276105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // if it is set, and, if so, add a fudge factor.
276205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
276305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE32  = 0x4F800000ULL;
276405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE64  = 0x5F800000ULL;
276505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE128 = 0x7F800000ULL;
276605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
276705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    APInt FF(32, 0);
2768825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (SrcVT == MVT::i32)
276905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE32);
2770825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (SrcVT == MVT::i64)
277105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE64);
2772825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    else if (SrcVT == MVT::i128)
277305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE128);
277405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    else
277505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      assert(false && "Unsupported UINT_TO_FP!");
277605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
277705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Check whether the sign bit is set.
2778475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
277905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    GetExpandedInteger(Op, Lo, Hi);
27807fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands    SDValue SignSet = DAG.getSetCC(dl,
2781786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                                   TLI.getSetCCResultType(Hi.getValueType()),
27825480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                                   Hi, DAG.getConstant(0, Hi.getValueType()),
2783ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   ISD::SETLT);
278405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
278505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.
2786001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson    SDValue FudgePtr = DAG.getConstantPool(
2787eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson                               ConstantInt::get(*DAG.getContext(), FF.zext(64)),
278849c18cce976c158e86f54c681dff21bb81640fb8Duncan Sands                                           TLI.getPointerTy());
278905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
279005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
2791475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Zero = DAG.getIntPtrConstant(0);
2792475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Four = DAG.getIntPtrConstant(4);
279305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (TLI.isBigEndian()) std::swap(Zero, Four);
2794786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet,
2795ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                 Zero, Four);
27961606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment();
2797786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset);
279887a0f10dc7eff8cf5e83a754f75adf9cb3991435Dan Gohman    Alignment = std::min(Alignment, 4u);
279905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
280005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Load the value out, extending it from f32 to the destination float type.
280105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // FIXME: Avoid the extend by constructing the right constant pool?
2802a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings    SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
28033d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                                   FudgePtr,
28043d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                                   MachinePointerInfo::getConstantPool(),
28053d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner                                   MVT::f32,
28061e559443a17d1b335f697551c6263ba60d5dd827David Greene                                   false, false, Alignment);
2807786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
280805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
280905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
281005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Otherwise, use a libcall.
2811b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT);
281205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
281305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Don't know how to expand this UINT_TO_FP!");
2814c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  return MakeLibCall(LC, DstVT, &Op, 1, true, dl);
281505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
2816fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2817ba567d670d32e102a70b106fbfe284835085cb3fEli FriedmanSDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) {
2818ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  DebugLoc dl = N->getDebugLoc();
2819ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl,
2820ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getMemoryVT(),
2821ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               N->getOperand(0),
2822ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               N->getOperand(1), N->getOperand(2),
2823ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getMemOperand(),
2824ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getOrdering(),
2825ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman                               cast<AtomicSDNode>(N)->getSynchScope());
2826ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman  return Swap.getValue(1);
2827ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman}
2828ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman
2829ba567d670d32e102a70b106fbfe284835085cb3fEli Friedman
2830fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {
2831fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue InOp0 = N->getOperand(0);
2832fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT InVT = InOp0.getValueType();
2833fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2834fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2835fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2836fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
28375b82c2f8911e7e7bcaa563cf15b5d03cf0292379Nadav Rotem  unsigned OutNumElems = OutVT.getVectorNumElements();
2838fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2839fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2840fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2841fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue BaseIdx = N->getOperand(1);
2842fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2843fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<SDValue, 8> Ops;
28445b82c2f8911e7e7bcaa563cf15b5d03cf0292379Nadav Rotem  Ops.reserve(OutNumElems);
2845fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned i = 0; i != OutNumElems; ++i) {
2846fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2847fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    // Extract the element from the original vector.
2848fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(),
2849fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      BaseIdx, DAG.getIntPtrConstant(i));
2850fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2851fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      InVT.getVectorElementType(), N->getOperand(0), Index);
2852fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2853fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, Ext);
2854fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    // Insert the converted element to the new vector.
2855fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    Ops.push_back(Op);
2856fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2857fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2858fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size());
2859fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2860fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2861fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2862fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) {
2863fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N);
2864fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT VT = N->getValueType(0);
2865fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2866fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2867fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  unsigned NumElts = VT.getVectorNumElements();
2868fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<int, 8> NewMask;
2869fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned i = 0; i != NumElts; ++i) {
2870fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    NewMask.push_back(SV->getMaskElt(i));
2871fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2872fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2873fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V0 = GetPromotedInteger(N->getOperand(0));
2874fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V1 = GetPromotedInteger(N->getOperand(1));
28755b82c2f8911e7e7bcaa563cf15b5d03cf0292379Nadav Rotem  EVT OutVT = V0.getValueType();
2876fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
28775b82c2f8911e7e7bcaa563cf15b5d03cf0292379Nadav Rotem  return DAG.getVectorShuffle(OutVT, dl, V0, V1, &NewMask[0]);
2878fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2879fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2880fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2881fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) {
2882fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2883fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2884fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2885fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  unsigned NumElems = N->getNumOperands();
2886fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2887fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2888fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2889fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2890fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<SDValue, 8> Ops;
28915b82c2f8911e7e7bcaa563cf15b5d03cf0292379Nadav Rotem  Ops.reserve(NumElems);
2892fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  for (unsigned i = 0; i != NumElems; ++i) {
2893fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(i));
2894fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    Ops.push_back(Op);
2895fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2896fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2897fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size());
2898fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2899fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2900fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N) {
2901fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2902fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2903fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
29041396c403897e3d3e04fbf59f6c5fe77cbbab74a6Benjamin Kramer  assert(!N->getOperand(0).getValueType().isVector() &&
29051396c403897e3d3e04fbf59f6c5fe77cbbab74a6Benjamin Kramer         "Input must be a scalar");
2906fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2907fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2908fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2909fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2910fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2911fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2912fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(0));
2913fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2914fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NOutVT, Op);
2915fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2916fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2917fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) {
2918fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT OutVT = N->getValueType(0);
2919fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
2920fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  assert(NOutVT.isVector() && "This type must be promoted to a vector type");
2921fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2922fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT NOutVTElem = NOutVT.getVectorElementType();
2923fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2924fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2925811ad8690b798cdcbd9d80a2b6a404145222b9a9Nadav Rotem  SDValue V0 = GetPromotedInteger(N->getOperand(0));
2926fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2927fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl,
2928fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    NOutVTElem, N->getOperand(1));
2929811ad8690b798cdcbd9d80a2b6a404145222b9a9Nadav Rotem  return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT,
29302ff4bc615584fa9f32e64959767d64f2cb09fb99Nadav Rotem    V0, ConvElem, N->getOperand(2));
2931fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2932fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2933fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
2934fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2935fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V0 = GetPromotedInteger(N->getOperand(0));
2936fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue V1 = N->getOperand(1);
2937fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
2938fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    V0->getValueType(0).getScalarType(), V0, V1);
2939fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2940fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), Ext);
2941fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2942fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem}
2943fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2944fc3623bc50aa9e2a56736775edbd3ae919565351Nadav RotemSDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
2945fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  DebugLoc dl = N->getDebugLoc();
2946811ad8690b798cdcbd9d80a2b6a404145222b9a9Nadav Rotem  unsigned NumElems = N->getNumOperands();
2947fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2948fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  EVT RetSclrTy = N->getValueType(0).getVectorElementType();
2949fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2950fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  SmallVector<SDValue, 8> NewOps;
2951811ad8690b798cdcbd9d80a2b6a404145222b9a9Nadav Rotem  NewOps.reserve(NumElems);
2952fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2953fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  // For each incoming vector
2954811ad8690b798cdcbd9d80a2b6a404145222b9a9Nadav Rotem  for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) {
2955fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx));
2956fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    EVT SclrTy = Incoming->getValueType(0).getVectorElementType();
2957fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    unsigned NumElem = Incoming->getValueType(0).getVectorNumElements();
2958fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2959fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    for (unsigned i=0; i<NumElem; ++i) {
2960fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      // Extract element from incoming vector
2961fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy,
2962fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      Incoming, DAG.getIntPtrConstant(i));
2963fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex);
2964fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem      NewOps.push_back(Tr);
2965fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    }
2966fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2967fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem
2968fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  return DAG.getNode(ISD::BUILD_VECTOR, dl,  N->getValueType(0),
2969fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem    &NewOps[0], NewOps.size());
2970fc3623bc50aa9e2a56736775edbd3ae919565351Nadav Rotem  }
2971