Skip to content

Commit 3e65c30

Browse files
authored
[Lint][AMDGPU] No store to const addrspace (#109181)
Ensure store to const addrspace is not allowed by Linter.
1 parent a068b97 commit 3e65c30

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed

llvm/include/llvm/Support/AMDGPUAddrSpace.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,33 @@ inline bool isExtendedGlobalAddrSpace(unsigned AS) {
9393
AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT ||
9494
AS > AMDGPUAS::MAX_AMDGPU_ADDRESS;
9595
}
96+
97+
inline bool isConstantAddressSpace(unsigned AS) {
98+
switch (AS) {
99+
using namespace AMDGPUAS;
100+
case CONSTANT_ADDRESS:
101+
case CONSTANT_ADDRESS_32BIT:
102+
case CONSTANT_BUFFER_0:
103+
case CONSTANT_BUFFER_1:
104+
case CONSTANT_BUFFER_2:
105+
case CONSTANT_BUFFER_3:
106+
case CONSTANT_BUFFER_4:
107+
case CONSTANT_BUFFER_5:
108+
case CONSTANT_BUFFER_6:
109+
case CONSTANT_BUFFER_7:
110+
case CONSTANT_BUFFER_8:
111+
case CONSTANT_BUFFER_9:
112+
case CONSTANT_BUFFER_10:
113+
case CONSTANT_BUFFER_11:
114+
case CONSTANT_BUFFER_12:
115+
case CONSTANT_BUFFER_13:
116+
case CONSTANT_BUFFER_14:
117+
case CONSTANT_BUFFER_15:
118+
return true;
119+
default:
120+
return false;
121+
}
122+
}
96123
} // end namespace AMDGPU
97124

98125
} // end namespace llvm

llvm/lib/Analysis/Lint.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "llvm/IR/PassManager.h"
6868
#include "llvm/IR/Type.h"
6969
#include "llvm/IR/Value.h"
70+
#include "llvm/Support/AMDGPUAddrSpace.h"
7071
#include "llvm/Support/Casting.h"
7172
#include "llvm/Support/KnownBits.h"
7273
#include "llvm/Support/raw_ostream.h"
@@ -102,6 +103,8 @@ class Lint : public InstVisitor<Lint> {
102103
void visitReturnInst(ReturnInst &I);
103104
void visitLoadInst(LoadInst &I);
104105
void visitStoreInst(StoreInst &I);
106+
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I);
107+
void visitAtomicRMWInst(AtomicRMWInst &I);
105108
void visitXor(BinaryOperator &I);
106109
void visitSub(BinaryOperator &I);
107110
void visitLShr(BinaryOperator &I);
@@ -124,6 +127,7 @@ class Lint : public InstVisitor<Lint> {
124127

125128
public:
126129
Module *Mod;
130+
Triple TT;
127131
const DataLayout *DL;
128132
AliasAnalysis *AA;
129133
AssumptionCache *AC;
@@ -135,8 +139,8 @@ class Lint : public InstVisitor<Lint> {
135139

136140
Lint(Module *Mod, const DataLayout *DL, AliasAnalysis *AA,
137141
AssumptionCache *AC, DominatorTree *DT, TargetLibraryInfo *TLI)
138-
: Mod(Mod), DL(DL), AA(AA), AC(AC), DT(DT), TLI(TLI),
139-
MessagesStr(Messages) {}
142+
: Mod(Mod), TT(Triple::normalize(Mod->getTargetTriple())), DL(DL), AA(AA),
143+
AC(AC), DT(DT), TLI(TLI), MessagesStr(Messages) {}
140144

141145
void WriteValues(ArrayRef<const Value *> Vs) {
142146
for (const Value *V : Vs) {
@@ -401,6 +405,11 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
401405
"Unusual: Address one pointer dereference", &I);
402406

403407
if (Flags & MemRef::Write) {
408+
if (TT.isAMDGPU())
409+
Check(!AMDGPU::isConstantAddressSpace(
410+
UnderlyingObject->getType()->getPointerAddressSpace()),
411+
"Undefined behavior: Write to memory in const addrspace", &I);
412+
404413
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject))
405414
Check(!GV->isConstant(), "Undefined behavior: Write to read-only memory",
406415
&I);
@@ -480,6 +489,16 @@ void Lint::visitStoreInst(StoreInst &I) {
480489
I.getOperand(0)->getType(), MemRef::Write);
481490
}
482491

492+
void Lint::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
493+
visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
494+
I.getOperand(0)->getType(), MemRef::Write);
495+
}
496+
497+
void Lint::visitAtomicRMWInst(AtomicRMWInst &I) {
498+
visitMemoryReference(I, MemoryLocation::get(&I), I.getAlign(),
499+
I.getOperand(0)->getType(), MemRef::Write);
500+
}
501+
483502
void Lint::visitXor(BinaryOperator &I) {
484503
Check(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
485504
"Undefined result: xor(undef, undef)", &I);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; RUN: not opt --mtriple=amdgcn --passes=lint --lint-abort-on-error %s -disable-output 2>&1 | FileCheck %s
2+
; RUN: opt --mtriple=amdgcn --mcpu=gfx1030 --passes=lint %s -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK0
3+
; RUN: opt --mtriple=x86_64 --passes=lint --lint-abort-on-error %s -disable-output 2>&1 | FileCheck %s --allow-empty --check-prefix=NOERR
4+
; NOERR: {{^$}}
5+
6+
define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) {
7+
; CHECK: Undefined behavior: Write to memory in const addrspace
8+
; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out
9+
%r = add i32 %a, %b
10+
store i32 %r, ptr addrspace(4) %out
11+
ret void
12+
}
13+
14+
declare void @llvm.memset.p4.i64(ptr addrspace(4) noalias nocapture writeonly, i8, i64, i1)
15+
define amdgpu_kernel void @memset_const(ptr addrspace(4) %dst) {
16+
; CHECK0: Undefined behavior: Write to memory in const addrspace
17+
; CHECK0-NEXT: call void @llvm.memset.p4.i64(ptr addrspace(4) %dst, i8 0, i64 256, i1 false)
18+
call void @llvm.memset.p4.i64(ptr addrspace(4) %dst, i8 0, i64 256, i1 false)
19+
ret void
20+
}
21+
22+
declare void @llvm.memcpy.p6.p0.i32(ptr addrspace(6) noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1)
23+
define amdgpu_kernel void @memcpy_to_const(ptr addrspace(6) %dst, ptr %src) {
24+
; CHECK0: Undefined behavior: Write to memory in const addrspace
25+
; CHECK0-NEXT: call void @llvm.memcpy.p6.p0.i32(ptr addrspace(6) %dst, ptr %src, i32 256, i1 false)
26+
call void @llvm.memcpy.p6.p0.i32(ptr addrspace(6) %dst, ptr %src, i32 256, i1 false)
27+
ret void
28+
}
29+
30+
define amdgpu_kernel void @cmpxchg_to_const(ptr addrspace(4) %dst, i32 %src) {
31+
; CHECK0: Undefined behavior: Write to memory in const addrspace
32+
; CHECK0-NEXT: %void = cmpxchg ptr addrspace(4) %dst, i32 0, i32 %src seq_cst monotonic
33+
%void = cmpxchg ptr addrspace(4) %dst, i32 0, i32 %src seq_cst monotonic
34+
ret void
35+
}
36+
37+
define amdgpu_kernel void @atomicrmw_to_const(ptr addrspace(4) %dst, i32 %src) {
38+
; CHECK0: Undefined behavior: Write to memory in const addrspace
39+
; CHECK0-NEXT: %void = atomicrmw add ptr addrspace(4) %dst, i32 %src acquire
40+
%void = atomicrmw add ptr addrspace(4) %dst, i32 %src acquire
41+
ret void
42+
}
43+
44+
declare void @const_param(ptr addrspace(6))
45+
define amdgpu_kernel void @call_with_const(ptr addrspace(6) %dst) {
46+
; CHECK0-NOT: call void @const_param(ptr addrspace(6) %dst)
47+
call void @const_param(ptr addrspace(6) %dst)
48+
ret void
49+
}

0 commit comments

Comments
 (0)