summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>2019-10-02 23:23:46 +0000
committerStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>2019-10-02 23:23:46 +0000
commit1384c3a5b896e5f9463fe87d75b35cbdf80e288b (patch)
tree90f552e763acba4331806000030e4bdf3e31a549
parent2a964eabaa80399d5fb33535a1fcacc033e498e9 (diff)
downloadbcm5719-llvm-1384c3a5b896e5f9463fe87d75b35cbdf80e288b.tar.gz
bcm5719-llvm-1384c3a5b896e5f9463fe87d75b35cbdf80e288b.zip
[AMDGPU] Fix illegal agpr use by VALU
When SIFixSGPRCopies attempts to fix an illegal copy from vector to scalar register it calls moveToVALU(). A copy from an agpr to sgpr becomes a copy from agpr to agpr, which may result in the illegal register class at a use of this copy. Solution is to copy it always into a vgpr. This may result in a subsequent copy into an agpr if that is what really needed, however should not happen too often and likely will be folded later. The opposite situation may not happen because an sgpr is always illegal where agpr is legal, so such user instructions may not exist. Differential Revision: https://reviews.llvm.org/D68358 llvm-svn: 373544
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrInfo.cpp11
-rw-r--r--llvm/test/CodeGen/AMDGPU/fold_acc_copy_into_valu.mir15
-rw-r--r--llvm/test/CodeGen/AMDGPU/illegal-sgpr-to-vgpr-copy.ll9
3 files changed, 31 insertions, 4 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index d5f2902f18a..7a6bb0e20b7 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -5665,7 +5665,16 @@ const TargetRegisterClass *SIInstrInfo::getDestEquivalentVGPRClass(
if (RI.hasAGPRs(NewDstRC))
return nullptr;
- NewDstRC = RI.getEquivalentAGPRClass(NewDstRC);
+ switch (Inst.getOpcode()) {
+ case AMDGPU::PHI:
+ case AMDGPU::REG_SEQUENCE:
+ case AMDGPU::INSERT_SUBREG:
+ NewDstRC = RI.getEquivalentAGPRClass(NewDstRC);
+ break;
+ default:
+ NewDstRC = RI.getEquivalentVGPRClass(NewDstRC);
+ }
+
if (!NewDstRC)
return nullptr;
} else {
diff --git a/llvm/test/CodeGen/AMDGPU/fold_acc_copy_into_valu.mir b/llvm/test/CodeGen/AMDGPU/fold_acc_copy_into_valu.mir
new file mode 100644
index 00000000000..11af6e19ecb
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/fold_acc_copy_into_valu.mir
@@ -0,0 +1,15 @@
+# RUN: llc -march=amdgcn -mcpu=gfx908 -o - -run-pass si-fix-sgpr-copies -verify-machineinstrs %s | FileCheck -check-prefix=GCN %s
+
+# GCN-LABEL: fold_acc_copy_into_valu
+# GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY %0.sub0
+# GCN: %2:vgpr_32 = V_AND_B32_e32 [[COPY]], undef %3:vgpr_32, implicit $exec
+---
+name: fold_acc_copy_into_valu
+body: |
+ bb.0.entry:
+
+ %0:areg_1024 = IMPLICIT_DEF
+ %1:sreg_32_xm0 = COPY %0.sub0
+ %3:vgpr_32 = V_AND_B32_e32 %1, undef %2:vgpr_32, implicit $exec
+
+...
diff --git a/llvm/test/CodeGen/AMDGPU/illegal-sgpr-to-vgpr-copy.ll b/llvm/test/CodeGen/AMDGPU/illegal-sgpr-to-vgpr-copy.ll
index abcf3342fcf..e7ad0bd0122 100644
--- a/llvm/test/CodeGen/AMDGPU/illegal-sgpr-to-vgpr-copy.ll
+++ b/llvm/test/CodeGen/AMDGPU/illegal-sgpr-to-vgpr-copy.ll
@@ -1,5 +1,5 @@
; RUN: not llc -march=amdgcn < %s 2>&1 | FileCheck -check-prefix=ERR %s
-; RUN: not llc -march=amdgcn < %s | FileCheck -check-prefix=GCN %s
+; RUN: not llc -march=amdgcn < %s 2>&1 | FileCheck -check-prefix=GCN %s
; ERR: error: <unknown>:0:0: in function illegal_vgpr_to_sgpr_copy_i32 void (): illegal SGPR to VGPR copy
; GCN: ; illegal copy v1 to s9
@@ -43,7 +43,8 @@ define amdgpu_kernel void @illegal_vgpr_to_sgpr_copy_v16i32() #0 {
}
; ERR: error: <unknown>:0:0: in function illegal_agpr_to_sgpr_copy_i32 void (): illegal SGPR to VGPR copy
-; GCN: ; illegal copy a1 to s9
+; GCN: v_accvgpr_read_b32 [[COPY1:v[0-9]+]], a1
+; GCN: ; illegal copy [[COPY1]] to s9
define amdgpu_kernel void @illegal_agpr_to_sgpr_copy_i32() #1 {
%agpr = call i32 asm sideeffect "; def $0", "=${a1}"()
call void asm sideeffect "; use $0", "${s9}"(i32 %agpr)
@@ -51,7 +52,9 @@ define amdgpu_kernel void @illegal_agpr_to_sgpr_copy_i32() #1 {
}
; ERR: error: <unknown>:0:0: in function illegal_agpr_to_sgpr_copy_v2i32 void (): illegal SGPR to VGPR copy
-; GCN: ; illegal copy a[0:1] to s[10:11]
+; GCN-DAG: v_accvgpr_read_b32 v[[COPY1L:[0-9]+]], a0
+; GCN-DAG: v_accvgpr_read_b32 v[[COPY1H:[0-9]+]], a1
+; GCN: ; illegal copy v{{\[}}[[COPY1L]]:[[COPY1H]]] to s[10:11]
define amdgpu_kernel void @illegal_agpr_to_sgpr_copy_v2i32() #1 {
%vgpr = call <2 x i32> asm sideeffect "; def $0", "=${a[0:1]}"()
call void asm sideeffect "; use $0", "${s[10:11]}"(<2 x i32> %vgpr)
OpenPOWER on IntegriCloud