--- /dev/null
+# REQUIRES: amdgpu-registered-target
+# RUN: llvm-reduce -mtriple=amdgcn-amd-amdhsa --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2> %t.log
+# RUN: FileCheck --match-full-lines --check-prefix=RESULT %s < %t
+
+# Verify that reduction works with generic virtual registers, and the
+# properties like register banks, types and names.
+
+
+# CHECK-INTERESTINGNESS: G_IMPLICIT_DEF
+# CHECK-INTERESTINGNESS: G_BITCAST
+# CHECK-INTERESTINGNESS: G_ADD
+# CHECK-INTERESTINGNESS: G_IMPLICIT_DEF
+# CHECK-INTERESTINGNESS: G_STORE
+
+# RESULT: %v0:vgpr(s32) = COPY $vgpr0, implicit-def %9(p1), implicit-def %10(s64), implicit-def %11(s64)
+# RESULT-NEXT: %arst:_(<2 x s32>) = G_IMPLICIT_DEF
+# RESULT-NEXT: %aoeu:_(s64) = G_BITCAST %arst(<2 x s32>)
+# RESULT-NEXT: %add:_(s64) = G_ADD %aoeu, %aoeu
+# RESULT-NEXT: %ptr:_(p1) = G_IMPLICIT_DEF
+# RESULT-NEXT: G_STORE %v0(s32), %ptr(p1) :: (store (s32), addrspace 1)
+# RESULT-NEXT: S_ENDPGM 0, implicit %add(s64), implicit %v0(s32), implicit %11(s64)
+
+---
+name: f
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0, $vgpr1, $vgpr2_vgpr3
+ %v0:vgpr(s32) = COPY $vgpr0
+ %v1:vgpr(<2 x s16>) = COPY $vgpr1
+ %unused_load_ptr:sgpr(p1) = G_IMPLICIT_DEF
+ %unused_load:_(s64) = G_LOAD %unused_load_ptr :: (load (s64), addrspace 1)
+ G_STORE %unused_load, %unused_load_ptr :: (store (s64), addrspace 1)
+ %2:vreg_64(s64) = COPY $vgpr2_vgpr3
+ %arst:_(<2 x s32>) = G_IMPLICIT_DEF
+ %aoeu:_(s64) = G_BITCAST %arst
+ S_NOP 0
+ %add:_(s64) = G_ADD %aoeu, %aoeu
+ %ptr:_(p1) = G_IMPLICIT_DEF
+ G_STORE %v0, %ptr :: (store 4, addrspace 1)
+ S_ENDPGM 0, implicit %add, implicit %v1, implicit %2
+...
Register SrcReg = DMO.getReg();
if (Register::isPhysicalRegister(SrcReg))
continue;
- auto SrcRC = SrcMRI->getRegClass(SrcReg);
- auto DstReg = DstMRI->createVirtualRegister(SrcRC);
+ Register DstReg = DstMRI->createIncompleteVirtualRegister(
+ SrcMRI->getVRegName(SrcReg));
+ DstMRI->setRegClassOrRegBank(DstReg,
+ SrcMRI->getRegClassOrRegBank(SrcReg));
+
+ LLT RegTy = SrcMRI->getType(SrcReg);
+ if (RegTy.isValid())
+ DstMRI->setType(DstReg, RegTy);
Src2DstReg[SrcReg] = DstReg;
}
}
static Register getPrevDefOfRCInMBB(MachineBasicBlock &MBB,
MachineBasicBlock::reverse_iterator &RI,
- const TargetRegisterClass *RC,
+ const RegClassOrRegBank &RC,
SetVector<MachineInstr *> &ExcludeMIs) {
auto MRI = &MBB.getParent()->getRegInfo();
for (MachineBasicBlock::reverse_instr_iterator E = MBB.instr_rend(); RI != E;
if (Register::isPhysicalRegister(Reg))
continue;
- if (MRI->getRegClass(Reg) == RC && !ExcludeMIs.count(MO.getParent()))
+ if (MRI->getRegClassOrRegBank(Reg) == RC &&
+ !ExcludeMIs.count(MO.getParent()))
return Reg;
}
}
auto UI = MRI->use_begin(Reg);
auto UE = MRI->use_end();
- auto RegRC = MRI->getRegClass(Reg);
+ const auto &RegRC = MRI->getRegClassOrRegBank(Reg);
Register NewReg = 0;
// If this is not a physical register and there are some uses.
if (UI != UE) {
// If no dominating definition was found then add an implicit one to the
// first instruction in the entry block.
if (!NewReg && TopMI) {
- NewReg = MRI->createVirtualRegister(RegRC);
+ NewReg = MRI->cloneVirtualRegister(Reg);
TopMI->addOperand(MachineOperand::CreateReg(
NewReg, true /*IsDef*/, true /*IsImp*/, false /*IsKill*/));
}