1 //===-- NVPTXISelDAGToDAG.cpp - A dag to dag inst selector for NVPTX ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an instruction selector for the NVPTX target.
12 //===----------------------------------------------------------------------===//
14 #include "NVPTXISelDAGToDAG.h"
15 #include "llvm/IR/GlobalValue.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/Target/TargetIntrinsicInfo.h"
24 #define DEBUG_TYPE "nvptx-isel"
28 static cl::opt<bool> UseFMADInstruction(
29 "nvptx-mad-enable", cl::ZeroOrMore,
30 cl::desc("NVPTX Specific: Enable generating FMAD instructions"),
34 FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore,
35 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
36 " 1: do it 2: do it aggressively"),
39 static cl::opt<int> UsePrecDivF32(
40 "nvptx-prec-divf32", cl::ZeroOrMore,
41 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
42 " IEEE Compliant F32 div.rnd if avaiable."),
46 UsePrecSqrtF32("nvptx-prec-sqrtf32",
47 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
50 /// createNVPTXISelDag - This pass converts a legalized DAG into a
51 /// NVPTX-specific DAG, ready for instruction scheduling.
52 FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
53 llvm::CodeGenOpt::Level OptLevel) {
54 return new NVPTXDAGToDAGISel(TM, OptLevel);
57 NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
58 CodeGenOpt::Level OptLevel)
59 : SelectionDAGISel(tm, OptLevel),
60 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
61 // Always do fma.f32 fpcontract if the target supports the instruction.
62 // Always do fma.f64 fpcontract if the target supports the instruction.
63 // Do mad.f32 is nvptx-mad-enable is specified and the target does not
66 doFMADF32 = (OptLevel > 0) && UseFMADInstruction && !Subtarget.hasFMAF32();
67 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
68 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
70 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
72 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
74 allowFMA = (FMAContractLevel >= 1) || UseFMADInstruction;
78 doMulWide = (OptLevel > 0);
80 // Decide how to translate f32 div
81 do_DIVF32_PREC = UsePrecDivF32;
82 // Decide how to translate f32 sqrt
83 do_SQRTF32_PREC = UsePrecSqrtF32;
84 // sm less than sm_20 does not support div.rnd. Use div.full.
85 if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20())
90 /// Select - Select instructions not customized! Used for
91 /// expanded, promoted and normal instructions.
92 SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
94 if (N->isMachineOpcode())
95 return NULL; // Already selected.
97 SDNode *ResNode = NULL;
98 switch (N->getOpcode()) {
100 ResNode = SelectLoad(N);
103 ResNode = SelectStore(N);
105 case NVPTXISD::LoadV2:
106 case NVPTXISD::LoadV4:
107 ResNode = SelectLoadVector(N);
109 case NVPTXISD::LDGV2:
110 case NVPTXISD::LDGV4:
111 case NVPTXISD::LDUV2:
112 case NVPTXISD::LDUV4:
113 ResNode = SelectLDGLDUVector(N);
115 case NVPTXISD::StoreV2:
116 case NVPTXISD::StoreV4:
117 ResNode = SelectStoreVector(N);
124 return SelectCode(N);
127 static unsigned int getCodeAddrSpace(MemSDNode *N,
128 const NVPTXSubtarget &Subtarget) {
129 const Value *Src = N->getSrcValue();
132 return NVPTX::PTXLdStInstCode::GENERIC;
134 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
135 switch (PT->getAddressSpace()) {
136 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
137 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
138 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
139 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
140 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
141 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
145 return NVPTX::PTXLdStInstCode::GENERIC;
148 SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
150 LoadSDNode *LD = cast<LoadSDNode>(N);
151 EVT LoadedVT = LD->getMemoryVT();
152 SDNode *NVPTXLD = NULL;
154 // do not support pre/post inc/dec
158 if (!LoadedVT.isSimple())
161 // Address Space Setting
162 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
165 // - .volatile is only availalble for .global and .shared
166 bool isVolatile = LD->isVolatile();
167 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
168 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
169 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
173 MVT SimpleVT = LoadedVT.getSimpleVT();
174 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
175 if (SimpleVT.isVector()) {
176 unsigned num = SimpleVT.getVectorNumElements();
178 vecType = NVPTX::PTXLdStInstCode::V2;
180 vecType = NVPTX::PTXLdStInstCode::V4;
185 // Type Setting: fromType + fromTypeWidth
187 // Sign : ISD::SEXTLOAD
188 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
190 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
191 MVT ScalarVT = SimpleVT.getScalarType();
192 // Read at least 8 bits (predicates are stored as 8-bit values)
193 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
194 unsigned int fromType;
195 if ((LD->getExtensionType() == ISD::SEXTLOAD))
196 fromType = NVPTX::PTXLdStInstCode::Signed;
197 else if (ScalarVT.isFloatingPoint())
198 fromType = NVPTX::PTXLdStInstCode::Float;
200 fromType = NVPTX::PTXLdStInstCode::Unsigned;
202 // Create the machine instruction DAG
203 SDValue Chain = N->getOperand(0);
204 SDValue N1 = N->getOperand(1);
206 SDValue Offset, Base;
208 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
210 if (SelectDirectAddr(N1, Addr)) {
213 Opcode = NVPTX::LD_i8_avar;
216 Opcode = NVPTX::LD_i16_avar;
219 Opcode = NVPTX::LD_i32_avar;
222 Opcode = NVPTX::LD_i64_avar;
225 Opcode = NVPTX::LD_f32_avar;
228 Opcode = NVPTX::LD_f64_avar;
233 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
234 getI32Imm(vecType), getI32Imm(fromType),
235 getI32Imm(fromTypeWidth), Addr, Chain };
236 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
237 } else if (Subtarget.is64Bit()
238 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
239 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
242 Opcode = NVPTX::LD_i8_asi;
245 Opcode = NVPTX::LD_i16_asi;
248 Opcode = NVPTX::LD_i32_asi;
251 Opcode = NVPTX::LD_i64_asi;
254 Opcode = NVPTX::LD_f32_asi;
257 Opcode = NVPTX::LD_f64_asi;
262 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
263 getI32Imm(vecType), getI32Imm(fromType),
264 getI32Imm(fromTypeWidth), Base, Offset, Chain };
265 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
266 } else if (Subtarget.is64Bit()
267 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
268 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
269 if (Subtarget.is64Bit()) {
272 Opcode = NVPTX::LD_i8_ari_64;
275 Opcode = NVPTX::LD_i16_ari_64;
278 Opcode = NVPTX::LD_i32_ari_64;
281 Opcode = NVPTX::LD_i64_ari_64;
284 Opcode = NVPTX::LD_f32_ari_64;
287 Opcode = NVPTX::LD_f64_ari_64;
295 Opcode = NVPTX::LD_i8_ari;
298 Opcode = NVPTX::LD_i16_ari;
301 Opcode = NVPTX::LD_i32_ari;
304 Opcode = NVPTX::LD_i64_ari;
307 Opcode = NVPTX::LD_f32_ari;
310 Opcode = NVPTX::LD_f64_ari;
316 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
317 getI32Imm(vecType), getI32Imm(fromType),
318 getI32Imm(fromTypeWidth), Base, Offset, Chain };
319 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
321 if (Subtarget.is64Bit()) {
324 Opcode = NVPTX::LD_i8_areg_64;
327 Opcode = NVPTX::LD_i16_areg_64;
330 Opcode = NVPTX::LD_i32_areg_64;
333 Opcode = NVPTX::LD_i64_areg_64;
336 Opcode = NVPTX::LD_f32_areg_64;
339 Opcode = NVPTX::LD_f64_areg_64;
347 Opcode = NVPTX::LD_i8_areg;
350 Opcode = NVPTX::LD_i16_areg;
353 Opcode = NVPTX::LD_i32_areg;
356 Opcode = NVPTX::LD_i64_areg;
359 Opcode = NVPTX::LD_f32_areg;
362 Opcode = NVPTX::LD_f64_areg;
368 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
369 getI32Imm(vecType), getI32Imm(fromType),
370 getI32Imm(fromTypeWidth), N1, Chain };
371 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
374 if (NVPTXLD != NULL) {
375 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
376 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
377 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
383 SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
385 SDValue Chain = N->getOperand(0);
386 SDValue Op1 = N->getOperand(1);
387 SDValue Addr, Offset, Base;
391 MemSDNode *MemSD = cast<MemSDNode>(N);
392 EVT LoadedVT = MemSD->getMemoryVT();
394 if (!LoadedVT.isSimple())
397 // Address Space Setting
398 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
401 // - .volatile is only availalble for .global and .shared
402 bool IsVolatile = MemSD->isVolatile();
403 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
404 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
405 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
409 MVT SimpleVT = LoadedVT.getSimpleVT();
411 // Type Setting: fromType + fromTypeWidth
413 // Sign : ISD::SEXTLOAD
414 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
416 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
417 MVT ScalarVT = SimpleVT.getScalarType();
418 // Read at least 8 bits (predicates are stored as 8-bit values)
419 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
420 unsigned int FromType;
421 // The last operand holds the original LoadSDNode::getExtensionType() value
422 unsigned ExtensionType = cast<ConstantSDNode>(
423 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
424 if (ExtensionType == ISD::SEXTLOAD)
425 FromType = NVPTX::PTXLdStInstCode::Signed;
426 else if (ScalarVT.isFloatingPoint())
427 FromType = NVPTX::PTXLdStInstCode::Float;
429 FromType = NVPTX::PTXLdStInstCode::Unsigned;
433 switch (N->getOpcode()) {
434 case NVPTXISD::LoadV2:
435 VecType = NVPTX::PTXLdStInstCode::V2;
437 case NVPTXISD::LoadV4:
438 VecType = NVPTX::PTXLdStInstCode::V4;
444 EVT EltVT = N->getValueType(0);
446 if (SelectDirectAddr(Op1, Addr)) {
447 switch (N->getOpcode()) {
450 case NVPTXISD::LoadV2:
451 switch (EltVT.getSimpleVT().SimpleTy) {
455 Opcode = NVPTX::LDV_i8_v2_avar;
458 Opcode = NVPTX::LDV_i16_v2_avar;
461 Opcode = NVPTX::LDV_i32_v2_avar;
464 Opcode = NVPTX::LDV_i64_v2_avar;
467 Opcode = NVPTX::LDV_f32_v2_avar;
470 Opcode = NVPTX::LDV_f64_v2_avar;
474 case NVPTXISD::LoadV4:
475 switch (EltVT.getSimpleVT().SimpleTy) {
479 Opcode = NVPTX::LDV_i8_v4_avar;
482 Opcode = NVPTX::LDV_i16_v4_avar;
485 Opcode = NVPTX::LDV_i32_v4_avar;
488 Opcode = NVPTX::LDV_f32_v4_avar;
494 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
495 getI32Imm(VecType), getI32Imm(FromType),
496 getI32Imm(FromTypeWidth), Addr, Chain };
497 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
498 } else if (Subtarget.is64Bit()
499 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
500 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
501 switch (N->getOpcode()) {
504 case NVPTXISD::LoadV2:
505 switch (EltVT.getSimpleVT().SimpleTy) {
509 Opcode = NVPTX::LDV_i8_v2_asi;
512 Opcode = NVPTX::LDV_i16_v2_asi;
515 Opcode = NVPTX::LDV_i32_v2_asi;
518 Opcode = NVPTX::LDV_i64_v2_asi;
521 Opcode = NVPTX::LDV_f32_v2_asi;
524 Opcode = NVPTX::LDV_f64_v2_asi;
528 case NVPTXISD::LoadV4:
529 switch (EltVT.getSimpleVT().SimpleTy) {
533 Opcode = NVPTX::LDV_i8_v4_asi;
536 Opcode = NVPTX::LDV_i16_v4_asi;
539 Opcode = NVPTX::LDV_i32_v4_asi;
542 Opcode = NVPTX::LDV_f32_v4_asi;
548 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
549 getI32Imm(VecType), getI32Imm(FromType),
550 getI32Imm(FromTypeWidth), Base, Offset, Chain };
551 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
552 } else if (Subtarget.is64Bit()
553 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
554 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
555 if (Subtarget.is64Bit()) {
556 switch (N->getOpcode()) {
559 case NVPTXISD::LoadV2:
560 switch (EltVT.getSimpleVT().SimpleTy) {
564 Opcode = NVPTX::LDV_i8_v2_ari_64;
567 Opcode = NVPTX::LDV_i16_v2_ari_64;
570 Opcode = NVPTX::LDV_i32_v2_ari_64;
573 Opcode = NVPTX::LDV_i64_v2_ari_64;
576 Opcode = NVPTX::LDV_f32_v2_ari_64;
579 Opcode = NVPTX::LDV_f64_v2_ari_64;
583 case NVPTXISD::LoadV4:
584 switch (EltVT.getSimpleVT().SimpleTy) {
588 Opcode = NVPTX::LDV_i8_v4_ari_64;
591 Opcode = NVPTX::LDV_i16_v4_ari_64;
594 Opcode = NVPTX::LDV_i32_v4_ari_64;
597 Opcode = NVPTX::LDV_f32_v4_ari_64;
603 switch (N->getOpcode()) {
606 case NVPTXISD::LoadV2:
607 switch (EltVT.getSimpleVT().SimpleTy) {
611 Opcode = NVPTX::LDV_i8_v2_ari;
614 Opcode = NVPTX::LDV_i16_v2_ari;
617 Opcode = NVPTX::LDV_i32_v2_ari;
620 Opcode = NVPTX::LDV_i64_v2_ari;
623 Opcode = NVPTX::LDV_f32_v2_ari;
626 Opcode = NVPTX::LDV_f64_v2_ari;
630 case NVPTXISD::LoadV4:
631 switch (EltVT.getSimpleVT().SimpleTy) {
635 Opcode = NVPTX::LDV_i8_v4_ari;
638 Opcode = NVPTX::LDV_i16_v4_ari;
641 Opcode = NVPTX::LDV_i32_v4_ari;
644 Opcode = NVPTX::LDV_f32_v4_ari;
651 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
652 getI32Imm(VecType), getI32Imm(FromType),
653 getI32Imm(FromTypeWidth), Base, Offset, Chain };
655 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
657 if (Subtarget.is64Bit()) {
658 switch (N->getOpcode()) {
661 case NVPTXISD::LoadV2:
662 switch (EltVT.getSimpleVT().SimpleTy) {
666 Opcode = NVPTX::LDV_i8_v2_areg_64;
669 Opcode = NVPTX::LDV_i16_v2_areg_64;
672 Opcode = NVPTX::LDV_i32_v2_areg_64;
675 Opcode = NVPTX::LDV_i64_v2_areg_64;
678 Opcode = NVPTX::LDV_f32_v2_areg_64;
681 Opcode = NVPTX::LDV_f64_v2_areg_64;
685 case NVPTXISD::LoadV4:
686 switch (EltVT.getSimpleVT().SimpleTy) {
690 Opcode = NVPTX::LDV_i8_v4_areg_64;
693 Opcode = NVPTX::LDV_i16_v4_areg_64;
696 Opcode = NVPTX::LDV_i32_v4_areg_64;
699 Opcode = NVPTX::LDV_f32_v4_areg_64;
705 switch (N->getOpcode()) {
708 case NVPTXISD::LoadV2:
709 switch (EltVT.getSimpleVT().SimpleTy) {
713 Opcode = NVPTX::LDV_i8_v2_areg;
716 Opcode = NVPTX::LDV_i16_v2_areg;
719 Opcode = NVPTX::LDV_i32_v2_areg;
722 Opcode = NVPTX::LDV_i64_v2_areg;
725 Opcode = NVPTX::LDV_f32_v2_areg;
728 Opcode = NVPTX::LDV_f64_v2_areg;
732 case NVPTXISD::LoadV4:
733 switch (EltVT.getSimpleVT().SimpleTy) {
737 Opcode = NVPTX::LDV_i8_v4_areg;
740 Opcode = NVPTX::LDV_i16_v4_areg;
743 Opcode = NVPTX::LDV_i32_v4_areg;
746 Opcode = NVPTX::LDV_f32_v4_areg;
753 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
754 getI32Imm(VecType), getI32Imm(FromType),
755 getI32Imm(FromTypeWidth), Op1, Chain };
756 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
759 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
760 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
761 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
766 SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
768 SDValue Chain = N->getOperand(0);
769 SDValue Op1 = N->getOperand(1);
774 EVT RetVT = N->getValueType(0);
777 if (Subtarget.is64Bit()) {
778 switch (N->getOpcode()) {
781 case NVPTXISD::LDGV2:
782 switch (RetVT.getSimpleVT().SimpleTy) {
786 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_64;
789 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_64;
792 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_64;
795 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_64;
798 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_64;
801 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_64;
805 case NVPTXISD::LDGV4:
806 switch (RetVT.getSimpleVT().SimpleTy) {
810 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_64;
813 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_64;
816 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_64;
819 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_64;
823 case NVPTXISD::LDUV2:
824 switch (RetVT.getSimpleVT().SimpleTy) {
828 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_64;
831 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_64;
834 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_64;
837 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_64;
840 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_64;
843 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_64;
847 case NVPTXISD::LDUV4:
848 switch (RetVT.getSimpleVT().SimpleTy) {
852 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_64;
855 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_64;
858 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_64;
861 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_64;
867 switch (N->getOpcode()) {
870 case NVPTXISD::LDGV2:
871 switch (RetVT.getSimpleVT().SimpleTy) {
875 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_32;
878 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_32;
881 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_32;
884 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_32;
887 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_32;
890 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_32;
894 case NVPTXISD::LDGV4:
895 switch (RetVT.getSimpleVT().SimpleTy) {
899 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_32;
902 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_32;
905 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_32;
908 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_32;
912 case NVPTXISD::LDUV2:
913 switch (RetVT.getSimpleVT().SimpleTy) {
917 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_32;
920 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_32;
923 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_32;
926 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_32;
929 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_32;
932 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_32;
936 case NVPTXISD::LDUV4:
937 switch (RetVT.getSimpleVT().SimpleTy) {
941 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_32;
944 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_32;
947 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_32;
950 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_32;
957 SDValue Ops[] = { Op1, Chain };
958 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
960 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
961 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
962 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
967 SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
969 StoreSDNode *ST = cast<StoreSDNode>(N);
970 EVT StoreVT = ST->getMemoryVT();
971 SDNode *NVPTXST = NULL;
973 // do not support pre/post inc/dec
977 if (!StoreVT.isSimple())
980 // Address Space Setting
981 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
984 // - .volatile is only availalble for .global and .shared
985 bool isVolatile = ST->isVolatile();
986 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
987 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
988 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
992 MVT SimpleVT = StoreVT.getSimpleVT();
993 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
994 if (SimpleVT.isVector()) {
995 unsigned num = SimpleVT.getVectorNumElements();
997 vecType = NVPTX::PTXLdStInstCode::V2;
999 vecType = NVPTX::PTXLdStInstCode::V4;
1004 // Type Setting: toType + toTypeWidth
1005 // - for integer type, always use 'u'
1007 MVT ScalarVT = SimpleVT.getScalarType();
1008 unsigned toTypeWidth = ScalarVT.getSizeInBits();
1009 unsigned int toType;
1010 if (ScalarVT.isFloatingPoint())
1011 toType = NVPTX::PTXLdStInstCode::Float;
1013 toType = NVPTX::PTXLdStInstCode::Unsigned;
1015 // Create the machine instruction DAG
1016 SDValue Chain = N->getOperand(0);
1017 SDValue N1 = N->getOperand(1);
1018 SDValue N2 = N->getOperand(2);
1020 SDValue Offset, Base;
1022 MVT::SimpleValueType SourceVT =
1023 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1025 if (SelectDirectAddr(N2, Addr)) {
1028 Opcode = NVPTX::ST_i8_avar;
1031 Opcode = NVPTX::ST_i16_avar;
1034 Opcode = NVPTX::ST_i32_avar;
1037 Opcode = NVPTX::ST_i64_avar;
1040 Opcode = NVPTX::ST_f32_avar;
1043 Opcode = NVPTX::ST_f64_avar;
1048 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1049 getI32Imm(vecType), getI32Imm(toType),
1050 getI32Imm(toTypeWidth), Addr, Chain };
1051 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1052 } else if (Subtarget.is64Bit()
1053 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1054 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1057 Opcode = NVPTX::ST_i8_asi;
1060 Opcode = NVPTX::ST_i16_asi;
1063 Opcode = NVPTX::ST_i32_asi;
1066 Opcode = NVPTX::ST_i64_asi;
1069 Opcode = NVPTX::ST_f32_asi;
1072 Opcode = NVPTX::ST_f64_asi;
1077 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1078 getI32Imm(vecType), getI32Imm(toType),
1079 getI32Imm(toTypeWidth), Base, Offset, Chain };
1080 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1081 } else if (Subtarget.is64Bit()
1082 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1083 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1084 if (Subtarget.is64Bit()) {
1087 Opcode = NVPTX::ST_i8_ari_64;
1090 Opcode = NVPTX::ST_i16_ari_64;
1093 Opcode = NVPTX::ST_i32_ari_64;
1096 Opcode = NVPTX::ST_i64_ari_64;
1099 Opcode = NVPTX::ST_f32_ari_64;
1102 Opcode = NVPTX::ST_f64_ari_64;
1110 Opcode = NVPTX::ST_i8_ari;
1113 Opcode = NVPTX::ST_i16_ari;
1116 Opcode = NVPTX::ST_i32_ari;
1119 Opcode = NVPTX::ST_i64_ari;
1122 Opcode = NVPTX::ST_f32_ari;
1125 Opcode = NVPTX::ST_f64_ari;
1131 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1132 getI32Imm(vecType), getI32Imm(toType),
1133 getI32Imm(toTypeWidth), Base, Offset, Chain };
1134 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1136 if (Subtarget.is64Bit()) {
1139 Opcode = NVPTX::ST_i8_areg_64;
1142 Opcode = NVPTX::ST_i16_areg_64;
1145 Opcode = NVPTX::ST_i32_areg_64;
1148 Opcode = NVPTX::ST_i64_areg_64;
1151 Opcode = NVPTX::ST_f32_areg_64;
1154 Opcode = NVPTX::ST_f64_areg_64;
1162 Opcode = NVPTX::ST_i8_areg;
1165 Opcode = NVPTX::ST_i16_areg;
1168 Opcode = NVPTX::ST_i32_areg;
1171 Opcode = NVPTX::ST_i64_areg;
1174 Opcode = NVPTX::ST_f32_areg;
1177 Opcode = NVPTX::ST_f64_areg;
1183 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1184 getI32Imm(vecType), getI32Imm(toType),
1185 getI32Imm(toTypeWidth), N2, Chain };
1186 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1189 if (NVPTXST != NULL) {
1190 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1191 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1192 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1198 SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1199 SDValue Chain = N->getOperand(0);
1200 SDValue Op1 = N->getOperand(1);
1201 SDValue Addr, Offset, Base;
1205 EVT EltVT = Op1.getValueType();
1206 MemSDNode *MemSD = cast<MemSDNode>(N);
1207 EVT StoreVT = MemSD->getMemoryVT();
1209 // Address Space Setting
1210 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1212 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1213 report_fatal_error("Cannot store to pointer that points to constant "
1218 // - .volatile is only availalble for .global and .shared
1219 bool IsVolatile = MemSD->isVolatile();
1220 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1221 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1222 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1225 // Type Setting: toType + toTypeWidth
1226 // - for integer type, always use 'u'
1227 assert(StoreVT.isSimple() && "Store value is not simple");
1228 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
1229 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
1231 if (ScalarVT.isFloatingPoint())
1232 ToType = NVPTX::PTXLdStInstCode::Float;
1234 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1236 SmallVector<SDValue, 12> StOps;
1240 switch (N->getOpcode()) {
1241 case NVPTXISD::StoreV2:
1242 VecType = NVPTX::PTXLdStInstCode::V2;
1243 StOps.push_back(N->getOperand(1));
1244 StOps.push_back(N->getOperand(2));
1245 N2 = N->getOperand(3);
1247 case NVPTXISD::StoreV4:
1248 VecType = NVPTX::PTXLdStInstCode::V4;
1249 StOps.push_back(N->getOperand(1));
1250 StOps.push_back(N->getOperand(2));
1251 StOps.push_back(N->getOperand(3));
1252 StOps.push_back(N->getOperand(4));
1253 N2 = N->getOperand(5);
1259 StOps.push_back(getI32Imm(IsVolatile));
1260 StOps.push_back(getI32Imm(CodeAddrSpace));
1261 StOps.push_back(getI32Imm(VecType));
1262 StOps.push_back(getI32Imm(ToType));
1263 StOps.push_back(getI32Imm(ToTypeWidth));
1265 if (SelectDirectAddr(N2, Addr)) {
1266 switch (N->getOpcode()) {
1269 case NVPTXISD::StoreV2:
1270 switch (EltVT.getSimpleVT().SimpleTy) {
1274 Opcode = NVPTX::STV_i8_v2_avar;
1277 Opcode = NVPTX::STV_i16_v2_avar;
1280 Opcode = NVPTX::STV_i32_v2_avar;
1283 Opcode = NVPTX::STV_i64_v2_avar;
1286 Opcode = NVPTX::STV_f32_v2_avar;
1289 Opcode = NVPTX::STV_f64_v2_avar;
1293 case NVPTXISD::StoreV4:
1294 switch (EltVT.getSimpleVT().SimpleTy) {
1298 Opcode = NVPTX::STV_i8_v4_avar;
1301 Opcode = NVPTX::STV_i16_v4_avar;
1304 Opcode = NVPTX::STV_i32_v4_avar;
1307 Opcode = NVPTX::STV_f32_v4_avar;
1312 StOps.push_back(Addr);
1313 } else if (Subtarget.is64Bit()
1314 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1315 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1316 switch (N->getOpcode()) {
1319 case NVPTXISD::StoreV2:
1320 switch (EltVT.getSimpleVT().SimpleTy) {
1324 Opcode = NVPTX::STV_i8_v2_asi;
1327 Opcode = NVPTX::STV_i16_v2_asi;
1330 Opcode = NVPTX::STV_i32_v2_asi;
1333 Opcode = NVPTX::STV_i64_v2_asi;
1336 Opcode = NVPTX::STV_f32_v2_asi;
1339 Opcode = NVPTX::STV_f64_v2_asi;
1343 case NVPTXISD::StoreV4:
1344 switch (EltVT.getSimpleVT().SimpleTy) {
1348 Opcode = NVPTX::STV_i8_v4_asi;
1351 Opcode = NVPTX::STV_i16_v4_asi;
1354 Opcode = NVPTX::STV_i32_v4_asi;
1357 Opcode = NVPTX::STV_f32_v4_asi;
1362 StOps.push_back(Base);
1363 StOps.push_back(Offset);
1364 } else if (Subtarget.is64Bit()
1365 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1366 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1367 if (Subtarget.is64Bit()) {
1368 switch (N->getOpcode()) {
1371 case NVPTXISD::StoreV2:
1372 switch (EltVT.getSimpleVT().SimpleTy) {
1376 Opcode = NVPTX::STV_i8_v2_ari_64;
1379 Opcode = NVPTX::STV_i16_v2_ari_64;
1382 Opcode = NVPTX::STV_i32_v2_ari_64;
1385 Opcode = NVPTX::STV_i64_v2_ari_64;
1388 Opcode = NVPTX::STV_f32_v2_ari_64;
1391 Opcode = NVPTX::STV_f64_v2_ari_64;
1395 case NVPTXISD::StoreV4:
1396 switch (EltVT.getSimpleVT().SimpleTy) {
1400 Opcode = NVPTX::STV_i8_v4_ari_64;
1403 Opcode = NVPTX::STV_i16_v4_ari_64;
1406 Opcode = NVPTX::STV_i32_v4_ari_64;
1409 Opcode = NVPTX::STV_f32_v4_ari_64;
1415 switch (N->getOpcode()) {
1418 case NVPTXISD::StoreV2:
1419 switch (EltVT.getSimpleVT().SimpleTy) {
1423 Opcode = NVPTX::STV_i8_v2_ari;
1426 Opcode = NVPTX::STV_i16_v2_ari;
1429 Opcode = NVPTX::STV_i32_v2_ari;
1432 Opcode = NVPTX::STV_i64_v2_ari;
1435 Opcode = NVPTX::STV_f32_v2_ari;
1438 Opcode = NVPTX::STV_f64_v2_ari;
1442 case NVPTXISD::StoreV4:
1443 switch (EltVT.getSimpleVT().SimpleTy) {
1447 Opcode = NVPTX::STV_i8_v4_ari;
1450 Opcode = NVPTX::STV_i16_v4_ari;
1453 Opcode = NVPTX::STV_i32_v4_ari;
1456 Opcode = NVPTX::STV_f32_v4_ari;
1462 StOps.push_back(Base);
1463 StOps.push_back(Offset);
1465 if (Subtarget.is64Bit()) {
1466 switch (N->getOpcode()) {
1469 case NVPTXISD::StoreV2:
1470 switch (EltVT.getSimpleVT().SimpleTy) {
1474 Opcode = NVPTX::STV_i8_v2_areg_64;
1477 Opcode = NVPTX::STV_i16_v2_areg_64;
1480 Opcode = NVPTX::STV_i32_v2_areg_64;
1483 Opcode = NVPTX::STV_i64_v2_areg_64;
1486 Opcode = NVPTX::STV_f32_v2_areg_64;
1489 Opcode = NVPTX::STV_f64_v2_areg_64;
1493 case NVPTXISD::StoreV4:
1494 switch (EltVT.getSimpleVT().SimpleTy) {
1498 Opcode = NVPTX::STV_i8_v4_areg_64;
1501 Opcode = NVPTX::STV_i16_v4_areg_64;
1504 Opcode = NVPTX::STV_i32_v4_areg_64;
1507 Opcode = NVPTX::STV_f32_v4_areg_64;
1513 switch (N->getOpcode()) {
1516 case NVPTXISD::StoreV2:
1517 switch (EltVT.getSimpleVT().SimpleTy) {
1521 Opcode = NVPTX::STV_i8_v2_areg;
1524 Opcode = NVPTX::STV_i16_v2_areg;
1527 Opcode = NVPTX::STV_i32_v2_areg;
1530 Opcode = NVPTX::STV_i64_v2_areg;
1533 Opcode = NVPTX::STV_f32_v2_areg;
1536 Opcode = NVPTX::STV_f64_v2_areg;
1540 case NVPTXISD::StoreV4:
1541 switch (EltVT.getSimpleVT().SimpleTy) {
1545 Opcode = NVPTX::STV_i8_v4_areg;
1548 Opcode = NVPTX::STV_i16_v4_areg;
1551 Opcode = NVPTX::STV_i32_v4_areg;
1554 Opcode = NVPTX::STV_f32_v4_areg;
1560 StOps.push_back(N2);
1563 StOps.push_back(Chain);
1565 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
1567 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1568 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1569 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1574 // SelectDirectAddr - Match a direct address for DAG.
1575 // A direct address could be a globaladdress or externalsymbol.
1576 bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
1577 // Return true if TGA or ES.
1578 if (N.getOpcode() == ISD::TargetGlobalAddress ||
1579 N.getOpcode() == ISD::TargetExternalSymbol) {
1583 if (N.getOpcode() == NVPTXISD::Wrapper) {
1584 Address = N.getOperand(0);
1587 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
1588 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
1589 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
1590 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
1591 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
1597 bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
1598 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1599 if (Addr.getOpcode() == ISD::ADD) {
1600 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1601 SDValue base = Addr.getOperand(0);
1602 if (SelectDirectAddr(base, Base)) {
1603 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1612 bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
1613 SDValue &Base, SDValue &Offset) {
1614 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
1618 bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
1619 SDValue &Base, SDValue &Offset) {
1620 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
1624 bool NVPTXDAGToDAGISel::SelectADDRri_imp(
1625 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1626 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1627 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1628 Offset = CurDAG->getTargetConstant(0, mvt);
1631 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1632 Addr.getOpcode() == ISD::TargetGlobalAddress)
1633 return false; // direct calls.
1635 if (Addr.getOpcode() == ISD::ADD) {
1636 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
1639 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1640 if (FrameIndexSDNode *FIN =
1641 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
1642 // Constant offset from frame ref.
1643 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1645 Base = Addr.getOperand(0);
1646 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1654 bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
1655 SDValue &Base, SDValue &Offset) {
1656 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
1660 bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
1661 SDValue &Base, SDValue &Offset) {
1662 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
1665 bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
1666 unsigned int spN) const {
1667 const Value *Src = NULL;
1668 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
1669 // the classof() for MemSDNode does not include MemIntrinsicSDNode
1670 // (See SelectionDAGNodes.h). So we need to check for both.
1671 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
1672 Src = mN->getSrcValue();
1673 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
1674 Src = mN->getSrcValue();
1678 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
1679 return (PT->getAddressSpace() == spN);
1683 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
1684 /// inline asm expressions.
1685 bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
1686 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
1688 switch (ConstraintCode) {
1692 if (SelectDirectAddr(Op, Op0)) {
1693 OutOps.push_back(Op0);
1694 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
1697 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
1698 OutOps.push_back(Op0);
1699 OutOps.push_back(Op1);
1707 // Return true if N is a undef or a constant.
1708 // If N was undef, return a (i8imm 0) in Retval
1709 // If N was imm, convert it to i8imm and return in Retval
1710 // Note: The convert to i8imm is required, otherwise the
1711 // pattern matcher inserts a bunch of IMOVi8rr to convert
1712 // the imm to i8imm, and this causes instruction selection
1714 bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
1715 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
1718 if (N.getOpcode() == ISD::UNDEF)
1719 Retval = CurDAG->getTargetConstant(0, MVT::i8);
1721 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
1722 unsigned retval = cn->getZExtValue();
1723 Retval = CurDAG->getTargetConstant(retval, MVT::i8);