Skip to content

Commit 245e25f

Browse files
committed
AMDGPU: Implement isAsmClobberable
Warn on inline assembly clobbering reserved registers. It should also warn on at least some reserved register defs, but that isn't happening right now. If you have a def and re-use of a register we reserve, the register coalescer will eliminate the intermediate virtual register. When the reserved reg def is introduced later by the backend, it will end up clobbering the value the register coalescer assumed was live through the range. There is also isInlineAsmReadOnlyReg, although I don't understand what the distinction really is. It's called in SelectionDAGBuilder, long before the set of reserved registers is frozen so I'm not sure how that can possibly work reliably. Unfortunately this is also using the ugly tablegenerated names for the registers.
1 parent 979d0ee commit 245e25f

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,11 @@ BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
690690
return Reserved;
691691
}
692692

693+
bool SIRegisterInfo::isAsmClobberable(const MachineFunction &MF,
694+
MCRegister PhysReg) const {
695+
return !MF.getRegInfo().isReserved(PhysReg);
696+
}
697+
693698
bool SIRegisterInfo::shouldRealignStack(const MachineFunction &MF) const {
694699
const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
695700
// On entry, the base address is 0, so it can't possibly need any more

llvm/lib/Target/AMDGPU/SIRegisterInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
6464
MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
6565

6666
BitVector getReservedRegs(const MachineFunction &MF) const override;
67+
bool isAsmClobberable(const MachineFunction &MF,
68+
MCRegister PhysReg) const override;
6769

6870
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
6971
const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs -o /dev/null 2>&1 %s | FileCheck -check-prefix=ERR %s
2+
3+
; ERR: warning: inline asm clobber list contains reserved registers: VGPR42
4+
; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
5+
define amdgpu_kernel void @clobber_occupancy_limited_vgpr() #0 {
6+
entry:
7+
call void asm sideeffect "; clobber $0", "~{v42}"()
8+
ret void
9+
}
10+
11+
; ERR: warning: inline asm clobber list contains reserved registers: VGPR42_VGPR43
12+
; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
13+
define amdgpu_kernel void @clobber_occupancy_limited_vgpr64() #0 {
14+
entry:
15+
call void asm sideeffect "; clobber $0", "~{v[42:43]}"()
16+
ret void
17+
}
18+
19+
; ERR: warning: inline asm clobber list contains reserved registers: M0
20+
; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
21+
define amdgpu_kernel void @clobber_m0() {
22+
entry:
23+
call void asm sideeffect "; clobber $0", "~{m0}"()
24+
ret void
25+
}
26+
27+
; ERR: warning: inline asm clobber list contains reserved registers: EXEC
28+
; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
29+
define amdgpu_kernel void @clobber_exec() {
30+
entry:
31+
call void asm sideeffect "; clobber $0", "~{exec}"()
32+
ret void
33+
}
34+
35+
; ERR: warning: inline asm clobber list contains reserved registers: EXEC_LO
36+
; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
37+
define amdgpu_kernel void @clobber_exec_lo() {
38+
entry:
39+
call void asm sideeffect "; clobber $0", "~{exec_lo}"()
40+
ret void
41+
}
42+
43+
; FIXME: This should warn too
44+
; ERR-NOT: warning
45+
define amdgpu_kernel void @def_exec(i64 addrspace(1)* %ptr) {
46+
entry:
47+
%exec = call i64 asm sideeffect "; def $0", "={exec}"()
48+
store i64 %exec, i64 addrspace(1)* %ptr
49+
ret void
50+
}
51+
52+
attributes #0 = { "amdgpu-waves-per-eu"="10,10" }

0 commit comments

Comments
 (0)