Skip to content

[AMDGPU] Set register bank for i1 register copies #96155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3735,17 +3735,28 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
const MachineRegisterInfo &MRI = MF.getRegInfo();

if (MI.isCopy() || MI.getOpcode() == AMDGPU::G_FREEZE) {
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = MI.getOperand(1).getReg();

// The default logic bothers to analyze impossible alternative mappings. We
// want the most straightforward mapping, so just directly handle this.
const RegisterBank *DstBank = getRegBank(MI.getOperand(0).getReg(), MRI,
*TRI);
const RegisterBank *SrcBank = getRegBank(MI.getOperand(1).getReg(), MRI,
*TRI);
const RegisterBank *DstBank = getRegBank(DstReg, MRI, *TRI);
const RegisterBank *SrcBank = getRegBank(SrcReg, MRI, *TRI);
assert(SrcBank && "src bank should have been assigned already");

// For COPY between a physical reg and an s1, there is no type associated so
// we need to take the virtual register's type as a hint on how to interpret
// s1 values.
if (!SrcReg.isVirtual() && !DstBank &&
MRI.getType(DstReg) == LLT::scalar(1))
DstBank = &AMDGPU::VCCRegBank;
else if (!DstReg.isVirtual() && MRI.getType(SrcReg) == LLT::scalar(1))
DstBank = &AMDGPU::VCCRegBank;

if (!DstBank)
DstBank = SrcBank;

unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
unsigned Size = getSizeInBits(DstReg, MRI, *TRI);
if (MI.getOpcode() != AMDGPU::G_FREEZE &&
cannotCopy(*DstBank, *SrcBank, TypeSize::getFixed(Size)))
return getInvalidInstructionMapping();
Expand Down
298 changes: 298 additions & 0 deletions llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-copy.mir
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=amdgcn -mcpu=gfx908 -run-pass=amdgpu-regbankselect -regbankselect-fast -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -mtriple=amdgcn -mcpu=gfx908 -run-pass=amdgpu-regbankselect -regbankselect-greedy -verify-machineinstrs %s -o - | FileCheck %s
# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -run-pass=amdgpu-regbankselect -regbankselect-fast -verify-machineinstrs %s -o - | FileCheck --check-prefix=WAVE32 %s
# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -run-pass=amdgpu-regbankselect -regbankselect-greedy -verify-machineinstrs %s -o - | FileCheck --check-prefix=WAVE32 %s

---
name: copy_s32_vgpr_to_vgpr
Expand Down Expand Up @@ -201,3 +203,299 @@ body: |
%2:vcc(s1) = COPY %1
S_ENDPGM 0, implicit %2
...

---
name: wave64_copy_sgpr_64_to_s1
legalized: true

body: |
bb.0:
liveins: $sgpr4_sgpr5
; CHECK-LABEL: name: wave64_copy_sgpr_64_to_s1
; CHECK: liveins: $sgpr4_sgpr5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vcc(s1) = COPY $sgpr4_sgpr5
; CHECK-NEXT: [[CONST1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[CONST2:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY]](s1), [[CONST1]], [[CONST2]]
%0:_(s1) = COPY $sgpr4_sgpr5
%1:_(s32) = G_ZEXT %0:_(s1)
...

---
name: wave32_copy_sgpr_32_to_s1
legalized: true

body: |
bb.0:
liveins: $sgpr0
; WAVE32-LABEL: name: wave32_copy_sgpr_32_to_s1
; WAVE32: liveins: $sgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vcc(s1) = COPY $sgpr0
; WAVE32-NEXT: [[CONST1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; WAVE32-NEXT: [[CONST2:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; WAVE32-NEXT: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY]](s1), [[CONST1]], [[CONST2]]
%0:_(s1) = COPY $sgpr0
%1:_(s32) = G_ZEXT %0:_(s1)
...

---
name: wave64_copy2_sgpr_64_to_s1
legalized: true

body: |
bb.0:
liveins: $sgpr4_sgpr5, $sgpr6_sgpr7
; CHECK-LABEL: name: wave64_copy2_sgpr_64_to_s1
; CHECK: liveins: $sgpr4_sgpr5, $sgpr6_sgpr7
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:vcc(s1) = COPY $sgpr4_sgpr5
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vcc(s1) = COPY $sgpr6_sgpr7
; CHECK-NEXT: [[CONST1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[CONST2:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[SELECT1:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY1]](s1), [[CONST1]], [[CONST2]]
; CHECK-NEXT: [[CONST3:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[CONST4:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[SELECT2:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY2]](s1), [[CONST3]], [[CONST4]]
%0:_(s1) = COPY $sgpr4_sgpr5
%1:_(s1) = COPY $sgpr6_sgpr7
%2:_(s32) = G_ZEXT %0:_(s1)
%3:_(s32) = G_ZEXT %1:_(s1)
...

---
name: wave32_copy2_sgpr_32_to_s1
legalized: true

body: |
bb.0:
liveins: $sgpr0, $sgpr1
; WAVE32-LABEL: name: wave32_copy2_sgpr_32_to_s1
; WAVE32: liveins: $sgpr0, $sgpr1
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY1:%[0-9]+]]:vcc(s1) = COPY $sgpr0
; WAVE32-NEXT: [[COPY2:%[0-9]+]]:vcc(s1) = COPY $sgpr1
; WAVE32-NEXT: [[CONST1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; WAVE32-NEXT: [[CONST2:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; WAVE32-NEXT: [[SELECT1:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY1]](s1), [[CONST1]], [[CONST2]]
; WAVE32-NEXT: [[CONST3:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; WAVE32-NEXT: [[CONST4:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; WAVE32-NEXT: [[SELECT2:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY2]](s1), [[CONST3]], [[CONST4]]
%0:_(s1) = COPY $sgpr0
%1:_(s1) = COPY $sgpr1
%2:_(s32) = G_ZEXT %0:_(s1)
%3:_(s32) = G_ZEXT %1:_(s1)
...

---
name: copy_sgpr_64_to_s1_vgpr
legalized: true

body: |
bb.0:
liveins: $sgpr4_sgpr5
; CHECK-LABEL: name: copy_sgpr_64_to_s1_vgpr
; CHECK: liveins: $sgpr4_sgpr5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s1) = COPY $sgpr4_sgpr5
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:vgpr(s32) = G_ZEXT [[COPY]](s1)
;
; WAVE32-LABEL: name: copy_sgpr_64_to_s1_vgpr
; WAVE32: liveins: $sgpr4_sgpr5
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s1) = COPY $sgpr4_sgpr5
; WAVE32-NEXT: [[ZEXT:%[0-9]+]]:vgpr(s32) = G_ZEXT [[COPY]](s1)
%0:vgpr(s1) = COPY $sgpr4_sgpr5
%1:_(s32) = G_ZEXT %0:vgpr(s1)
...

---
name: copy_sgpr_32_to_s1_vgpr
legalized: true

body: |
bb.0:
liveins: $sgpr0
; CHECK-LABEL: name: copy_sgpr_32_to_s1_vgpr
; CHECK: liveins: $sgpr0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s1) = COPY $sgpr0
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:vgpr(s32) = G_ZEXT [[COPY]](s1)
;
; WAVE32-LABEL: name: copy_sgpr_32_to_s1_vgpr
; WAVE32: liveins: $sgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s1) = COPY $sgpr0
; WAVE32-NEXT: [[ZEXT:%[0-9]+]]:vgpr(s32) = G_ZEXT [[COPY]](s1)
%0:vgpr(s1) = COPY $sgpr0
%1:_(s32) = G_ZEXT %0:vgpr(s1)
...

---
name: wave64_copy_sgpr_64_to_s1_vcc
legalized: true

body: |
bb.0:
liveins: $sgpr4_sgpr5
; CHECK-LABEL: name: wave64_copy_sgpr_64_to_s1_vcc
; CHECK: liveins: $sgpr4_sgpr5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vcc(s1) = COPY $sgpr4_sgpr5
; CHECK-NEXT: [[CONST1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[CONST2:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY]](s1), [[CONST1]], [[CONST2]]
%0:vcc(s1) = COPY $sgpr4_sgpr5
%1:_(s32) = G_ZEXT %0:vcc(s1)
...

---
name: wave32_copy_sgpr_32_to_s1_vcc
legalized: true

body: |
bb.0:
liveins: $sgpr0
; WAVE32-LABEL: name: wave32_copy_sgpr_32_to_s1_vcc
; WAVE32: liveins: $sgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vcc(s1) = COPY $sgpr0
; WAVE32-NEXT: [[CONST1:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 1
; WAVE32-NEXT: [[CONST2:%[0-9]+]]:vgpr(s32) = G_CONSTANT i32 0
; WAVE32-NEXT: [[SELECT:%[0-9]+]]:vgpr(s32) = G_SELECT [[COPY]](s1), [[CONST1]], [[CONST2]]
%0:vcc(s1) = COPY $sgpr0
%1:_(s32) = G_ZEXT %0:vcc(s1)
...

---
name: copy_virt_reg_to_s1
legalized: true

body: |
bb.0:
liveins: $vgpr0
; CHECK-LABEL: name: copy_virt_reg_to_s1
; CHECK: liveins: $vgpr0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr(s1) = COPY [[TRUNC]](s1)
;
; WAVE32-LABEL: name: copy_virt_reg_to_s1
; WAVE32: liveins: $vgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; WAVE32-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; WAVE32-NEXT: [[COPY2:%[0-9]+]]:vgpr(s1) = COPY [[TRUNC]](s1)
%0:_(s32) = COPY $vgpr0
%1:_(s1) = G_TRUNC %0
%2:_(s1) = COPY %1
...

---
name: copy_virt_reg_to_s1_vgpr
legalized: true

body: |
bb.0:
liveins: $vgpr0
; CHECK-LABEL: name: copy_virt_reg_to_s1_vgpr
; CHECK: liveins: $vgpr0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr(s1) = COPY [[TRUNC]](s1)
; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr(s1) = COPY [[COPY2]](s1)
;
; WAVE32-LABEL: name: copy_virt_reg_to_s1_vgpr
; WAVE32: liveins: $vgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; WAVE32-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; WAVE32-NEXT: [[COPY2:%[0-9]+]]:vgpr(s1) = COPY [[TRUNC]](s1)
; WAVE32-NEXT: [[COPY3:%[0-9]+]]:vgpr(s1) = COPY [[COPY2]](s1)
%0:_(s32) = COPY $vgpr0
%1:_(s1) = G_TRUNC %0
%2:vgpr(s1) = COPY %1
%3:_(s1) = COPY %2
...


---
name: copy_virt_reg_to_s1_vcc
legalized: true

body: |
bb.0:
liveins: $vgpr0
; CHECK-LABEL: name: copy_virt_reg_to_s1_vcc
; CHECK: liveins: $vgpr0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; CHECK-NEXT: [[COPY2:%[0-9]+]]:vcc(s1) = COPY [[TRUNC]](s1)
; CHECK-NEXT: [[COPY3:%[0-9]+]]:vcc(s1) = COPY [[COPY2]](s1)
;
; WAVE32-LABEL: name: copy_virt_reg_to_s1_vcc
; WAVE32: liveins: $vgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; WAVE32-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; WAVE32-NEXT: [[COPY2:%[0-9]+]]:vcc(s1) = COPY [[TRUNC]](s1)
; WAVE32-NEXT: [[COPY3:%[0-9]+]]:vcc(s1) = COPY [[COPY2]](s1)
%0:_(s32) = COPY $vgpr0
%1:_(s1) = G_TRUNC %0
%2:vcc(s1) = COPY %1
%3:_(s1) = COPY %2
...

---
name: copy_s1_to_sgpr_64
legalized: true

body: |
bb.0:
liveins: $vgpr0
; CHECK-LABEL: name: copy_s1_to_sgpr_64
; CHECK: liveins: $vgpr0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; CHECK-NEXT: $sgpr4_sgpr5 = COPY [[TRUNC]](s1)
;
; WAVE32-LABEL: name: copy_s1_to_sgpr_64
; WAVE32: liveins: $vgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; WAVE32-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; WAVE32-NEXT: $sgpr4_sgpr5 = COPY [[TRUNC]](s1)
%0:_(s32) = COPY $vgpr0
%1:_(s1) = G_TRUNC %0
$sgpr4_sgpr5 = COPY %1
...

---
name: copy_s1_to_sgpr_32
legalized: true

body: |
bb.0:
liveins: $vgpr0
; CHECK-LABEL: name: copy_s1_to_sgpr_32
; CHECK: liveins: $vgpr0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; CHECK-NEXT: $sgpr0 = COPY [[TRUNC]](s1)
;
; WAVE32-LABEL: name: copy_s1_to_sgpr_32
; WAVE32: liveins: $vgpr0
; WAVE32-NEXT: {{ $}}
; WAVE32-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
; WAVE32-NEXT: [[TRUNC:%[0-9]+]]:vgpr(s1) = G_TRUNC [[COPY]](s32)
; WAVE32-NEXT: $sgpr0 = COPY [[TRUNC]](s1)
%0:_(s32) = COPY $vgpr0
%1:_(s1) = G_TRUNC %0
$sgpr0 = COPY %1
...
Loading