Skip to content

Commit 63cb322

Browse files
committed
AMDGPU: Mark sendmsg intrinsics as norecurse
We cannot mark these as nocallback or nosync. These send a message to a host thread which could trigger arbitrary code. However this signaled code can't directly cause this thread to start recursing. FunctionAttrs manages to propagate norecurse to the caller, but attributor does not. Fixes #124802
1 parent 0f11011 commit 63cb322

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

llvm/include/llvm/IR/IntrinsicsAMDGPU.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,16 +237,16 @@ def int_amdgcn_reloc_constant : DefaultAttrsIntrinsic<
237237
// the second one is copied to m0
238238
def int_amdgcn_s_sendmsg : ClangBuiltin<"__builtin_amdgcn_s_sendmsg">,
239239
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty],
240-
[ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
240+
[ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects, IntrWillReturn, IntrNoRecurse]>;
241241
def int_amdgcn_s_sendmsghalt : ClangBuiltin<"__builtin_amdgcn_s_sendmsghalt">,
242242
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty],
243-
[ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects]>;
243+
[ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects, IntrNoRecurse]>;
244244

245245

246246
// gfx11 intrinsic
247247
// The first parameter is s_sendmsg immediate (i16). Return type is i32 or i64.
248248
def int_amdgcn_s_sendmsg_rtn : Intrinsic <[llvm_anyint_ty], [llvm_i32_ty],
249-
[ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
249+
[ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects, IntrWillReturn, IntrNoRecurse]>;
250250

251251
// Vanilla workgroup sync-barrier
252252
def int_amdgcn_s_barrier : ClangBuiltin<"__builtin_amdgcn_s_barrier">,
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2+
; RUN: opt -S -passes=function-attrs < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s
3+
; RUN: opt -S -passes=attributor-light < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s
4+
5+
; FIXME: attributor misses inferring norecurse
6+
define internal void @sendmsg_is_norecurse() {
7+
; FNATTRS: Function Attrs: mustprogress norecurse nounwind willreturn
8+
; FNATTRS-LABEL: define internal void @sendmsg_is_norecurse(
9+
; FNATTRS-SAME: ) #[[ATTR0:[0-9]+]] {
10+
; FNATTRS-NEXT: call void @llvm.amdgcn.s.sendmsg(i32 1, i32 0)
11+
; FNATTRS-NEXT: ret void
12+
;
13+
; ATTRIBUTOR: Function Attrs: mustprogress nounwind willreturn
14+
; ATTRIBUTOR-LABEL: define internal void @sendmsg_is_norecurse(
15+
; ATTRIBUTOR-SAME: ) #[[ATTR0:[0-9]+]] {
16+
; ATTRIBUTOR-NEXT: call void @llvm.amdgcn.s.sendmsg(i32 1, i32 0) #[[ATTR4:[0-9]+]]
17+
; ATTRIBUTOR-NEXT: ret void
18+
;
19+
call void @llvm.amdgcn.s.sendmsg(i32 1, i32 0)
20+
ret void
21+
}
22+
23+
define internal void @sendmsghalt_is_norecurse() {
24+
; FNATTRS: Function Attrs: norecurse nounwind
25+
; FNATTRS-LABEL: define internal void @sendmsghalt_is_norecurse(
26+
; FNATTRS-SAME: ) #[[ATTR1:[0-9]+]] {
27+
; FNATTRS-NEXT: call void @llvm.amdgcn.s.sendmsghalt(i32 1, i32 0)
28+
; FNATTRS-NEXT: ret void
29+
;
30+
; ATTRIBUTOR: Function Attrs: nounwind
31+
; ATTRIBUTOR-LABEL: define internal void @sendmsghalt_is_norecurse(
32+
; ATTRIBUTOR-SAME: ) #[[ATTR1:[0-9]+]] {
33+
; ATTRIBUTOR-NEXT: call void @llvm.amdgcn.s.sendmsghalt(i32 1, i32 0)
34+
; ATTRIBUTOR-NEXT: ret void
35+
;
36+
call void @llvm.amdgcn.s.sendmsghalt(i32 1, i32 0)
37+
ret void
38+
}
39+
40+
define internal i32 @sendmsg_rtn_is_norecurse() {
41+
; FNATTRS: Function Attrs: mustprogress norecurse nounwind willreturn
42+
; FNATTRS-LABEL: define internal i32 @sendmsg_rtn_is_norecurse(
43+
; FNATTRS-SAME: ) #[[ATTR0]] {
44+
; FNATTRS-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.s.sendmsg.rtn.i32(i32 1)
45+
; FNATTRS-NEXT: ret i32 [[RES]]
46+
;
47+
; ATTRIBUTOR: Function Attrs: mustprogress nounwind willreturn
48+
; ATTRIBUTOR-LABEL: define internal i32 @sendmsg_rtn_is_norecurse(
49+
; ATTRIBUTOR-SAME: ) #[[ATTR0]] {
50+
; ATTRIBUTOR-NEXT: [[RES:%.*]] = call i32 @llvm.amdgcn.s.sendmsg.rtn.i32(i32 1) #[[ATTR4]]
51+
; ATTRIBUTOR-NEXT: ret i32 [[RES]]
52+
;
53+
%res = call i32 @llvm.amdgcn.s.sendmsg.rtn(i32 1)
54+
ret i32 %res
55+
}
56+
57+
define void @user() {
58+
; FNATTRS-LABEL: define void @user() {
59+
; FNATTRS-NEXT: call void @sendmsg_is_norecurse()
60+
; FNATTRS-NEXT: call void @sendmsghalt_is_norecurse()
61+
; FNATTRS-NEXT: call void @sendmsg_rtn_is_norecurse()
62+
; FNATTRS-NEXT: ret void
63+
;
64+
; ATTRIBUTOR: Function Attrs: nounwind
65+
; ATTRIBUTOR-LABEL: define void @user(
66+
; ATTRIBUTOR-SAME: ) #[[ATTR1]] {
67+
; ATTRIBUTOR-NEXT: call void @sendmsg_is_norecurse() #[[ATTR5:[0-9]+]]
68+
; ATTRIBUTOR-NEXT: call void @sendmsghalt_is_norecurse() #[[ATTR1]]
69+
; ATTRIBUTOR-NEXT: call void @sendmsg_rtn_is_norecurse() #[[ATTR1]]
70+
; ATTRIBUTOR-NEXT: ret void
71+
;
72+
call void @sendmsg_is_norecurse()
73+
call void @sendmsghalt_is_norecurse()
74+
call void @sendmsg_rtn_is_norecurse()
75+
ret void
76+
}
77+
;.
78+
; FNATTRS: attributes #[[ATTR0]] = { mustprogress norecurse nounwind willreturn }
79+
; FNATTRS: attributes #[[ATTR1]] = { norecurse nounwind }
80+
; FNATTRS: attributes #[[ATTR2:[0-9]+]] = { norecurse nounwind willreturn }
81+
;.
82+
; ATTRIBUTOR: attributes #[[ATTR0]] = { mustprogress nounwind willreturn }
83+
; ATTRIBUTOR: attributes #[[ATTR1]] = { nounwind }
84+
; ATTRIBUTOR: attributes #[[ATTR2:[0-9]+]] = { norecurse nounwind willreturn }
85+
; ATTRIBUTOR: attributes #[[ATTR3:[0-9]+]] = { norecurse nounwind }
86+
; ATTRIBUTOR: attributes #[[ATTR4]] = { willreturn }
87+
; ATTRIBUTOR: attributes #[[ATTR5]] = { nounwind willreturn }
88+
;.
89+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
90+
; COMMON: {{.*}}

0 commit comments

Comments
 (0)