1 //===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// \brief Custom DAG lowering for R600 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "R600ISelLowering.h" 16 #include "AMDGPUFrameLowering.h" 17 #include "AMDGPUIntrinsicInfo.h" 18 #include "AMDGPUSubtarget.h" 19 #include "R600Defines.h" 20 #include "R600InstrInfo.h" 21 #include "R600MachineFunctionInfo.h" 22 #include "llvm/Analysis/ValueTracking.h" 23 #include "llvm/CodeGen/CallingConvLower.h" 24 #include "llvm/CodeGen/MachineFrameInfo.h" 25 #include "llvm/CodeGen/MachineInstrBuilder.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 #include "llvm/CodeGen/SelectionDAG.h" 28 #include "llvm/IR/Argument.h" 29 #include "llvm/IR/Function.h" 30 31 using namespace llvm; 32 33 R600TargetLowering::R600TargetLowering(TargetMachine &TM, 34 const AMDGPUSubtarget &STI) 35 : AMDGPUTargetLowering(TM, STI), Gen(STI.getGeneration()) { 36 addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass); 37 addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass); 38 addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass); 39 addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass); 40 addRegisterClass(MVT::v2f32, &AMDGPU::R600_Reg64RegClass); 41 addRegisterClass(MVT::v2i32, &AMDGPU::R600_Reg64RegClass); 42 43 computeRegisterProperties(STI.getRegisterInfo()); 44 45 // Set condition code actions 46 setCondCodeAction(ISD::SETO, MVT::f32, Expand); 47 setCondCodeAction(ISD::SETUO, MVT::f32, Expand); 48 setCondCodeAction(ISD::SETLT, MVT::f32, Expand); 49 setCondCodeAction(ISD::SETLE, MVT::f32, Expand); 50 setCondCodeAction(ISD::SETOLT, MVT::f32, Expand); 51 setCondCodeAction(ISD::SETOLE, MVT::f32, Expand); 52 setCondCodeAction(ISD::SETONE, MVT::f32, Expand); 53 setCondCodeAction(ISD::SETUEQ, MVT::f32, Expand); 54 setCondCodeAction(ISD::SETUGE, MVT::f32, Expand); 55 setCondCodeAction(ISD::SETUGT, MVT::f32, Expand); 56 setCondCodeAction(ISD::SETULT, MVT::f32, Expand); 57 setCondCodeAction(ISD::SETULE, MVT::f32, Expand); 58 59 setCondCodeAction(ISD::SETLE, MVT::i32, Expand); 60 setCondCodeAction(ISD::SETLT, MVT::i32, Expand); 61 setCondCodeAction(ISD::SETULE, MVT::i32, Expand); 62 setCondCodeAction(ISD::SETULT, MVT::i32, Expand); 63 64 setOperationAction(ISD::FCOS, MVT::f32, Custom); 65 setOperationAction(ISD::FSIN, MVT::f32, Custom); 66 67 setOperationAction(ISD::SETCC, MVT::v4i32, Expand); 68 setOperationAction(ISD::SETCC, MVT::v2i32, Expand); 69 70 setOperationAction(ISD::BR_CC, MVT::i32, Expand); 71 setOperationAction(ISD::BR_CC, MVT::f32, Expand); 72 setOperationAction(ISD::BRCOND, MVT::Other, Custom); 73 74 setOperationAction(ISD::FSUB, MVT::f32, Expand); 75 76 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 77 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 78 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i1, Custom); 79 80 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 81 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 82 83 setOperationAction(ISD::SETCC, MVT::i32, Expand); 84 setOperationAction(ISD::SETCC, MVT::f32, Expand); 85 setOperationAction(ISD::FP_TO_UINT, MVT::i1, Custom); 86 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 87 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom); 88 89 setOperationAction(ISD::SELECT, MVT::i32, Expand); 90 setOperationAction(ISD::SELECT, MVT::f32, Expand); 91 setOperationAction(ISD::SELECT, MVT::v2i32, Expand); 92 setOperationAction(ISD::SELECT, MVT::v4i32, Expand); 93 94 // ADD, SUB overflow. 95 // TODO: turn these into Legal? 96 if (Subtarget->hasCARRY()) 97 setOperationAction(ISD::UADDO, MVT::i32, Custom); 98 99 if (Subtarget->hasBORROW()) 100 setOperationAction(ISD::USUBO, MVT::i32, Custom); 101 102 // Expand sign extension of vectors 103 if (!Subtarget->hasBFE()) 104 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 105 106 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i1, Expand); 107 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i1, Expand); 108 109 if (!Subtarget->hasBFE()) 110 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); 111 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i8, Expand); 112 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i8, Expand); 113 114 if (!Subtarget->hasBFE()) 115 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 116 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i16, Expand); 117 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i16, Expand); 118 119 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal); 120 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i32, Expand); 121 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i32, Expand); 122 123 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::Other, Expand); 124 125 126 // Legalize loads and stores to the private address space. 127 setOperationAction(ISD::LOAD, MVT::i32, Custom); 128 setOperationAction(ISD::LOAD, MVT::v2i32, Custom); 129 setOperationAction(ISD::LOAD, MVT::v4i32, Custom); 130 131 // EXTLOAD should be the same as ZEXTLOAD. It is legal for some address 132 // spaces, so it is custom lowered to handle those where it isn't. 133 for (MVT VT : MVT::integer_valuetypes()) { 134 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); 135 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Custom); 136 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Custom); 137 138 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote); 139 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i8, Custom); 140 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i16, Custom); 141 142 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); 143 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i8, Custom); 144 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i16, Custom); 145 } 146 147 setOperationAction(ISD::STORE, MVT::i8, Custom); 148 setOperationAction(ISD::STORE, MVT::i32, Custom); 149 setOperationAction(ISD::STORE, MVT::v2i32, Custom); 150 setOperationAction(ISD::STORE, MVT::v4i32, Custom); 151 setTruncStoreAction(MVT::i32, MVT::i8, Custom); 152 setTruncStoreAction(MVT::i32, MVT::i16, Custom); 153 154 setOperationAction(ISD::LOAD, MVT::i32, Custom); 155 setOperationAction(ISD::LOAD, MVT::v4i32, Custom); 156 setOperationAction(ISD::FrameIndex, MVT::i32, Custom); 157 158 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i32, Custom); 159 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2f32, Custom); 160 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Custom); 161 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom); 162 163 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v2i32, Custom); 164 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v2f32, Custom); 165 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Custom); 166 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom); 167 168 setTargetDAGCombine(ISD::FP_ROUND); 169 setTargetDAGCombine(ISD::FP_TO_SINT); 170 setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT); 171 setTargetDAGCombine(ISD::SELECT_CC); 172 setTargetDAGCombine(ISD::INSERT_VECTOR_ELT); 173 174 // We don't have 64-bit shifts. Thus we need either SHX i64 or SHX_PARTS i32 175 // to be Legal/Custom in order to avoid library calls. 176 setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom); 177 setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom); 178 setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom); 179 180 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 181 182 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 }; 183 for (MVT VT : ScalarIntVTs) { 184 setOperationAction(ISD::ADDC, VT, Expand); 185 setOperationAction(ISD::SUBC, VT, Expand); 186 setOperationAction(ISD::ADDE, VT, Expand); 187 setOperationAction(ISD::SUBE, VT, Expand); 188 } 189 190 setSchedulingPreference(Sched::Source); 191 } 192 193 static inline bool isEOP(MachineBasicBlock::iterator I) { 194 return std::next(I)->getOpcode() == AMDGPU::RETURN; 195 } 196 197 MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( 198 MachineInstr * MI, MachineBasicBlock * BB) const { 199 MachineFunction * MF = BB->getParent(); 200 MachineRegisterInfo &MRI = MF->getRegInfo(); 201 MachineBasicBlock::iterator I = *MI; 202 const R600InstrInfo *TII = 203 static_cast<const R600InstrInfo *>(Subtarget->getInstrInfo()); 204 205 switch (MI->getOpcode()) { 206 default: 207 // Replace LDS_*_RET instruction that don't have any uses with the 208 // equivalent LDS_*_NORET instruction. 209 if (TII->isLDSRetInstr(MI->getOpcode())) { 210 int DstIdx = TII->getOperandIdx(MI->getOpcode(), AMDGPU::OpName::dst); 211 assert(DstIdx != -1); 212 MachineInstrBuilder NewMI; 213 // FIXME: getLDSNoRetOp method only handles LDS_1A1D LDS ops. Add 214 // LDS_1A2D support and remove this special case. 215 if (!MRI.use_empty(MI->getOperand(DstIdx).getReg()) || 216 MI->getOpcode() == AMDGPU::LDS_CMPST_RET) 217 return BB; 218 219 NewMI = BuildMI(*BB, I, BB->findDebugLoc(I), 220 TII->get(AMDGPU::getLDSNoRetOp(MI->getOpcode()))); 221 for (unsigned i = 1, e = MI->getNumOperands(); i < e; ++i) { 222 NewMI.addOperand(MI->getOperand(i)); 223 } 224 } else { 225 return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB); 226 } 227 break; 228 case AMDGPU::CLAMP_R600: { 229 MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 230 AMDGPU::MOV, 231 MI->getOperand(0).getReg(), 232 MI->getOperand(1).getReg()); 233 TII->addFlag(NewMI, 0, MO_FLAG_CLAMP); 234 break; 235 } 236 237 case AMDGPU::FABS_R600: { 238 MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 239 AMDGPU::MOV, 240 MI->getOperand(0).getReg(), 241 MI->getOperand(1).getReg()); 242 TII->addFlag(NewMI, 0, MO_FLAG_ABS); 243 break; 244 } 245 246 case AMDGPU::FNEG_R600: { 247 MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 248 AMDGPU::MOV, 249 MI->getOperand(0).getReg(), 250 MI->getOperand(1).getReg()); 251 TII->addFlag(NewMI, 0, MO_FLAG_NEG); 252 break; 253 } 254 255 case AMDGPU::MASK_WRITE: { 256 unsigned maskedRegister = MI->getOperand(0).getReg(); 257 assert(TargetRegisterInfo::isVirtualRegister(maskedRegister)); 258 MachineInstr * defInstr = MRI.getVRegDef(maskedRegister); 259 TII->addFlag(defInstr, 0, MO_FLAG_MASK); 260 break; 261 } 262 263 case AMDGPU::MOV_IMM_F32: 264 TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(), 265 MI->getOperand(1).getFPImm()->getValueAPF() 266 .bitcastToAPInt().getZExtValue()); 267 break; 268 case AMDGPU::MOV_IMM_I32: 269 TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(), 270 MI->getOperand(1).getImm()); 271 break; 272 case AMDGPU::CONST_COPY: { 273 MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, MI, AMDGPU::MOV, 274 MI->getOperand(0).getReg(), AMDGPU::ALU_CONST); 275 TII->setImmOperand(NewMI, AMDGPU::OpName::src0_sel, 276 MI->getOperand(1).getImm()); 277 break; 278 } 279 280 case AMDGPU::RAT_WRITE_CACHELESS_32_eg: 281 case AMDGPU::RAT_WRITE_CACHELESS_64_eg: 282 case AMDGPU::RAT_WRITE_CACHELESS_128_eg: { 283 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode())) 284 .addOperand(MI->getOperand(0)) 285 .addOperand(MI->getOperand(1)) 286 .addImm(isEOP(I)); // Set End of program bit 287 break; 288 } 289 case AMDGPU::RAT_STORE_TYPED_eg: { 290 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode())) 291 .addOperand(MI->getOperand(0)) 292 .addOperand(MI->getOperand(1)) 293 .addOperand(MI->getOperand(2)) 294 .addImm(isEOP(I)); // Set End of program bit 295 break; 296 } 297 298 case AMDGPU::TXD: { 299 unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 300 unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 301 MachineOperand &RID = MI->getOperand(4); 302 MachineOperand &SID = MI->getOperand(5); 303 unsigned TextureId = MI->getOperand(6).getImm(); 304 unsigned SrcX = 0, SrcY = 1, SrcZ = 2, SrcW = 3; 305 unsigned CTX = 1, CTY = 1, CTZ = 1, CTW = 1; 306 307 switch (TextureId) { 308 case 5: // Rect 309 CTX = CTY = 0; 310 break; 311 case 6: // Shadow1D 312 SrcW = SrcZ; 313 break; 314 case 7: // Shadow2D 315 SrcW = SrcZ; 316 break; 317 case 8: // ShadowRect 318 CTX = CTY = 0; 319 SrcW = SrcZ; 320 break; 321 case 9: // 1DArray 322 SrcZ = SrcY; 323 CTZ = 0; 324 break; 325 case 10: // 2DArray 326 CTZ = 0; 327 break; 328 case 11: // Shadow1DArray 329 SrcZ = SrcY; 330 CTZ = 0; 331 break; 332 case 12: // Shadow2DArray 333 CTZ = 0; 334 break; 335 } 336 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0) 337 .addOperand(MI->getOperand(3)) 338 .addImm(SrcX) 339 .addImm(SrcY) 340 .addImm(SrcZ) 341 .addImm(SrcW) 342 .addImm(0) 343 .addImm(0) 344 .addImm(0) 345 .addImm(0) 346 .addImm(1) 347 .addImm(2) 348 .addImm(3) 349 .addOperand(RID) 350 .addOperand(SID) 351 .addImm(CTX) 352 .addImm(CTY) 353 .addImm(CTZ) 354 .addImm(CTW); 355 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1) 356 .addOperand(MI->getOperand(2)) 357 .addImm(SrcX) 358 .addImm(SrcY) 359 .addImm(SrcZ) 360 .addImm(SrcW) 361 .addImm(0) 362 .addImm(0) 363 .addImm(0) 364 .addImm(0) 365 .addImm(1) 366 .addImm(2) 367 .addImm(3) 368 .addOperand(RID) 369 .addOperand(SID) 370 .addImm(CTX) 371 .addImm(CTY) 372 .addImm(CTZ) 373 .addImm(CTW); 374 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_G)) 375 .addOperand(MI->getOperand(0)) 376 .addOperand(MI->getOperand(1)) 377 .addImm(SrcX) 378 .addImm(SrcY) 379 .addImm(SrcZ) 380 .addImm(SrcW) 381 .addImm(0) 382 .addImm(0) 383 .addImm(0) 384 .addImm(0) 385 .addImm(1) 386 .addImm(2) 387 .addImm(3) 388 .addOperand(RID) 389 .addOperand(SID) 390 .addImm(CTX) 391 .addImm(CTY) 392 .addImm(CTZ) 393 .addImm(CTW) 394 .addReg(T0, RegState::Implicit) 395 .addReg(T1, RegState::Implicit); 396 break; 397 } 398 399 case AMDGPU::TXD_SHADOW: { 400 unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 401 unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 402 MachineOperand &RID = MI->getOperand(4); 403 MachineOperand &SID = MI->getOperand(5); 404 unsigned TextureId = MI->getOperand(6).getImm(); 405 unsigned SrcX = 0, SrcY = 1, SrcZ = 2, SrcW = 3; 406 unsigned CTX = 1, CTY = 1, CTZ = 1, CTW = 1; 407 408 switch (TextureId) { 409 case 5: // Rect 410 CTX = CTY = 0; 411 break; 412 case 6: // Shadow1D 413 SrcW = SrcZ; 414 break; 415 case 7: // Shadow2D 416 SrcW = SrcZ; 417 break; 418 case 8: // ShadowRect 419 CTX = CTY = 0; 420 SrcW = SrcZ; 421 break; 422 case 9: // 1DArray 423 SrcZ = SrcY; 424 CTZ = 0; 425 break; 426 case 10: // 2DArray 427 CTZ = 0; 428 break; 429 case 11: // Shadow1DArray 430 SrcZ = SrcY; 431 CTZ = 0; 432 break; 433 case 12: // Shadow2DArray 434 CTZ = 0; 435 break; 436 } 437 438 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0) 439 .addOperand(MI->getOperand(3)) 440 .addImm(SrcX) 441 .addImm(SrcY) 442 .addImm(SrcZ) 443 .addImm(SrcW) 444 .addImm(0) 445 .addImm(0) 446 .addImm(0) 447 .addImm(0) 448 .addImm(1) 449 .addImm(2) 450 .addImm(3) 451 .addOperand(RID) 452 .addOperand(SID) 453 .addImm(CTX) 454 .addImm(CTY) 455 .addImm(CTZ) 456 .addImm(CTW); 457 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1) 458 .addOperand(MI->getOperand(2)) 459 .addImm(SrcX) 460 .addImm(SrcY) 461 .addImm(SrcZ) 462 .addImm(SrcW) 463 .addImm(0) 464 .addImm(0) 465 .addImm(0) 466 .addImm(0) 467 .addImm(1) 468 .addImm(2) 469 .addImm(3) 470 .addOperand(RID) 471 .addOperand(SID) 472 .addImm(CTX) 473 .addImm(CTY) 474 .addImm(CTZ) 475 .addImm(CTW); 476 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_C_G)) 477 .addOperand(MI->getOperand(0)) 478 .addOperand(MI->getOperand(1)) 479 .addImm(SrcX) 480 .addImm(SrcY) 481 .addImm(SrcZ) 482 .addImm(SrcW) 483 .addImm(0) 484 .addImm(0) 485 .addImm(0) 486 .addImm(0) 487 .addImm(1) 488 .addImm(2) 489 .addImm(3) 490 .addOperand(RID) 491 .addOperand(SID) 492 .addImm(CTX) 493 .addImm(CTY) 494 .addImm(CTZ) 495 .addImm(CTW) 496 .addReg(T0, RegState::Implicit) 497 .addReg(T1, RegState::Implicit); 498 break; 499 } 500 501 case AMDGPU::BRANCH: 502 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 503 .addOperand(MI->getOperand(0)); 504 break; 505 506 case AMDGPU::BRANCH_COND_f32: { 507 MachineInstr *NewMI = 508 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X), 509 AMDGPU::PREDICATE_BIT) 510 .addOperand(MI->getOperand(1)) 511 .addImm(OPCODE_IS_NOT_ZERO) 512 .addImm(0); // Flags 513 TII->addFlag(NewMI, 0, MO_FLAG_PUSH); 514 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP_COND)) 515 .addOperand(MI->getOperand(0)) 516 .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 517 break; 518 } 519 520 case AMDGPU::BRANCH_COND_i32: { 521 MachineInstr *NewMI = 522 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X), 523 AMDGPU::PREDICATE_BIT) 524 .addOperand(MI->getOperand(1)) 525 .addImm(OPCODE_IS_NOT_ZERO_INT) 526 .addImm(0); // Flags 527 TII->addFlag(NewMI, 0, MO_FLAG_PUSH); 528 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP_COND)) 529 .addOperand(MI->getOperand(0)) 530 .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 531 break; 532 } 533 534 case AMDGPU::EG_ExportSwz: 535 case AMDGPU::R600_ExportSwz: { 536 // Instruction is left unmodified if its not the last one of its type 537 bool isLastInstructionOfItsType = true; 538 unsigned InstExportType = MI->getOperand(1).getImm(); 539 for (MachineBasicBlock::iterator NextExportInst = std::next(I), 540 EndBlock = BB->end(); NextExportInst != EndBlock; 541 NextExportInst = std::next(NextExportInst)) { 542 if (NextExportInst->getOpcode() == AMDGPU::EG_ExportSwz || 543 NextExportInst->getOpcode() == AMDGPU::R600_ExportSwz) { 544 unsigned CurrentInstExportType = NextExportInst->getOperand(1) 545 .getImm(); 546 if (CurrentInstExportType == InstExportType) { 547 isLastInstructionOfItsType = false; 548 break; 549 } 550 } 551 } 552 bool EOP = isEOP(I); 553 if (!EOP && !isLastInstructionOfItsType) 554 return BB; 555 unsigned CfInst = (MI->getOpcode() == AMDGPU::EG_ExportSwz)? 84 : 40; 556 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode())) 557 .addOperand(MI->getOperand(0)) 558 .addOperand(MI->getOperand(1)) 559 .addOperand(MI->getOperand(2)) 560 .addOperand(MI->getOperand(3)) 561 .addOperand(MI->getOperand(4)) 562 .addOperand(MI->getOperand(5)) 563 .addOperand(MI->getOperand(6)) 564 .addImm(CfInst) 565 .addImm(EOP); 566 break; 567 } 568 case AMDGPU::RETURN: { 569 // RETURN instructions must have the live-out registers as implicit uses, 570 // otherwise they appear dead. 571 R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>(); 572 MachineInstrBuilder MIB(*MF, MI); 573 for (unsigned i = 0, e = MFI->LiveOuts.size(); i != e; ++i) 574 MIB.addReg(MFI->LiveOuts[i], RegState::Implicit); 575 return BB; 576 } 577 } 578 579 MI->eraseFromParent(); 580 return BB; 581 } 582 583 //===----------------------------------------------------------------------===// 584 // Custom DAG Lowering Operations 585 //===----------------------------------------------------------------------===// 586 587 SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 588 MachineFunction &MF = DAG.getMachineFunction(); 589 R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); 590 switch (Op.getOpcode()) { 591 default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); 592 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); 593 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG); 594 case ISD::SHL_PARTS: return LowerSHLParts(Op, DAG); 595 case ISD::SRA_PARTS: 596 case ISD::SRL_PARTS: return LowerSRXParts(Op, DAG); 597 case ISD::UADDO: return LowerUADDSUBO(Op, DAG, ISD::ADD, AMDGPUISD::CARRY); 598 case ISD::USUBO: return LowerUADDSUBO(Op, DAG, ISD::SUB, AMDGPUISD::BORROW); 599 case ISD::FCOS: 600 case ISD::FSIN: return LowerTrig(Op, DAG); 601 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 602 case ISD::STORE: return LowerSTORE(Op, DAG); 603 case ISD::LOAD: { 604 SDValue Result = LowerLOAD(Op, DAG); 605 assert((!Result.getNode() || 606 Result.getNode()->getNumValues() == 2) && 607 "Load should return a value and a chain"); 608 return Result; 609 } 610 611 case ISD::BRCOND: return LowerBRCOND(Op, DAG); 612 case ISD::GlobalAddress: return LowerGlobalAddress(MFI, Op, DAG); 613 case ISD::INTRINSIC_VOID: { 614 SDValue Chain = Op.getOperand(0); 615 unsigned IntrinsicID = 616 cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 617 switch (IntrinsicID) { 618 case AMDGPUIntrinsic::R600_store_swizzle: { 619 SDLoc DL(Op); 620 const SDValue Args[8] = { 621 Chain, 622 Op.getOperand(2), // Export Value 623 Op.getOperand(3), // ArrayBase 624 Op.getOperand(4), // Type 625 DAG.getConstant(0, DL, MVT::i32), // SWZ_X 626 DAG.getConstant(1, DL, MVT::i32), // SWZ_Y 627 DAG.getConstant(2, DL, MVT::i32), // SWZ_Z 628 DAG.getConstant(3, DL, MVT::i32) // SWZ_W 629 }; 630 return DAG.getNode(AMDGPUISD::EXPORT, DL, Op.getValueType(), Args); 631 } 632 633 // default for switch(IntrinsicID) 634 default: break; 635 } 636 // break out of case ISD::INTRINSIC_VOID in switch(Op.getOpcode()) 637 break; 638 } 639 case ISD::INTRINSIC_WO_CHAIN: { 640 unsigned IntrinsicID = 641 cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 642 EVT VT = Op.getValueType(); 643 SDLoc DL(Op); 644 switch(IntrinsicID) { 645 default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); 646 case AMDGPUIntrinsic::R600_interp_xy: 647 case AMDGPUIntrinsic::R600_interp_zw: { 648 int slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 649 MachineSDNode *interp; 650 SDValue RegisterINode = Op.getOperand(2); 651 SDValue RegisterJNode = Op.getOperand(3); 652 653 if (IntrinsicID == AMDGPUIntrinsic::R600_interp_xy) 654 interp = DAG.getMachineNode(AMDGPU::INTERP_PAIR_XY, DL, 655 MVT::f32, MVT::f32, DAG.getTargetConstant(slot, DL, MVT::i32), 656 RegisterJNode, RegisterINode); 657 else 658 interp = DAG.getMachineNode(AMDGPU::INTERP_PAIR_ZW, DL, 659 MVT::f32, MVT::f32, DAG.getTargetConstant(slot, DL, MVT::i32), 660 RegisterJNode, RegisterINode); 661 return DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v2f32, 662 SDValue(interp, 0), SDValue(interp, 1)); 663 } 664 case AMDGPUIntrinsic::r600_tex: 665 case AMDGPUIntrinsic::r600_texc: 666 case AMDGPUIntrinsic::r600_txl: 667 case AMDGPUIntrinsic::r600_txlc: 668 case AMDGPUIntrinsic::r600_txb: 669 case AMDGPUIntrinsic::r600_txbc: 670 case AMDGPUIntrinsic::r600_txf: 671 case AMDGPUIntrinsic::r600_txq: 672 case AMDGPUIntrinsic::r600_ddx: 673 case AMDGPUIntrinsic::r600_ddy: 674 case AMDGPUIntrinsic::R600_ldptr: { 675 unsigned TextureOp; 676 switch (IntrinsicID) { 677 case AMDGPUIntrinsic::r600_tex: 678 TextureOp = 0; 679 break; 680 case AMDGPUIntrinsic::r600_texc: 681 TextureOp = 1; 682 break; 683 case AMDGPUIntrinsic::r600_txl: 684 TextureOp = 2; 685 break; 686 case AMDGPUIntrinsic::r600_txlc: 687 TextureOp = 3; 688 break; 689 case AMDGPUIntrinsic::r600_txb: 690 TextureOp = 4; 691 break; 692 case AMDGPUIntrinsic::r600_txbc: 693 TextureOp = 5; 694 break; 695 case AMDGPUIntrinsic::r600_txf: 696 TextureOp = 6; 697 break; 698 case AMDGPUIntrinsic::r600_txq: 699 TextureOp = 7; 700 break; 701 case AMDGPUIntrinsic::r600_ddx: 702 TextureOp = 8; 703 break; 704 case AMDGPUIntrinsic::r600_ddy: 705 TextureOp = 9; 706 break; 707 case AMDGPUIntrinsic::R600_ldptr: 708 TextureOp = 10; 709 break; 710 default: 711 llvm_unreachable("Unknow Texture Operation"); 712 } 713 714 SDValue TexArgs[19] = { 715 DAG.getConstant(TextureOp, DL, MVT::i32), 716 Op.getOperand(1), 717 DAG.getConstant(0, DL, MVT::i32), 718 DAG.getConstant(1, DL, MVT::i32), 719 DAG.getConstant(2, DL, MVT::i32), 720 DAG.getConstant(3, DL, MVT::i32), 721 Op.getOperand(2), 722 Op.getOperand(3), 723 Op.getOperand(4), 724 DAG.getConstant(0, DL, MVT::i32), 725 DAG.getConstant(1, DL, MVT::i32), 726 DAG.getConstant(2, DL, MVT::i32), 727 DAG.getConstant(3, DL, MVT::i32), 728 Op.getOperand(5), 729 Op.getOperand(6), 730 Op.getOperand(7), 731 Op.getOperand(8), 732 Op.getOperand(9), 733 Op.getOperand(10) 734 }; 735 return DAG.getNode(AMDGPUISD::TEXTURE_FETCH, DL, MVT::v4f32, TexArgs); 736 } 737 case AMDGPUIntrinsic::AMDGPU_dp4: { 738 SDValue Args[8] = { 739 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1), 740 DAG.getConstant(0, DL, MVT::i32)), 741 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2), 742 DAG.getConstant(0, DL, MVT::i32)), 743 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1), 744 DAG.getConstant(1, DL, MVT::i32)), 745 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2), 746 DAG.getConstant(1, DL, MVT::i32)), 747 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1), 748 DAG.getConstant(2, DL, MVT::i32)), 749 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2), 750 DAG.getConstant(2, DL, MVT::i32)), 751 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1), 752 DAG.getConstant(3, DL, MVT::i32)), 753 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2), 754 DAG.getConstant(3, DL, MVT::i32)) 755 }; 756 return DAG.getNode(AMDGPUISD::DOT4, DL, MVT::f32, Args); 757 } 758 759 case Intrinsic::r600_read_ngroups_x: 760 return LowerImplicitParameter(DAG, VT, DL, 0); 761 case Intrinsic::r600_read_ngroups_y: 762 return LowerImplicitParameter(DAG, VT, DL, 1); 763 case Intrinsic::r600_read_ngroups_z: 764 return LowerImplicitParameter(DAG, VT, DL, 2); 765 case Intrinsic::r600_read_global_size_x: 766 return LowerImplicitParameter(DAG, VT, DL, 3); 767 case Intrinsic::r600_read_global_size_y: 768 return LowerImplicitParameter(DAG, VT, DL, 4); 769 case Intrinsic::r600_read_global_size_z: 770 return LowerImplicitParameter(DAG, VT, DL, 5); 771 case Intrinsic::r600_read_local_size_x: 772 return LowerImplicitParameter(DAG, VT, DL, 6); 773 case Intrinsic::r600_read_local_size_y: 774 return LowerImplicitParameter(DAG, VT, DL, 7); 775 case Intrinsic::r600_read_local_size_z: 776 return LowerImplicitParameter(DAG, VT, DL, 8); 777 778 case Intrinsic::r600_read_workdim: 779 case AMDGPUIntrinsic::AMDGPU_read_workdim: { // Legacy name. 780 uint32_t ByteOffset = getImplicitParameterOffset(MFI, GRID_DIM); 781 return LowerImplicitParameter(DAG, VT, DL, ByteOffset / 4); 782 } 783 784 case Intrinsic::r600_read_tgid_x: 785 return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 786 AMDGPU::T1_X, VT); 787 case Intrinsic::r600_read_tgid_y: 788 return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 789 AMDGPU::T1_Y, VT); 790 case Intrinsic::r600_read_tgid_z: 791 return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 792 AMDGPU::T1_Z, VT); 793 case Intrinsic::r600_read_tidig_x: 794 return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 795 AMDGPU::T0_X, VT); 796 case Intrinsic::r600_read_tidig_y: 797 return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 798 AMDGPU::T0_Y, VT); 799 case Intrinsic::r600_read_tidig_z: 800 return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 801 AMDGPU::T0_Z, VT); 802 803 // FIXME: Should be renamed to r600 prefix 804 case AMDGPUIntrinsic::AMDGPU_rsq_clamped: 805 return DAG.getNode(AMDGPUISD::RSQ_CLAMP, DL, VT, Op.getOperand(1)); 806 807 case Intrinsic::r600_rsq: 808 case AMDGPUIntrinsic::AMDGPU_rsq: // Legacy name 809 // XXX - I'm assuming SI's RSQ_LEGACY matches R600's behavior. 810 return DAG.getNode(AMDGPUISD::RSQ_LEGACY, DL, VT, Op.getOperand(1)); 811 } 812 // break out of case ISD::INTRINSIC_WO_CHAIN in switch(Op.getOpcode()) 813 break; 814 } 815 } // end switch(Op.getOpcode()) 816 return SDValue(); 817 } 818 819 void R600TargetLowering::ReplaceNodeResults(SDNode *N, 820 SmallVectorImpl<SDValue> &Results, 821 SelectionDAG &DAG) const { 822 switch (N->getOpcode()) { 823 default: 824 AMDGPUTargetLowering::ReplaceNodeResults(N, Results, DAG); 825 return; 826 case ISD::FP_TO_UINT: 827 if (N->getValueType(0) == MVT::i1) { 828 Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG)); 829 return; 830 } 831 // Fall-through. Since we don't care about out of bounds values 832 // we can use FP_TO_SINT for uints too. The DAGLegalizer code for uint 833 // considers some extra cases which are not necessary here. 834 case ISD::FP_TO_SINT: { 835 SDValue Result; 836 if (expandFP_TO_SINT(N, Result, DAG)) 837 Results.push_back(Result); 838 return; 839 } 840 case ISD::SDIVREM: { 841 SDValue Op = SDValue(N, 1); 842 SDValue RES = LowerSDIVREM(Op, DAG); 843 Results.push_back(RES); 844 Results.push_back(RES.getValue(1)); 845 break; 846 } 847 case ISD::UDIVREM: { 848 SDValue Op = SDValue(N, 0); 849 LowerUDIVREM64(Op, DAG, Results); 850 break; 851 } 852 } 853 } 854 855 SDValue R600TargetLowering::vectorToVerticalVector(SelectionDAG &DAG, 856 SDValue Vector) const { 857 858 SDLoc DL(Vector); 859 EVT VecVT = Vector.getValueType(); 860 EVT EltVT = VecVT.getVectorElementType(); 861 SmallVector<SDValue, 8> Args; 862 863 for (unsigned i = 0, e = VecVT.getVectorNumElements(); 864 i != e; ++i) { 865 Args.push_back(DAG.getNode( 866 ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Vector, 867 DAG.getConstant(i, DL, getVectorIdxTy(DAG.getDataLayout())))); 868 } 869 870 return DAG.getNode(AMDGPUISD::BUILD_VERTICAL_VECTOR, DL, VecVT, Args); 871 } 872 873 SDValue R600TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op, 874 SelectionDAG &DAG) const { 875 876 SDLoc DL(Op); 877 SDValue Vector = Op.getOperand(0); 878 SDValue Index = Op.getOperand(1); 879 880 if (isa<ConstantSDNode>(Index) || 881 Vector.getOpcode() == AMDGPUISD::BUILD_VERTICAL_VECTOR) 882 return Op; 883 884 Vector = vectorToVerticalVector(DAG, Vector); 885 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, Op.getValueType(), 886 Vector, Index); 887 } 888 889 SDValue R600TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op, 890 SelectionDAG &DAG) const { 891 SDLoc DL(Op); 892 SDValue Vector = Op.getOperand(0); 893 SDValue Value = Op.getOperand(1); 894 SDValue Index = Op.getOperand(2); 895 896 if (isa<ConstantSDNode>(Index) || 897 Vector.getOpcode() == AMDGPUISD::BUILD_VERTICAL_VECTOR) 898 return Op; 899 900 Vector = vectorToVerticalVector(DAG, Vector); 901 SDValue Insert = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, Op.getValueType(), 902 Vector, Value, Index); 903 return vectorToVerticalVector(DAG, Insert); 904 } 905 906 SDValue R600TargetLowering::LowerTrig(SDValue Op, SelectionDAG &DAG) const { 907 // On hw >= R700, COS/SIN input must be between -1. and 1. 908 // Thus we lower them to TRIG ( FRACT ( x / 2Pi + 0.5) - 0.5) 909 EVT VT = Op.getValueType(); 910 SDValue Arg = Op.getOperand(0); 911 SDLoc DL(Op); 912 913 // TODO: Should this propagate fast-math-flags? 914 SDValue FractPart = DAG.getNode(AMDGPUISD::FRACT, DL, VT, 915 DAG.getNode(ISD::FADD, DL, VT, 916 DAG.getNode(ISD::FMUL, DL, VT, Arg, 917 DAG.getConstantFP(0.15915494309, DL, MVT::f32)), 918 DAG.getConstantFP(0.5, DL, MVT::f32))); 919 unsigned TrigNode; 920 switch (Op.getOpcode()) { 921 case ISD::FCOS: 922 TrigNode = AMDGPUISD::COS_HW; 923 break; 924 case ISD::FSIN: 925 TrigNode = AMDGPUISD::SIN_HW; 926 break; 927 default: 928 llvm_unreachable("Wrong trig opcode"); 929 } 930 SDValue TrigVal = DAG.getNode(TrigNode, DL, VT, 931 DAG.getNode(ISD::FADD, DL, VT, FractPart, 932 DAG.getConstantFP(-0.5, DL, MVT::f32))); 933 if (Gen >= AMDGPUSubtarget::R700) 934 return TrigVal; 935 // On R600 hw, COS/SIN input must be between -Pi and Pi. 936 return DAG.getNode(ISD::FMUL, DL, VT, TrigVal, 937 DAG.getConstantFP(3.14159265359, DL, MVT::f32)); 938 } 939 940 SDValue R600TargetLowering::LowerSHLParts(SDValue Op, SelectionDAG &DAG) const { 941 SDLoc DL(Op); 942 EVT VT = Op.getValueType(); 943 944 SDValue Lo = Op.getOperand(0); 945 SDValue Hi = Op.getOperand(1); 946 SDValue Shift = Op.getOperand(2); 947 SDValue Zero = DAG.getConstant(0, DL, VT); 948 SDValue One = DAG.getConstant(1, DL, VT); 949 950 SDValue Width = DAG.getConstant(VT.getSizeInBits(), DL, VT); 951 SDValue Width1 = DAG.getConstant(VT.getSizeInBits() - 1, DL, VT); 952 SDValue BigShift = DAG.getNode(ISD::SUB, DL, VT, Shift, Width); 953 SDValue CompShift = DAG.getNode(ISD::SUB, DL, VT, Width1, Shift); 954 955 // The dance around Width1 is necessary for 0 special case. 956 // Without it the CompShift might be 32, producing incorrect results in 957 // Overflow. So we do the shift in two steps, the alternative is to 958 // add a conditional to filter the special case. 959 960 SDValue Overflow = DAG.getNode(ISD::SRL, DL, VT, Lo, CompShift); 961 Overflow = DAG.getNode(ISD::SRL, DL, VT, Overflow, One); 962 963 SDValue HiSmall = DAG.getNode(ISD::SHL, DL, VT, Hi, Shift); 964 HiSmall = DAG.getNode(ISD::OR, DL, VT, HiSmall, Overflow); 965 SDValue LoSmall = DAG.getNode(ISD::SHL, DL, VT, Lo, Shift); 966 967 SDValue HiBig = DAG.getNode(ISD::SHL, DL, VT, Lo, BigShift); 968 SDValue LoBig = Zero; 969 970 Hi = DAG.getSelectCC(DL, Shift, Width, HiSmall, HiBig, ISD::SETULT); 971 Lo = DAG.getSelectCC(DL, Shift, Width, LoSmall, LoBig, ISD::SETULT); 972 973 return DAG.getNode(ISD::MERGE_VALUES, DL, DAG.getVTList(VT,VT), Lo, Hi); 974 } 975 976 SDValue R600TargetLowering::LowerSRXParts(SDValue Op, SelectionDAG &DAG) const { 977 SDLoc DL(Op); 978 EVT VT = Op.getValueType(); 979 980 SDValue Lo = Op.getOperand(0); 981 SDValue Hi = Op.getOperand(1); 982 SDValue Shift = Op.getOperand(2); 983 SDValue Zero = DAG.getConstant(0, DL, VT); 984 SDValue One = DAG.getConstant(1, DL, VT); 985 986 const bool SRA = Op.getOpcode() == ISD::SRA_PARTS; 987 988 SDValue Width = DAG.getConstant(VT.getSizeInBits(), DL, VT); 989 SDValue Width1 = DAG.getConstant(VT.getSizeInBits() - 1, DL, VT); 990 SDValue BigShift = DAG.getNode(ISD::SUB, DL, VT, Shift, Width); 991 SDValue CompShift = DAG.getNode(ISD::SUB, DL, VT, Width1, Shift); 992 993 // The dance around Width1 is necessary for 0 special case. 994 // Without it the CompShift might be 32, producing incorrect results in 995 // Overflow. So we do the shift in two steps, the alternative is to 996 // add a conditional to filter the special case. 997 998 SDValue Overflow = DAG.getNode(ISD::SHL, DL, VT, Hi, CompShift); 999 Overflow = DAG.getNode(ISD::SHL, DL, VT, Overflow, One); 1000 1001 SDValue HiSmall = DAG.getNode(SRA ? ISD::SRA : ISD::SRL, DL, VT, Hi, Shift); 1002 SDValue LoSmall = DAG.getNode(ISD::SRL, DL, VT, Lo, Shift); 1003 LoSmall = DAG.getNode(ISD::OR, DL, VT, LoSmall, Overflow); 1004 1005 SDValue LoBig = DAG.getNode(SRA ? ISD::SRA : ISD::SRL, DL, VT, Hi, BigShift); 1006 SDValue HiBig = SRA ? DAG.getNode(ISD::SRA, DL, VT, Hi, Width1) : Zero; 1007 1008 Hi = DAG.getSelectCC(DL, Shift, Width, HiSmall, HiBig, ISD::SETULT); 1009 Lo = DAG.getSelectCC(DL, Shift, Width, LoSmall, LoBig, ISD::SETULT); 1010 1011 return DAG.getNode(ISD::MERGE_VALUES, DL, DAG.getVTList(VT,VT), Lo, Hi); 1012 } 1013 1014 SDValue R600TargetLowering::LowerUADDSUBO(SDValue Op, SelectionDAG &DAG, 1015 unsigned mainop, unsigned ovf) const { 1016 SDLoc DL(Op); 1017 EVT VT = Op.getValueType(); 1018 1019 SDValue Lo = Op.getOperand(0); 1020 SDValue Hi = Op.getOperand(1); 1021 1022 SDValue OVF = DAG.getNode(ovf, DL, VT, Lo, Hi); 1023 // Extend sign. 1024 OVF = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, OVF, 1025 DAG.getValueType(MVT::i1)); 1026 1027 SDValue Res = DAG.getNode(mainop, DL, VT, Lo, Hi); 1028 1029 return DAG.getNode(ISD::MERGE_VALUES, DL, DAG.getVTList(VT, VT), Res, OVF); 1030 } 1031 1032 SDValue R600TargetLowering::LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const { 1033 SDLoc DL(Op); 1034 return DAG.getNode( 1035 ISD::SETCC, 1036 DL, 1037 MVT::i1, 1038 Op, DAG.getConstantFP(0.0f, DL, MVT::f32), 1039 DAG.getCondCode(ISD::SETNE) 1040 ); 1041 } 1042 1043 SDValue R600TargetLowering::LowerImplicitParameter(SelectionDAG &DAG, EVT VT, 1044 SDLoc DL, 1045 unsigned DwordOffset) const { 1046 unsigned ByteOffset = DwordOffset * 4; 1047 PointerType * PtrType = PointerType::get(VT.getTypeForEVT(*DAG.getContext()), 1048 AMDGPUAS::CONSTANT_BUFFER_0); 1049 1050 // We shouldn't be using an offset wider than 16-bits for implicit parameters. 1051 assert(isInt<16>(ByteOffset)); 1052 1053 return DAG.getLoad(VT, DL, DAG.getEntryNode(), 1054 DAG.getConstant(ByteOffset, DL, MVT::i32), // PTR 1055 MachinePointerInfo(ConstantPointerNull::get(PtrType)), 1056 false, false, false, 0); 1057 } 1058 1059 bool R600TargetLowering::isZero(SDValue Op) const { 1060 if(ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Op)) { 1061 return Cst->isNullValue(); 1062 } else if(ConstantFPSDNode *CstFP = dyn_cast<ConstantFPSDNode>(Op)){ 1063 return CstFP->isZero(); 1064 } else { 1065 return false; 1066 } 1067 } 1068 1069 SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { 1070 SDLoc DL(Op); 1071 EVT VT = Op.getValueType(); 1072 1073 SDValue LHS = Op.getOperand(0); 1074 SDValue RHS = Op.getOperand(1); 1075 SDValue True = Op.getOperand(2); 1076 SDValue False = Op.getOperand(3); 1077 SDValue CC = Op.getOperand(4); 1078 SDValue Temp; 1079 1080 if (VT == MVT::f32) { 1081 DAGCombinerInfo DCI(DAG, AfterLegalizeVectorOps, true, nullptr); 1082 SDValue MinMax = CombineFMinMaxLegacy(DL, VT, LHS, RHS, True, False, CC, DCI); 1083 if (MinMax) 1084 return MinMax; 1085 } 1086 1087 // LHS and RHS are guaranteed to be the same value type 1088 EVT CompareVT = LHS.getValueType(); 1089 1090 // Check if we can lower this to a native operation. 1091 1092 // Try to lower to a SET* instruction: 1093 // 1094 // SET* can match the following patterns: 1095 // 1096 // select_cc f32, f32, -1, 0, cc_supported 1097 // select_cc f32, f32, 1.0f, 0.0f, cc_supported 1098 // select_cc i32, i32, -1, 0, cc_supported 1099 // 1100 1101 // Move hardware True/False values to the correct operand. 1102 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 1103 ISD::CondCode InverseCC = 1104 ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32); 1105 if (isHWTrueValue(False) && isHWFalseValue(True)) { 1106 if (isCondCodeLegal(InverseCC, CompareVT.getSimpleVT())) { 1107 std::swap(False, True); 1108 CC = DAG.getCondCode(InverseCC); 1109 } else { 1110 ISD::CondCode SwapInvCC = ISD::getSetCCSwappedOperands(InverseCC); 1111 if (isCondCodeLegal(SwapInvCC, CompareVT.getSimpleVT())) { 1112 std::swap(False, True); 1113 std::swap(LHS, RHS); 1114 CC = DAG.getCondCode(SwapInvCC); 1115 } 1116 } 1117 } 1118 1119 if (isHWTrueValue(True) && isHWFalseValue(False) && 1120 (CompareVT == VT || VT == MVT::i32)) { 1121 // This can be matched by a SET* instruction. 1122 return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC); 1123 } 1124 1125 // Try to lower to a CND* instruction: 1126 // 1127 // CND* can match the following patterns: 1128 // 1129 // select_cc f32, 0.0, f32, f32, cc_supported 1130 // select_cc f32, 0.0, i32, i32, cc_supported 1131 // select_cc i32, 0, f32, f32, cc_supported 1132 // select_cc i32, 0, i32, i32, cc_supported 1133 // 1134 1135 // Try to move the zero value to the RHS 1136 if (isZero(LHS)) { 1137 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 1138 // Try swapping the operands 1139 ISD::CondCode CCSwapped = ISD::getSetCCSwappedOperands(CCOpcode); 1140 if (isCondCodeLegal(CCSwapped, CompareVT.getSimpleVT())) { 1141 std::swap(LHS, RHS); 1142 CC = DAG.getCondCode(CCSwapped); 1143 } else { 1144 // Try inverting the conditon and then swapping the operands 1145 ISD::CondCode CCInv = ISD::getSetCCInverse(CCOpcode, CompareVT.isInteger()); 1146 CCSwapped = ISD::getSetCCSwappedOperands(CCInv); 1147 if (isCondCodeLegal(CCSwapped, CompareVT.getSimpleVT())) { 1148 std::swap(True, False); 1149 std::swap(LHS, RHS); 1150 CC = DAG.getCondCode(CCSwapped); 1151 } 1152 } 1153 } 1154 if (isZero(RHS)) { 1155 SDValue Cond = LHS; 1156 SDValue Zero = RHS; 1157 ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 1158 if (CompareVT != VT) { 1159 // Bitcast True / False to the correct types. This will end up being 1160 // a nop, but it allows us to define only a single pattern in the 1161 // .TD files for each CND* instruction rather than having to have 1162 // one pattern for integer True/False and one for fp True/False 1163 True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True); 1164 False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False); 1165 } 1166 1167 switch (CCOpcode) { 1168 case ISD::SETONE: 1169 case ISD::SETUNE: 1170 case ISD::SETNE: 1171 CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32); 1172 Temp = True; 1173 True = False; 1174 False = Temp; 1175 break; 1176 default: 1177 break; 1178 } 1179 SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, 1180 Cond, Zero, 1181 True, False, 1182 DAG.getCondCode(CCOpcode)); 1183 return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode); 1184 } 1185 1186 // If we make it this for it means we have no native instructions to handle 1187 // this SELECT_CC, so we must lower it. 1188 SDValue HWTrue, HWFalse; 1189 1190 if (CompareVT == MVT::f32) { 1191 HWTrue = DAG.getConstantFP(1.0f, DL, CompareVT); 1192 HWFalse = DAG.getConstantFP(0.0f, DL, CompareVT); 1193 } else if (CompareVT == MVT::i32) { 1194 HWTrue = DAG.getConstant(-1, DL, CompareVT); 1195 HWFalse = DAG.getConstant(0, DL, CompareVT); 1196 } 1197 else { 1198 llvm_unreachable("Unhandled value type in LowerSELECT_CC"); 1199 } 1200 1201 // Lower this unsupported SELECT_CC into a combination of two supported 1202 // SELECT_CC operations. 1203 SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, LHS, RHS, HWTrue, HWFalse, CC); 1204 1205 return DAG.getNode(ISD::SELECT_CC, DL, VT, 1206 Cond, HWFalse, 1207 True, False, 1208 DAG.getCondCode(ISD::SETNE)); 1209 } 1210 1211 /// LLVM generates byte-addressed pointers. For indirect addressing, we need to 1212 /// convert these pointers to a register index. Each register holds 1213 /// 16 bytes, (4 x 32bit sub-register), but we need to take into account the 1214 /// \p StackWidth, which tells us how many of the 4 sub-registrers will be used 1215 /// for indirect addressing. 1216 SDValue R600TargetLowering::stackPtrToRegIndex(SDValue Ptr, 1217 unsigned StackWidth, 1218 SelectionDAG &DAG) const { 1219 unsigned SRLPad; 1220 switch(StackWidth) { 1221 case 1: 1222 SRLPad = 2; 1223 break; 1224 case 2: 1225 SRLPad = 3; 1226 break; 1227 case 4: 1228 SRLPad = 4; 1229 break; 1230 default: llvm_unreachable("Invalid stack width"); 1231 } 1232 1233 SDLoc DL(Ptr); 1234 return DAG.getNode(ISD::SRL, DL, Ptr.getValueType(), Ptr, 1235 DAG.getConstant(SRLPad, DL, MVT::i32)); 1236 } 1237 1238 void R600TargetLowering::getStackAddress(unsigned StackWidth, 1239 unsigned ElemIdx, 1240 unsigned &Channel, 1241 unsigned &PtrIncr) const { 1242 switch (StackWidth) { 1243 default: 1244 case 1: 1245 Channel = 0; 1246 if (ElemIdx > 0) { 1247 PtrIncr = 1; 1248 } else { 1249 PtrIncr = 0; 1250 } 1251 break; 1252 case 2: 1253 Channel = ElemIdx % 2; 1254 if (ElemIdx == 2) { 1255 PtrIncr = 1; 1256 } else { 1257 PtrIncr = 0; 1258 } 1259 break; 1260 case 4: 1261 Channel = ElemIdx; 1262 PtrIncr = 0; 1263 break; 1264 } 1265 } 1266 1267 SDValue R600TargetLowering::lowerPrivateTruncStore(StoreSDNode *Store, 1268 SelectionDAG &DAG) const { 1269 SDLoc DL(Store); 1270 1271 unsigned Mask = 0; 1272 if (Store->getMemoryVT() == MVT::i8) { 1273 Mask = 0xff; 1274 } else if (Store->getMemoryVT() == MVT::i16) { 1275 Mask = 0xffff; 1276 } 1277 1278 SDValue Chain = Store->getChain(); 1279 SDValue BasePtr = Store->getBasePtr(); 1280 EVT MemVT = Store->getMemoryVT(); 1281 1282 SDValue Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, BasePtr, 1283 DAG.getConstant(2, DL, MVT::i32)); 1284 SDValue Dst = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, MVT::i32, 1285 Chain, Ptr, 1286 DAG.getTargetConstant(0, DL, MVT::i32)); 1287 1288 SDValue ByteIdx = DAG.getNode(ISD::AND, DL, MVT::i32, BasePtr, 1289 DAG.getConstant(0x3, DL, MVT::i32)); 1290 1291 SDValue ShiftAmt = DAG.getNode(ISD::SHL, DL, MVT::i32, ByteIdx, 1292 DAG.getConstant(3, DL, MVT::i32)); 1293 1294 SDValue SExtValue = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i32, 1295 Store->getValue()); 1296 1297 SDValue MaskedValue = DAG.getZeroExtendInReg(SExtValue, DL, MemVT); 1298 1299 SDValue ShiftedValue = DAG.getNode(ISD::SHL, DL, MVT::i32, 1300 MaskedValue, ShiftAmt); 1301 1302 SDValue DstMask = DAG.getNode(ISD::SHL, DL, MVT::i32, 1303 DAG.getConstant(Mask, DL, MVT::i32), 1304 ShiftAmt); 1305 DstMask = DAG.getNode(ISD::XOR, DL, MVT::i32, DstMask, 1306 DAG.getConstant(0xffffffff, DL, MVT::i32)); 1307 Dst = DAG.getNode(ISD::AND, DL, MVT::i32, Dst, DstMask); 1308 1309 SDValue Value = DAG.getNode(ISD::OR, DL, MVT::i32, Dst, ShiftedValue); 1310 return DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, 1311 Chain, Value, Ptr, 1312 DAG.getTargetConstant(0, DL, MVT::i32)); 1313 } 1314 1315 SDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const { 1316 if (SDValue Result = AMDGPUTargetLowering::MergeVectorStore(Op, DAG)) 1317 return Result; 1318 1319 StoreSDNode *StoreNode = cast<StoreSDNode>(Op); 1320 unsigned AS = StoreNode->getAddressSpace(); 1321 SDValue Value = StoreNode->getValue(); 1322 EVT ValueVT = Value.getValueType(); 1323 1324 if ((AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::PRIVATE_ADDRESS) && 1325 ValueVT.isVector()) { 1326 return SplitVectorStore(Op, DAG); 1327 } 1328 1329 SDLoc DL(Op); 1330 SDValue Chain = StoreNode->getChain(); 1331 SDValue Ptr = StoreNode->getBasePtr(); 1332 1333 if (AS == AMDGPUAS::GLOBAL_ADDRESS) { 1334 if (StoreNode->isTruncatingStore()) { 1335 EVT VT = Value.getValueType(); 1336 assert(VT.bitsLE(MVT::i32)); 1337 EVT MemVT = StoreNode->getMemoryVT(); 1338 SDValue MaskConstant; 1339 if (MemVT == MVT::i8) { 1340 MaskConstant = DAG.getConstant(0xFF, DL, MVT::i32); 1341 } else { 1342 assert(MemVT == MVT::i16); 1343 MaskConstant = DAG.getConstant(0xFFFF, DL, MVT::i32); 1344 } 1345 SDValue DWordAddr = DAG.getNode(ISD::SRL, DL, VT, Ptr, 1346 DAG.getConstant(2, DL, MVT::i32)); 1347 SDValue ByteIndex = DAG.getNode(ISD::AND, DL, Ptr.getValueType(), Ptr, 1348 DAG.getConstant(0x00000003, DL, VT)); 1349 SDValue TruncValue = DAG.getNode(ISD::AND, DL, VT, Value, MaskConstant); 1350 SDValue Shift = DAG.getNode(ISD::SHL, DL, VT, ByteIndex, 1351 DAG.getConstant(3, DL, VT)); 1352 SDValue ShiftedValue = DAG.getNode(ISD::SHL, DL, VT, TruncValue, Shift); 1353 SDValue Mask = DAG.getNode(ISD::SHL, DL, VT, MaskConstant, Shift); 1354 // XXX: If we add a 64-bit ZW register class, then we could use a 2 x i32 1355 // vector instead. 1356 SDValue Src[4] = { 1357 ShiftedValue, 1358 DAG.getConstant(0, DL, MVT::i32), 1359 DAG.getConstant(0, DL, MVT::i32), 1360 Mask 1361 }; 1362 SDValue Input = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4i32, Src); 1363 SDValue Args[3] = { Chain, Input, DWordAddr }; 1364 return DAG.getMemIntrinsicNode(AMDGPUISD::STORE_MSKOR, DL, 1365 Op->getVTList(), Args, MemVT, 1366 StoreNode->getMemOperand()); 1367 } else if (Ptr->getOpcode() != AMDGPUISD::DWORDADDR && 1368 ValueVT.bitsGE(MVT::i32)) { 1369 // Convert pointer from byte address to dword address. 1370 Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, Ptr.getValueType(), 1371 DAG.getNode(ISD::SRL, DL, Ptr.getValueType(), 1372 Ptr, DAG.getConstant(2, DL, MVT::i32))); 1373 1374 if (StoreNode->isTruncatingStore() || StoreNode->isIndexed()) { 1375 llvm_unreachable("Truncated and indexed stores not supported yet"); 1376 } else { 1377 Chain = DAG.getStore(Chain, DL, Value, Ptr, StoreNode->getMemOperand()); 1378 } 1379 return Chain; 1380 } 1381 } 1382 1383 if (AS != AMDGPUAS::PRIVATE_ADDRESS) 1384 return SDValue(); 1385 1386 EVT MemVT = StoreNode->getMemoryVT(); 1387 if (MemVT.bitsLT(MVT::i32)) 1388 return lowerPrivateTruncStore(StoreNode, DAG); 1389 1390 // Lowering for indirect addressing 1391 const MachineFunction &MF = DAG.getMachineFunction(); 1392 const AMDGPUFrameLowering *TFL = 1393 static_cast<const AMDGPUFrameLowering *>(Subtarget->getFrameLowering()); 1394 unsigned StackWidth = TFL->getStackWidth(MF); 1395 1396 Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG); 1397 1398 if (ValueVT.isVector()) { 1399 unsigned NumElemVT = ValueVT.getVectorNumElements(); 1400 EVT ElemVT = ValueVT.getVectorElementType(); 1401 SmallVector<SDValue, 4> Stores(NumElemVT); 1402 1403 assert(NumElemVT >= StackWidth && "Stack width cannot be greater than " 1404 "vector width in load"); 1405 1406 for (unsigned i = 0; i < NumElemVT; ++i) { 1407 unsigned Channel, PtrIncr; 1408 getStackAddress(StackWidth, i, Channel, PtrIncr); 1409 Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr, 1410 DAG.getConstant(PtrIncr, DL, MVT::i32)); 1411 SDValue Elem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT, 1412 Value, DAG.getConstant(i, DL, MVT::i32)); 1413 1414 Stores[i] = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, 1415 Chain, Elem, Ptr, 1416 DAG.getTargetConstant(Channel, DL, MVT::i32)); 1417 } 1418 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores); 1419 } else { 1420 if (ValueVT == MVT::i8) { 1421 Value = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Value); 1422 } 1423 Chain = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, Chain, Value, Ptr, 1424 DAG.getTargetConstant(0, DL, MVT::i32)); // Channel 1425 } 1426 1427 return Chain; 1428 } 1429 1430 // return (512 + (kc_bank << 12) 1431 static int 1432 ConstantAddressBlock(unsigned AddressSpace) { 1433 switch (AddressSpace) { 1434 case AMDGPUAS::CONSTANT_BUFFER_0: 1435 return 512; 1436 case AMDGPUAS::CONSTANT_BUFFER_1: 1437 return 512 + 4096; 1438 case AMDGPUAS::CONSTANT_BUFFER_2: 1439 return 512 + 4096 * 2; 1440 case AMDGPUAS::CONSTANT_BUFFER_3: 1441 return 512 + 4096 * 3; 1442 case AMDGPUAS::CONSTANT_BUFFER_4: 1443 return 512 + 4096 * 4; 1444 case AMDGPUAS::CONSTANT_BUFFER_5: 1445 return 512 + 4096 * 5; 1446 case AMDGPUAS::CONSTANT_BUFFER_6: 1447 return 512 + 4096 * 6; 1448 case AMDGPUAS::CONSTANT_BUFFER_7: 1449 return 512 + 4096 * 7; 1450 case AMDGPUAS::CONSTANT_BUFFER_8: 1451 return 512 + 4096 * 8; 1452 case AMDGPUAS::CONSTANT_BUFFER_9: 1453 return 512 + 4096 * 9; 1454 case AMDGPUAS::CONSTANT_BUFFER_10: 1455 return 512 + 4096 * 10; 1456 case AMDGPUAS::CONSTANT_BUFFER_11: 1457 return 512 + 4096 * 11; 1458 case AMDGPUAS::CONSTANT_BUFFER_12: 1459 return 512 + 4096 * 12; 1460 case AMDGPUAS::CONSTANT_BUFFER_13: 1461 return 512 + 4096 * 13; 1462 case AMDGPUAS::CONSTANT_BUFFER_14: 1463 return 512 + 4096 * 14; 1464 case AMDGPUAS::CONSTANT_BUFFER_15: 1465 return 512 + 4096 * 15; 1466 default: 1467 return -1; 1468 } 1469 } 1470 1471 SDValue R600TargetLowering::lowerPrivateExtLoad(SDValue Op, 1472 SelectionDAG &DAG) const { 1473 SDLoc DL(Op); 1474 LoadSDNode *Load = cast<LoadSDNode>(Op); 1475 ISD::LoadExtType ExtType = Load->getExtensionType(); 1476 EVT MemVT = Load->getMemoryVT(); 1477 1478 // <SI && AS=PRIVATE && EXTLOAD && size < 32bit, 1479 // register (2-)byte extract. 1480 1481 // Get Register holding the target. 1482 SDValue Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, Load->getBasePtr(), 1483 DAG.getConstant(2, DL, MVT::i32)); 1484 // Load the Register. 1485 SDValue Ret = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, Op.getValueType(), 1486 Load->getChain(), 1487 Ptr, 1488 DAG.getTargetConstant(0, DL, MVT::i32), 1489 Op.getOperand(2)); 1490 1491 // Get offset within the register. 1492 SDValue ByteIdx = DAG.getNode(ISD::AND, DL, MVT::i32, 1493 Load->getBasePtr(), 1494 DAG.getConstant(0x3, DL, MVT::i32)); 1495 1496 // Bit offset of target byte (byteIdx * 8). 1497 SDValue ShiftAmt = DAG.getNode(ISD::SHL, DL, MVT::i32, ByteIdx, 1498 DAG.getConstant(3, DL, MVT::i32)); 1499 1500 // Shift to the right. 1501 Ret = DAG.getNode(ISD::SRL, DL, MVT::i32, Ret, ShiftAmt); 1502 1503 // Eliminate the upper bits by setting them to ... 1504 EVT MemEltVT = MemVT.getScalarType(); 1505 1506 // ... ones. 1507 if (ExtType == ISD::SEXTLOAD) { 1508 SDValue MemEltVTNode = DAG.getValueType(MemEltVT); 1509 1510 SDValue Ops[] = { 1511 DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32, Ret, MemEltVTNode), 1512 Load->getChain() 1513 }; 1514 1515 return DAG.getMergeValues(Ops, DL); 1516 } 1517 1518 // ... or zeros. 1519 SDValue Ops[] = { 1520 DAG.getZeroExtendInReg(Ret, DL, MemEltVT), 1521 Load->getChain() 1522 }; 1523 1524 return DAG.getMergeValues(Ops, DL); 1525 } 1526 1527 SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const { 1528 LoadSDNode *LoadNode = cast<LoadSDNode>(Op); 1529 unsigned AS = LoadNode->getAddressSpace(); 1530 EVT MemVT = LoadNode->getMemoryVT(); 1531 ISD::LoadExtType ExtType = LoadNode->getExtensionType(); 1532 1533 if (AS == AMDGPUAS::PRIVATE_ADDRESS && 1534 ExtType != ISD::NON_EXTLOAD && MemVT.bitsLT(MVT::i32)) { 1535 return lowerPrivateExtLoad(Op, DAG); 1536 } 1537 1538 SDLoc DL(Op); 1539 EVT VT = Op.getValueType(); 1540 SDValue Chain = LoadNode->getChain(); 1541 SDValue Ptr = LoadNode->getBasePtr(); 1542 1543 // Lower loads constant address space global variable loads 1544 if (LoadNode->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS && 1545 isa<GlobalVariable>(GetUnderlyingObject( 1546 LoadNode->getMemOperand()->getValue(), DAG.getDataLayout()))) { 1547 1548 SDValue Ptr = DAG.getZExtOrTrunc( 1549 LoadNode->getBasePtr(), DL, 1550 getPointerTy(DAG.getDataLayout(), AMDGPUAS::PRIVATE_ADDRESS)); 1551 Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, Ptr, 1552 DAG.getConstant(2, DL, MVT::i32)); 1553 return DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, Op->getVTList(), 1554 LoadNode->getChain(), Ptr, 1555 DAG.getTargetConstant(0, DL, MVT::i32), 1556 Op.getOperand(2)); 1557 } 1558 1559 if (LoadNode->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS && VT.isVector()) { 1560 SDValue MergedValues[2] = { 1561 ScalarizeVectorLoad(Op, DAG), 1562 Chain 1563 }; 1564 return DAG.getMergeValues(MergedValues, DL); 1565 } 1566 1567 int ConstantBlock = ConstantAddressBlock(LoadNode->getAddressSpace()); 1568 if (ConstantBlock > -1 && 1569 ((LoadNode->getExtensionType() == ISD::NON_EXTLOAD) || 1570 (LoadNode->getExtensionType() == ISD::ZEXTLOAD))) { 1571 SDValue Result; 1572 if (isa<ConstantExpr>(LoadNode->getMemOperand()->getValue()) || 1573 isa<Constant>(LoadNode->getMemOperand()->getValue()) || 1574 isa<ConstantSDNode>(Ptr)) { 1575 SDValue Slots[4]; 1576 for (unsigned i = 0; i < 4; i++) { 1577 // We want Const position encoded with the following formula : 1578 // (((512 + (kc_bank << 12) + const_index) << 2) + chan) 1579 // const_index is Ptr computed by llvm using an alignment of 16. 1580 // Thus we add (((512 + (kc_bank << 12)) + chan ) * 4 here and 1581 // then div by 4 at the ISel step 1582 SDValue NewPtr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, 1583 DAG.getConstant(4 * i + ConstantBlock * 16, DL, MVT::i32)); 1584 Slots[i] = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::i32, NewPtr); 1585 } 1586 EVT NewVT = MVT::v4i32; 1587 unsigned NumElements = 4; 1588 if (VT.isVector()) { 1589 NewVT = VT; 1590 NumElements = VT.getVectorNumElements(); 1591 } 1592 Result = DAG.getNode(ISD::BUILD_VECTOR, DL, NewVT, 1593 makeArrayRef(Slots, NumElements)); 1594 } else { 1595 // non-constant ptr can't be folded, keeps it as a v4f32 load 1596 Result = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::v4i32, 1597 DAG.getNode(ISD::SRL, DL, MVT::i32, Ptr, 1598 DAG.getConstant(4, DL, MVT::i32)), 1599 DAG.getConstant(LoadNode->getAddressSpace() - 1600 AMDGPUAS::CONSTANT_BUFFER_0, DL, MVT::i32) 1601 ); 1602 } 1603 1604 if (!VT.isVector()) { 1605 Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, Result, 1606 DAG.getConstant(0, DL, MVT::i32)); 1607 } 1608 1609 SDValue MergedValues[2] = { 1610 Result, 1611 Chain 1612 }; 1613 return DAG.getMergeValues(MergedValues, DL); 1614 } 1615 1616 SDValue LoweredLoad; 1617 1618 // For most operations returning SDValue() will result in the node being 1619 // expanded by the DAG Legalizer. This is not the case for ISD::LOAD, so we 1620 // need to manually expand loads that may be legal in some address spaces and 1621 // illegal in others. SEXT loads from CONSTANT_BUFFER_0 are supported for 1622 // compute shaders, since the data is sign extended when it is uploaded to the 1623 // buffer. However SEXT loads from other address spaces are not supported, so 1624 // we need to expand them here. 1625 if (LoadNode->getExtensionType() == ISD::SEXTLOAD) { 1626 EVT MemVT = LoadNode->getMemoryVT(); 1627 assert(!MemVT.isVector() && (MemVT == MVT::i16 || MemVT == MVT::i8)); 1628 SDValue NewLoad = DAG.getExtLoad(ISD::EXTLOAD, DL, VT, Chain, Ptr, 1629 LoadNode->getPointerInfo(), MemVT, 1630 LoadNode->isVolatile(), 1631 LoadNode->isNonTemporal(), 1632 LoadNode->isInvariant(), 1633 LoadNode->getAlignment()); 1634 SDValue Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, NewLoad, 1635 DAG.getValueType(MemVT)); 1636 1637 SDValue MergedValues[2] = { Res, Chain }; 1638 return DAG.getMergeValues(MergedValues, DL); 1639 } 1640 1641 if (LoadNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) { 1642 return SDValue(); 1643 } 1644 1645 // Lowering for indirect addressing 1646 const MachineFunction &MF = DAG.getMachineFunction(); 1647 const AMDGPUFrameLowering *TFL = 1648 static_cast<const AMDGPUFrameLowering *>(Subtarget->getFrameLowering()); 1649 unsigned StackWidth = TFL->getStackWidth(MF); 1650 1651 Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG); 1652 1653 if (VT.isVector()) { 1654 unsigned NumElemVT = VT.getVectorNumElements(); 1655 EVT ElemVT = VT.getVectorElementType(); 1656 SDValue Loads[4]; 1657 1658 assert(NumElemVT >= StackWidth && "Stack width cannot be greater than " 1659 "vector width in load"); 1660 1661 for (unsigned i = 0; i < NumElemVT; ++i) { 1662 unsigned Channel, PtrIncr; 1663 getStackAddress(StackWidth, i, Channel, PtrIncr); 1664 Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr, 1665 DAG.getConstant(PtrIncr, DL, MVT::i32)); 1666 Loads[i] = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, ElemVT, 1667 Chain, Ptr, 1668 DAG.getTargetConstant(Channel, DL, MVT::i32), 1669 Op.getOperand(2)); 1670 } 1671 for (unsigned i = NumElemVT; i < 4; ++i) { 1672 Loads[i] = DAG.getUNDEF(ElemVT); 1673 } 1674 EVT TargetVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, 4); 1675 LoweredLoad = DAG.getNode(ISD::BUILD_VECTOR, DL, TargetVT, Loads); 1676 } else { 1677 LoweredLoad = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, VT, 1678 Chain, Ptr, 1679 DAG.getTargetConstant(0, DL, MVT::i32), // Channel 1680 Op.getOperand(2)); 1681 } 1682 1683 SDValue Ops[2] = { 1684 LoweredLoad, 1685 Chain 1686 }; 1687 1688 return DAG.getMergeValues(Ops, DL); 1689 } 1690 1691 SDValue R600TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const { 1692 SDValue Chain = Op.getOperand(0); 1693 SDValue Cond = Op.getOperand(1); 1694 SDValue Jump = Op.getOperand(2); 1695 1696 return DAG.getNode(AMDGPUISD::BRANCH_COND, SDLoc(Op), Op.getValueType(), 1697 Chain, Jump, Cond); 1698 } 1699 1700 /// XXX Only kernel functions are supported, so we can assume for now that 1701 /// every function is a kernel function, but in the future we should use 1702 /// separate calling conventions for kernel and non-kernel functions. 1703 SDValue R600TargetLowering::LowerFormalArguments( 1704 SDValue Chain, 1705 CallingConv::ID CallConv, 1706 bool isVarArg, 1707 const SmallVectorImpl<ISD::InputArg> &Ins, 1708 SDLoc DL, SelectionDAG &DAG, 1709 SmallVectorImpl<SDValue> &InVals) const { 1710 SmallVector<CCValAssign, 16> ArgLocs; 1711 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, 1712 *DAG.getContext()); 1713 MachineFunction &MF = DAG.getMachineFunction(); 1714 R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); 1715 1716 SmallVector<ISD::InputArg, 8> LocalIns; 1717 1718 getOriginalFunctionArgs(DAG, MF.getFunction(), Ins, LocalIns); 1719 1720 AnalyzeFormalArguments(CCInfo, LocalIns); 1721 1722 for (unsigned i = 0, e = Ins.size(); i < e; ++i) { 1723 CCValAssign &VA = ArgLocs[i]; 1724 const ISD::InputArg &In = Ins[i]; 1725 EVT VT = In.VT; 1726 EVT MemVT = VA.getLocVT(); 1727 if (!VT.isVector() && MemVT.isVector()) { 1728 // Get load source type if scalarized. 1729 MemVT = MemVT.getVectorElementType(); 1730 } 1731 1732 if (MFI->getShaderType() != ShaderType::COMPUTE) { 1733 unsigned Reg = MF.addLiveIn(VA.getLocReg(), &AMDGPU::R600_Reg128RegClass); 1734 SDValue Register = DAG.getCopyFromReg(Chain, DL, Reg, VT); 1735 InVals.push_back(Register); 1736 continue; 1737 } 1738 1739 PointerType *PtrTy = PointerType::get(VT.getTypeForEVT(*DAG.getContext()), 1740 AMDGPUAS::CONSTANT_BUFFER_0); 1741 1742 // i64 isn't a legal type, so the register type used ends up as i32, which 1743 // isn't expected here. It attempts to create this sextload, but it ends up 1744 // being invalid. Somehow this seems to work with i64 arguments, but breaks 1745 // for <1 x i64>. 1746 1747 // The first 36 bytes of the input buffer contains information about 1748 // thread group and global sizes. 1749 ISD::LoadExtType Ext = ISD::NON_EXTLOAD; 1750 if (MemVT.getScalarSizeInBits() != VT.getScalarSizeInBits()) { 1751 // FIXME: This should really check the extload type, but the handling of 1752 // extload vector parameters seems to be broken. 1753 1754 // Ext = In.Flags.isSExt() ? ISD::SEXTLOAD : ISD::ZEXTLOAD; 1755 Ext = ISD::SEXTLOAD; 1756 } 1757 1758 // Compute the offset from the value. 1759 // XXX - I think PartOffset should give you this, but it seems to give the 1760 // size of the register which isn't useful. 1761 1762 unsigned ValBase = ArgLocs[In.getOrigArgIndex()].getLocMemOffset(); 1763 unsigned PartOffset = VA.getLocMemOffset(); 1764 unsigned Offset = 36 + VA.getLocMemOffset(); 1765 1766 MachinePointerInfo PtrInfo(UndefValue::get(PtrTy), PartOffset - ValBase); 1767 SDValue Arg = DAG.getLoad(ISD::UNINDEXED, Ext, VT, DL, Chain, 1768 DAG.getConstant(Offset, DL, MVT::i32), 1769 DAG.getUNDEF(MVT::i32), 1770 PtrInfo, 1771 MemVT, false, true, true, 4); 1772 1773 // 4 is the preferred alignment for the CONSTANT memory space. 1774 InVals.push_back(Arg); 1775 MFI->ABIArgOffset = Offset + MemVT.getStoreSize(); 1776 } 1777 return Chain; 1778 } 1779 1780 EVT R600TargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &, 1781 EVT VT) const { 1782 if (!VT.isVector()) 1783 return MVT::i32; 1784 return VT.changeVectorElementTypeToInteger(); 1785 } 1786 1787 bool R600TargetLowering::allowsMisalignedMemoryAccesses(EVT VT, 1788 unsigned AddrSpace, 1789 unsigned Align, 1790 bool *IsFast) const { 1791 if (IsFast) 1792 *IsFast = false; 1793 1794 if (!VT.isSimple() || VT == MVT::Other) 1795 return false; 1796 1797 if (VT.bitsLT(MVT::i32)) 1798 return false; 1799 1800 // TODO: This is a rough estimate. 1801 if (IsFast) 1802 *IsFast = true; 1803 1804 return VT.bitsGT(MVT::i32) && Align % 4 == 0; 1805 } 1806 1807 static SDValue CompactSwizzlableVector( 1808 SelectionDAG &DAG, SDValue VectorEntry, 1809 DenseMap<unsigned, unsigned> &RemapSwizzle) { 1810 assert(VectorEntry.getOpcode() == ISD::BUILD_VECTOR); 1811 assert(RemapSwizzle.empty()); 1812 SDValue NewBldVec[4] = { 1813 VectorEntry.getOperand(0), 1814 VectorEntry.getOperand(1), 1815 VectorEntry.getOperand(2), 1816 VectorEntry.getOperand(3) 1817 }; 1818 1819 for (unsigned i = 0; i < 4; i++) { 1820 if (NewBldVec[i].getOpcode() == ISD::UNDEF) 1821 // We mask write here to teach later passes that the ith element of this 1822 // vector is undef. Thus we can use it to reduce 128 bits reg usage, 1823 // break false dependencies and additionnaly make assembly easier to read. 1824 RemapSwizzle[i] = 7; // SEL_MASK_WRITE 1825 if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(NewBldVec[i])) { 1826 if (C->isZero()) { 1827 RemapSwizzle[i] = 4; // SEL_0 1828 NewBldVec[i] = DAG.getUNDEF(MVT::f32); 1829 } else if (C->isExactlyValue(1.0)) { 1830 RemapSwizzle[i] = 5; // SEL_1 1831 NewBldVec[i] = DAG.getUNDEF(MVT::f32); 1832 } 1833 } 1834 1835 if (NewBldVec[i].getOpcode() == ISD::UNDEF) 1836 continue; 1837 for (unsigned j = 0; j < i; j++) { 1838 if (NewBldVec[i] == NewBldVec[j]) { 1839 NewBldVec[i] = DAG.getUNDEF(NewBldVec[i].getValueType()); 1840 RemapSwizzle[i] = j; 1841 break; 1842 } 1843 } 1844 } 1845 1846 return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(VectorEntry), 1847 VectorEntry.getValueType(), NewBldVec); 1848 } 1849 1850 static SDValue ReorganizeVector(SelectionDAG &DAG, SDValue VectorEntry, 1851 DenseMap<unsigned, unsigned> &RemapSwizzle) { 1852 assert(VectorEntry.getOpcode() == ISD::BUILD_VECTOR); 1853 assert(RemapSwizzle.empty()); 1854 SDValue NewBldVec[4] = { 1855 VectorEntry.getOperand(0), 1856 VectorEntry.getOperand(1), 1857 VectorEntry.getOperand(2), 1858 VectorEntry.getOperand(3) 1859 }; 1860 bool isUnmovable[4] = { false, false, false, false }; 1861 for (unsigned i = 0; i < 4; i++) { 1862 RemapSwizzle[i] = i; 1863 if (NewBldVec[i].getOpcode() == ISD::EXTRACT_VECTOR_ELT) { 1864 unsigned Idx = dyn_cast<ConstantSDNode>(NewBldVec[i].getOperand(1)) 1865 ->getZExtValue(); 1866 if (i == Idx) 1867 isUnmovable[Idx] = true; 1868 } 1869 } 1870 1871 for (unsigned i = 0; i < 4; i++) { 1872 if (NewBldVec[i].getOpcode() == ISD::EXTRACT_VECTOR_ELT) { 1873 unsigned Idx = dyn_cast<ConstantSDNode>(NewBldVec[i].getOperand(1)) 1874 ->getZExtValue(); 1875 if (isUnmovable[Idx]) 1876 continue; 1877 // Swap i and Idx 1878 std::swap(NewBldVec[Idx], NewBldVec[i]); 1879 std::swap(RemapSwizzle[i], RemapSwizzle[Idx]); 1880 break; 1881 } 1882 } 1883 1884 return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(VectorEntry), 1885 VectorEntry.getValueType(), NewBldVec); 1886 } 1887 1888 1889 SDValue R600TargetLowering::OptimizeSwizzle(SDValue BuildVector, 1890 SDValue Swz[4], SelectionDAG &DAG, 1891 SDLoc DL) const { 1892 assert(BuildVector.getOpcode() == ISD::BUILD_VECTOR); 1893 // Old -> New swizzle values 1894 DenseMap<unsigned, unsigned> SwizzleRemap; 1895 1896 BuildVector = CompactSwizzlableVector(DAG, BuildVector, SwizzleRemap); 1897 for (unsigned i = 0; i < 4; i++) { 1898 unsigned Idx = cast<ConstantSDNode>(Swz[i])->getZExtValue(); 1899 if (SwizzleRemap.find(Idx) != SwizzleRemap.end()) 1900 Swz[i] = DAG.getConstant(SwizzleRemap[Idx], DL, MVT::i32); 1901 } 1902 1903 SwizzleRemap.clear(); 1904 BuildVector = ReorganizeVector(DAG, BuildVector, SwizzleRemap); 1905 for (unsigned i = 0; i < 4; i++) { 1906 unsigned Idx = cast<ConstantSDNode>(Swz[i])->getZExtValue(); 1907 if (SwizzleRemap.find(Idx) != SwizzleRemap.end()) 1908 Swz[i] = DAG.getConstant(SwizzleRemap[Idx], DL, MVT::i32); 1909 } 1910 1911 return BuildVector; 1912 } 1913 1914 1915 //===----------------------------------------------------------------------===// 1916 // Custom DAG Optimizations 1917 //===----------------------------------------------------------------------===// 1918 1919 SDValue R600TargetLowering::PerformDAGCombine(SDNode *N, 1920 DAGCombinerInfo &DCI) const { 1921 SelectionDAG &DAG = DCI.DAG; 1922 1923 switch (N->getOpcode()) { 1924 default: return AMDGPUTargetLowering::PerformDAGCombine(N, DCI); 1925 // (f32 fp_round (f64 uint_to_fp a)) -> (f32 uint_to_fp a) 1926 case ISD::FP_ROUND: { 1927 SDValue Arg = N->getOperand(0); 1928 if (Arg.getOpcode() == ISD::UINT_TO_FP && Arg.getValueType() == MVT::f64) { 1929 return DAG.getNode(ISD::UINT_TO_FP, SDLoc(N), N->getValueType(0), 1930 Arg.getOperand(0)); 1931 } 1932 break; 1933 } 1934 1935 // (i32 fp_to_sint (fneg (select_cc f32, f32, 1.0, 0.0 cc))) -> 1936 // (i32 select_cc f32, f32, -1, 0 cc) 1937 // 1938 // Mesa's GLSL frontend generates the above pattern a lot and we can lower 1939 // this to one of the SET*_DX10 instructions. 1940 case ISD::FP_TO_SINT: { 1941 SDValue FNeg = N->getOperand(0); 1942 if (FNeg.getOpcode() != ISD::FNEG) { 1943 return SDValue(); 1944 } 1945 SDValue SelectCC = FNeg.getOperand(0); 1946 if (SelectCC.getOpcode() != ISD::SELECT_CC || 1947 SelectCC.getOperand(0).getValueType() != MVT::f32 || // LHS 1948 SelectCC.getOperand(2).getValueType() != MVT::f32 || // True 1949 !isHWTrueValue(SelectCC.getOperand(2)) || 1950 !isHWFalseValue(SelectCC.getOperand(3))) { 1951 return SDValue(); 1952 } 1953 1954 SDLoc dl(N); 1955 return DAG.getNode(ISD::SELECT_CC, dl, N->getValueType(0), 1956 SelectCC.getOperand(0), // LHS 1957 SelectCC.getOperand(1), // RHS 1958 DAG.getConstant(-1, dl, MVT::i32), // True 1959 DAG.getConstant(0, dl, MVT::i32), // False 1960 SelectCC.getOperand(4)); // CC 1961 1962 break; 1963 } 1964 1965 // insert_vector_elt (build_vector elt0, ... , eltN), NewEltIdx, idx 1966 // => build_vector elt0, ... , NewEltIdx, ... , eltN 1967 case ISD::INSERT_VECTOR_ELT: { 1968 SDValue InVec = N->getOperand(0); 1969 SDValue InVal = N->getOperand(1); 1970 SDValue EltNo = N->getOperand(2); 1971 SDLoc dl(N); 1972 1973 // If the inserted element is an UNDEF, just use the input vector. 1974 if (InVal.getOpcode() == ISD::UNDEF) 1975 return InVec; 1976 1977 EVT VT = InVec.getValueType(); 1978 1979 // If we can't generate a legal BUILD_VECTOR, exit 1980 if (!isOperationLegal(ISD::BUILD_VECTOR, VT)) 1981 return SDValue(); 1982 1983 // Check that we know which element is being inserted 1984 if (!isa<ConstantSDNode>(EltNo)) 1985 return SDValue(); 1986 unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue(); 1987 1988 // Check that the operand is a BUILD_VECTOR (or UNDEF, which can essentially 1989 // be converted to a BUILD_VECTOR). Fill in the Ops vector with the 1990 // vector elements. 1991 SmallVector<SDValue, 8> Ops; 1992 if (InVec.getOpcode() == ISD::BUILD_VECTOR) { 1993 Ops.append(InVec.getNode()->op_begin(), 1994 InVec.getNode()->op_end()); 1995 } else if (InVec.getOpcode() == ISD::UNDEF) { 1996 unsigned NElts = VT.getVectorNumElements(); 1997 Ops.append(NElts, DAG.getUNDEF(InVal.getValueType())); 1998 } else { 1999 return SDValue(); 2000 } 2001 2002 // Insert the element 2003 if (Elt < Ops.size()) { 2004 // All the operands of BUILD_VECTOR must have the same type; 2005 // we enforce that here. 2006 EVT OpVT = Ops[0].getValueType(); 2007 if (InVal.getValueType() != OpVT) 2008 InVal = OpVT.bitsGT(InVal.getValueType()) ? 2009 DAG.getNode(ISD::ANY_EXTEND, dl, OpVT, InVal) : 2010 DAG.getNode(ISD::TRUNCATE, dl, OpVT, InVal); 2011 Ops[Elt] = InVal; 2012 } 2013 2014 // Return the new vector 2015 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); 2016 } 2017 2018 // Extract_vec (Build_vector) generated by custom lowering 2019 // also needs to be customly combined 2020 case ISD::EXTRACT_VECTOR_ELT: { 2021 SDValue Arg = N->getOperand(0); 2022 if (Arg.getOpcode() == ISD::BUILD_VECTOR) { 2023 if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 2024 unsigned Element = Const->getZExtValue(); 2025 return Arg->getOperand(Element); 2026 } 2027 } 2028 if (Arg.getOpcode() == ISD::BITCAST && 2029 Arg.getOperand(0).getOpcode() == ISD::BUILD_VECTOR) { 2030 if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 2031 unsigned Element = Const->getZExtValue(); 2032 return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getVTList(), 2033 Arg->getOperand(0).getOperand(Element)); 2034 } 2035 } 2036 break; 2037 } 2038 2039 case ISD::SELECT_CC: { 2040 // Try common optimizations 2041 if (SDValue Ret = AMDGPUTargetLowering::PerformDAGCombine(N, DCI)) 2042 return Ret; 2043 2044 // fold selectcc (selectcc x, y, a, b, cc), b, a, b, seteq -> 2045 // selectcc x, y, a, b, inv(cc) 2046 // 2047 // fold selectcc (selectcc x, y, a, b, cc), b, a, b, setne -> 2048 // selectcc x, y, a, b, cc 2049 SDValue LHS = N->getOperand(0); 2050 if (LHS.getOpcode() != ISD::SELECT_CC) { 2051 return SDValue(); 2052 } 2053 2054 SDValue RHS = N->getOperand(1); 2055 SDValue True = N->getOperand(2); 2056 SDValue False = N->getOperand(3); 2057 ISD::CondCode NCC = cast<CondCodeSDNode>(N->getOperand(4))->get(); 2058 2059 if (LHS.getOperand(2).getNode() != True.getNode() || 2060 LHS.getOperand(3).getNode() != False.getNode() || 2061 RHS.getNode() != False.getNode()) { 2062 return SDValue(); 2063 } 2064 2065 switch (NCC) { 2066 default: return SDValue(); 2067 case ISD::SETNE: return LHS; 2068 case ISD::SETEQ: { 2069 ISD::CondCode LHSCC = cast<CondCodeSDNode>(LHS.getOperand(4))->get(); 2070 LHSCC = ISD::getSetCCInverse(LHSCC, 2071 LHS.getOperand(0).getValueType().isInteger()); 2072 if (DCI.isBeforeLegalizeOps() || 2073 isCondCodeLegal(LHSCC, LHS.getOperand(0).getSimpleValueType())) 2074 return DAG.getSelectCC(SDLoc(N), 2075 LHS.getOperand(0), 2076 LHS.getOperand(1), 2077 LHS.getOperand(2), 2078 LHS.getOperand(3), 2079 LHSCC); 2080 break; 2081 } 2082 } 2083 return SDValue(); 2084 } 2085 2086 case AMDGPUISD::EXPORT: { 2087 SDValue Arg = N->getOperand(1); 2088 if (Arg.getOpcode() != ISD::BUILD_VECTOR) 2089 break; 2090 2091 SDValue NewArgs[8] = { 2092 N->getOperand(0), // Chain 2093 SDValue(), 2094 N->getOperand(2), // ArrayBase 2095 N->getOperand(3), // Type 2096 N->getOperand(4), // SWZ_X 2097 N->getOperand(5), // SWZ_Y 2098 N->getOperand(6), // SWZ_Z 2099 N->getOperand(7) // SWZ_W 2100 }; 2101 SDLoc DL(N); 2102 NewArgs[1] = OptimizeSwizzle(N->getOperand(1), &NewArgs[4], DAG, DL); 2103 return DAG.getNode(AMDGPUISD::EXPORT, DL, N->getVTList(), NewArgs); 2104 } 2105 case AMDGPUISD::TEXTURE_FETCH: { 2106 SDValue Arg = N->getOperand(1); 2107 if (Arg.getOpcode() != ISD::BUILD_VECTOR) 2108 break; 2109 2110 SDValue NewArgs[19] = { 2111 N->getOperand(0), 2112 N->getOperand(1), 2113 N->getOperand(2), 2114 N->getOperand(3), 2115 N->getOperand(4), 2116 N->getOperand(5), 2117 N->getOperand(6), 2118 N->getOperand(7), 2119 N->getOperand(8), 2120 N->getOperand(9), 2121 N->getOperand(10), 2122 N->getOperand(11), 2123 N->getOperand(12), 2124 N->getOperand(13), 2125 N->getOperand(14), 2126 N->getOperand(15), 2127 N->getOperand(16), 2128 N->getOperand(17), 2129 N->getOperand(18), 2130 }; 2131 SDLoc DL(N); 2132 NewArgs[1] = OptimizeSwizzle(N->getOperand(1), &NewArgs[2], DAG, DL); 2133 return DAG.getNode(AMDGPUISD::TEXTURE_FETCH, DL, N->getVTList(), NewArgs); 2134 } 2135 } 2136 2137 return AMDGPUTargetLowering::PerformDAGCombine(N, DCI); 2138 } 2139 2140 static bool 2141 FoldOperand(SDNode *ParentNode, unsigned SrcIdx, SDValue &Src, SDValue &Neg, 2142 SDValue &Abs, SDValue &Sel, SDValue &Imm, SelectionDAG &DAG) { 2143 const R600InstrInfo *TII = 2144 static_cast<const R600InstrInfo *>(DAG.getSubtarget().getInstrInfo()); 2145 if (!Src.isMachineOpcode()) 2146 return false; 2147 switch (Src.getMachineOpcode()) { 2148 case AMDGPU::FNEG_R600: 2149 if (!Neg.getNode()) 2150 return false; 2151 Src = Src.getOperand(0); 2152 Neg = DAG.getTargetConstant(1, SDLoc(ParentNode), MVT::i32); 2153 return true; 2154 case AMDGPU::FABS_R600: 2155 if (!Abs.getNode()) 2156 return false; 2157 Src = Src.getOperand(0); 2158 Abs = DAG.getTargetConstant(1, SDLoc(ParentNode), MVT::i32); 2159 return true; 2160 case AMDGPU::CONST_COPY: { 2161 unsigned Opcode = ParentNode->getMachineOpcode(); 2162 bool HasDst = TII->getOperandIdx(Opcode, AMDGPU::OpName::dst) > -1; 2163 2164 if (!Sel.getNode()) 2165 return false; 2166 2167 SDValue CstOffset = Src.getOperand(0); 2168 if (ParentNode->getValueType(0).isVector()) 2169 return false; 2170 2171 // Gather constants values 2172 int SrcIndices[] = { 2173 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0), 2174 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1), 2175 TII->getOperandIdx(Opcode, AMDGPU::OpName::src2), 2176 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_X), 2177 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_Y), 2178 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_Z), 2179 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_W), 2180 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_X), 2181 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_Y), 2182 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_Z), 2183 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_W) 2184 }; 2185 std::vector<unsigned> Consts; 2186 for (int OtherSrcIdx : SrcIndices) { 2187 int OtherSelIdx = TII->getSelIdx(Opcode, OtherSrcIdx); 2188 if (OtherSrcIdx < 0 || OtherSelIdx < 0) 2189 continue; 2190 if (HasDst) { 2191 OtherSrcIdx--; 2192 OtherSelIdx--; 2193 } 2194 if (RegisterSDNode *Reg = 2195 dyn_cast<RegisterSDNode>(ParentNode->getOperand(OtherSrcIdx))) { 2196 if (Reg->getReg() == AMDGPU::ALU_CONST) { 2197 ConstantSDNode *Cst 2198 = cast<ConstantSDNode>(ParentNode->getOperand(OtherSelIdx)); 2199 Consts.push_back(Cst->getZExtValue()); 2200 } 2201 } 2202 } 2203 2204 ConstantSDNode *Cst = cast<ConstantSDNode>(CstOffset); 2205 Consts.push_back(Cst->getZExtValue()); 2206 if (!TII->fitsConstReadLimitations(Consts)) { 2207 return false; 2208 } 2209 2210 Sel = CstOffset; 2211 Src = DAG.getRegister(AMDGPU::ALU_CONST, MVT::f32); 2212 return true; 2213 } 2214 case AMDGPU::MOV_IMM_I32: 2215 case AMDGPU::MOV_IMM_F32: { 2216 unsigned ImmReg = AMDGPU::ALU_LITERAL_X; 2217 uint64_t ImmValue = 0; 2218 2219 2220 if (Src.getMachineOpcode() == AMDGPU::MOV_IMM_F32) { 2221 ConstantFPSDNode *FPC = dyn_cast<ConstantFPSDNode>(Src.getOperand(0)); 2222 float FloatValue = FPC->getValueAPF().convertToFloat(); 2223 if (FloatValue == 0.0) { 2224 ImmReg = AMDGPU::ZERO; 2225 } else if (FloatValue == 0.5) { 2226 ImmReg = AMDGPU::HALF; 2227 } else if (FloatValue == 1.0) { 2228 ImmReg = AMDGPU::ONE; 2229 } else { 2230 ImmValue = FPC->getValueAPF().bitcastToAPInt().getZExtValue(); 2231 } 2232 } else { 2233 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Src.getOperand(0)); 2234 uint64_t Value = C->getZExtValue(); 2235 if (Value == 0) { 2236 ImmReg = AMDGPU::ZERO; 2237 } else if (Value == 1) { 2238 ImmReg = AMDGPU::ONE_INT; 2239 } else { 2240 ImmValue = Value; 2241 } 2242 } 2243 2244 // Check that we aren't already using an immediate. 2245 // XXX: It's possible for an instruction to have more than one 2246 // immediate operand, but this is not supported yet. 2247 if (ImmReg == AMDGPU::ALU_LITERAL_X) { 2248 if (!Imm.getNode()) 2249 return false; 2250 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Imm); 2251 assert(C); 2252 if (C->getZExtValue()) 2253 return false; 2254 Imm = DAG.getTargetConstant(ImmValue, SDLoc(ParentNode), MVT::i32); 2255 } 2256 Src = DAG.getRegister(ImmReg, MVT::i32); 2257 return true; 2258 } 2259 default: 2260 return false; 2261 } 2262 } 2263 2264 2265 /// \brief Fold the instructions after selecting them 2266 SDNode *R600TargetLowering::PostISelFolding(MachineSDNode *Node, 2267 SelectionDAG &DAG) const { 2268 const R600InstrInfo *TII = 2269 static_cast<const R600InstrInfo *>(DAG.getSubtarget().getInstrInfo()); 2270 if (!Node->isMachineOpcode()) 2271 return Node; 2272 unsigned Opcode = Node->getMachineOpcode(); 2273 SDValue FakeOp; 2274 2275 std::vector<SDValue> Ops(Node->op_begin(), Node->op_end()); 2276 2277 if (Opcode == AMDGPU::DOT_4) { 2278 int OperandIdx[] = { 2279 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_X), 2280 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_Y), 2281 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_Z), 2282 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_W), 2283 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_X), 2284 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_Y), 2285 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_Z), 2286 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_W) 2287 }; 2288 int NegIdx[] = { 2289 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_neg_X), 2290 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_neg_Y), 2291 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_neg_Z), 2292 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_neg_W), 2293 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_neg_X), 2294 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_neg_Y), 2295 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_neg_Z), 2296 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_neg_W) 2297 }; 2298 int AbsIdx[] = { 2299 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_abs_X), 2300 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_abs_Y), 2301 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_abs_Z), 2302 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_abs_W), 2303 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_abs_X), 2304 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_abs_Y), 2305 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_abs_Z), 2306 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_abs_W) 2307 }; 2308 for (unsigned i = 0; i < 8; i++) { 2309 if (OperandIdx[i] < 0) 2310 return Node; 2311 SDValue &Src = Ops[OperandIdx[i] - 1]; 2312 SDValue &Neg = Ops[NegIdx[i] - 1]; 2313 SDValue &Abs = Ops[AbsIdx[i] - 1]; 2314 bool HasDst = TII->getOperandIdx(Opcode, AMDGPU::OpName::dst) > -1; 2315 int SelIdx = TII->getSelIdx(Opcode, OperandIdx[i]); 2316 if (HasDst) 2317 SelIdx--; 2318 SDValue &Sel = (SelIdx > -1) ? Ops[SelIdx] : FakeOp; 2319 if (FoldOperand(Node, i, Src, Neg, Abs, Sel, FakeOp, DAG)) 2320 return DAG.getMachineNode(Opcode, SDLoc(Node), Node->getVTList(), Ops); 2321 } 2322 } else if (Opcode == AMDGPU::REG_SEQUENCE) { 2323 for (unsigned i = 1, e = Node->getNumOperands(); i < e; i += 2) { 2324 SDValue &Src = Ops[i]; 2325 if (FoldOperand(Node, i, Src, FakeOp, FakeOp, FakeOp, FakeOp, DAG)) 2326 return DAG.getMachineNode(Opcode, SDLoc(Node), Node->getVTList(), Ops); 2327 } 2328 } else if (Opcode == AMDGPU::CLAMP_R600) { 2329 SDValue Src = Node->getOperand(0); 2330 if (!Src.isMachineOpcode() || 2331 !TII->hasInstrModifiers(Src.getMachineOpcode())) 2332 return Node; 2333 int ClampIdx = TII->getOperandIdx(Src.getMachineOpcode(), 2334 AMDGPU::OpName::clamp); 2335 if (ClampIdx < 0) 2336 return Node; 2337 SDLoc DL(Node); 2338 std::vector<SDValue> Ops(Src->op_begin(), Src->op_end()); 2339 Ops[ClampIdx - 1] = DAG.getTargetConstant(1, DL, MVT::i32); 2340 return DAG.getMachineNode(Src.getMachineOpcode(), DL, 2341 Node->getVTList(), Ops); 2342 } else { 2343 if (!TII->hasInstrModifiers(Opcode)) 2344 return Node; 2345 int OperandIdx[] = { 2346 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0), 2347 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1), 2348 TII->getOperandIdx(Opcode, AMDGPU::OpName::src2) 2349 }; 2350 int NegIdx[] = { 2351 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_neg), 2352 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_neg), 2353 TII->getOperandIdx(Opcode, AMDGPU::OpName::src2_neg) 2354 }; 2355 int AbsIdx[] = { 2356 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0_abs), 2357 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1_abs), 2358 -1 2359 }; 2360 for (unsigned i = 0; i < 3; i++) { 2361 if (OperandIdx[i] < 0) 2362 return Node; 2363 SDValue &Src = Ops[OperandIdx[i] - 1]; 2364 SDValue &Neg = Ops[NegIdx[i] - 1]; 2365 SDValue FakeAbs; 2366 SDValue &Abs = (AbsIdx[i] > -1) ? Ops[AbsIdx[i] - 1] : FakeAbs; 2367 bool HasDst = TII->getOperandIdx(Opcode, AMDGPU::OpName::dst) > -1; 2368 int SelIdx = TII->getSelIdx(Opcode, OperandIdx[i]); 2369 int ImmIdx = TII->getOperandIdx(Opcode, AMDGPU::OpName::literal); 2370 if (HasDst) { 2371 SelIdx--; 2372 ImmIdx--; 2373 } 2374 SDValue &Sel = (SelIdx > -1) ? Ops[SelIdx] : FakeOp; 2375 SDValue &Imm = Ops[ImmIdx]; 2376 if (FoldOperand(Node, i, Src, Neg, Abs, Sel, Imm, DAG)) 2377 return DAG.getMachineNode(Opcode, SDLoc(Node), Node->getVTList(), Ops); 2378 } 2379 } 2380 2381 return Node; 2382 } 2383