Skip to content

Commit 9690a71

Browse files
authored
[IR][CaptureTracking] Consider assume operand bundles captures(none) (llvm#159083)
Something like `call void @llvm.assume(i1 true) ["align"(ptr %p, i64 8)]` is equivalent to placing an `align 8` attribute on the parameter and should not be considered as capturing.
1 parent 07a7928 commit 9690a71

File tree

3 files changed

+69
-14
lines changed

3 files changed

+69
-14
lines changed

llvm/lib/IR/Instructions.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,10 @@ CaptureInfo CallBase::getCaptureInfo(unsigned OpNo) const {
720720
return CI;
721721
}
722722

723+
// Bundles on assumes are captures(none).
724+
if (getIntrinsicID() == Intrinsic::assume)
725+
return CaptureInfo::none();
726+
723727
// deopt operand bundles are captures(none)
724728
auto &BOI = getBundleOpInfoForOperand(OpNo);
725729
auto OBU = operandBundleFromBundleOpInfo(BOI);

llvm/test/Transforms/FunctionAttrs/nocapture.ll

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ define void @c3(ptr %q) {
4646
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
4747
; ATTRIBUTOR-LABEL: define void @c3
4848
; ATTRIBUTOR-SAME: (ptr nofree writeonly [[Q:%.*]]) #[[ATTR1]] {
49-
; ATTRIBUTOR-NEXT: call void @c2(ptr nofree writeonly [[Q]]) #[[ATTR19:[0-9]+]]
49+
; ATTRIBUTOR-NEXT: call void @c2(ptr nofree writeonly [[Q]]) #[[ATTR21:[0-9]+]]
5050
; ATTRIBUTOR-NEXT: ret void
5151
;
5252
call void @c2(ptr %q)
@@ -232,7 +232,7 @@ define i1 @c7(ptr %q, i32 %bitno) {
232232
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
233233
; ATTRIBUTOR-LABEL: define i1 @c7
234234
; ATTRIBUTOR-SAME: (ptr nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] {
235-
; ATTRIBUTOR-NEXT: [[PTR:%.*]] = call ptr @lookup_bit(ptr nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR20:[0-9]+]]
235+
; ATTRIBUTOR-NEXT: [[PTR:%.*]] = call ptr @lookup_bit(ptr nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR22:[0-9]+]]
236236
; ATTRIBUTOR-NEXT: [[VAL:%.*]] = load i1, ptr [[PTR]], align 1
237237
; ATTRIBUTOR-NEXT: ret i1 [[VAL]]
238238
;
@@ -337,7 +337,7 @@ define void @nc2(ptr %p, ptr %q) {
337337
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
338338
; ATTRIBUTOR-LABEL: define void @nc2
339339
; ATTRIBUTOR-SAME: (ptr nofree captures(none) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR5]] {
340-
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i32 @nc1(ptr nofree [[Q]], ptr nofree captures(none) [[P]], i1 false) #[[ATTR21:[0-9]+]]
340+
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i32 @nc1(ptr nofree [[Q]], ptr nofree captures(none) [[P]], i1 false) #[[ATTR23:[0-9]+]]
341341
; ATTRIBUTOR-NEXT: ret void
342342
;
343343
%1 = call i32 @nc1(ptr %q, ptr %p, i1 0) ; <i32> [#uses=0]
@@ -389,7 +389,7 @@ define void @readonly_nounwind_willreturn(ptr %p) {
389389
; ATTRIBUTOR: Function Attrs: mustprogress nosync nounwind willreturn memory(read)
390390
; ATTRIBUTOR-LABEL: define void @readonly_nounwind_willreturn
391391
; ATTRIBUTOR-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR9:[0-9]+]] {
392-
; ATTRIBUTOR-NEXT: call void @external_willreturn(ptr readonly captures(none) [[P]]) #[[ATTR22:[0-9]+]]
392+
; ATTRIBUTOR-NEXT: call void @external_willreturn(ptr readonly captures(none) [[P]]) #[[ATTR24:[0-9]+]]
393393
; ATTRIBUTOR-NEXT: ret void
394394
;
395395
call void @external_willreturn(ptr %p)
@@ -732,7 +732,7 @@ define void @nocaptureLaunder(ptr %p) {
732732
; ATTRIBUTOR-LABEL: define void @nocaptureLaunder
733733
; ATTRIBUTOR-SAME: (ptr nofree captures(none) [[P:%.*]]) #[[ATTR12:[0-9]+]] {
734734
; ATTRIBUTOR-NEXT: entry:
735-
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR23:[0-9]+]]
735+
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR25:[0-9]+]]
736736
; ATTRIBUTOR-NEXT: store i8 42, ptr [[B]], align 1
737737
; ATTRIBUTOR-NEXT: ret void
738738
;
@@ -754,7 +754,7 @@ define void @captureLaunder(ptr %p) {
754754
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
755755
; ATTRIBUTOR-LABEL: define void @captureLaunder
756756
; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR5]] {
757-
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR23]]
757+
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR25]]
758758
; ATTRIBUTOR-NEXT: store ptr [[B]], ptr @g2, align 8
759759
; ATTRIBUTOR-NEXT: ret void
760760
;
@@ -776,7 +776,7 @@ define void @nocaptureStrip(ptr %p) {
776776
; ATTRIBUTOR-LABEL: define void @nocaptureStrip
777777
; ATTRIBUTOR-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR13:[0-9]+]] {
778778
; ATTRIBUTOR-NEXT: entry:
779-
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR20]]
779+
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR22]]
780780
; ATTRIBUTOR-NEXT: store i8 42, ptr [[B]], align 1
781781
; ATTRIBUTOR-NEXT: ret void
782782
;
@@ -798,7 +798,7 @@ define void @captureStrip(ptr %p) {
798798
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
799799
; ATTRIBUTOR-LABEL: define void @captureStrip
800800
; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR1]] {
801-
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR20]]
801+
; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR22]]
802802
; ATTRIBUTOR-NEXT: store ptr [[B]], ptr @g3, align 8
803803
; ATTRIBUTOR-NEXT: ret void
804804
;
@@ -1033,13 +1033,13 @@ define void @readnone_indirec(ptr %f, ptr %p) {
10331033
; FNATTRS: Function Attrs: nofree nosync memory(none)
10341034
; FNATTRS-LABEL: define void @readnone_indirec
10351035
; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr readnone captures(address) [[P:%.*]]) #[[ATTR19:[0-9]+]] {
1036-
; FNATTRS-NEXT: call void [[F]](ptr [[P]]) #[[ATTR23:[0-9]+]]
1036+
; FNATTRS-NEXT: call void [[F]](ptr [[P]]) #[[ATTR25:[0-9]+]]
10371037
; FNATTRS-NEXT: ret void
10381038
;
10391039
; ATTRIBUTOR: Function Attrs: nosync memory(none)
10401040
; ATTRIBUTOR-LABEL: define void @readnone_indirec
10411041
; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[F:%.*]], ptr readnone [[P:%.*]]) #[[ATTR15:[0-9]+]] {
1042-
; ATTRIBUTOR-NEXT: call void [[F]](ptr [[P]]) #[[ATTR24:[0-9]+]]
1042+
; ATTRIBUTOR-NEXT: call void [[F]](ptr [[P]]) #[[ATTR26:[0-9]+]]
10431043
; ATTRIBUTOR-NEXT: ret void
10441044
;
10451045
call void %f(ptr %p) readnone
@@ -1347,5 +1347,56 @@ exit:
13471347
ret void
13481348
}
13491349

1350+
define void @assume_align(ptr %p) {
1351+
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
1352+
; FNATTRS-LABEL: define void @assume_align
1353+
; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21:[0-9]+]] {
1354+
; FNATTRS-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
1355+
; FNATTRS-NEXT: ret void
1356+
;
1357+
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
1358+
; ATTRIBUTOR-LABEL: define void @assume_align
1359+
; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[P:%.*]]) #[[ATTR17:[0-9]+]] {
1360+
; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #[[ATTR27:[0-9]+]] [ "align"(ptr [[P]], i64 8) ]
1361+
; ATTRIBUTOR-NEXT: ret void
1362+
;
1363+
call void @llvm.assume(i1 true) ["align"(ptr %p, i64 8)]
1364+
ret void
1365+
}
1366+
1367+
define void @assume_dereferenceable(ptr %p) {
1368+
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
1369+
; FNATTRS-LABEL: define void @assume_dereferenceable
1370+
; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21]] {
1371+
; FNATTRS-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 8) ]
1372+
; FNATTRS-NEXT: ret void
1373+
;
1374+
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
1375+
; ATTRIBUTOR-LABEL: define void @assume_dereferenceable
1376+
; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[P:%.*]]) #[[ATTR17]] {
1377+
; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #[[ATTR27]] [ "dereferenceable"(ptr [[P]], i64 8) ]
1378+
; ATTRIBUTOR-NEXT: ret void
1379+
;
1380+
call void @llvm.assume(i1 true) ["dereferenceable"(ptr %p, i64 8)]
1381+
ret void
1382+
}
1383+
1384+
define void @assume_nonnull(ptr %p) {
1385+
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
1386+
; FNATTRS-LABEL: define void @assume_nonnull
1387+
; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21]] {
1388+
; FNATTRS-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]) ]
1389+
; FNATTRS-NEXT: ret void
1390+
;
1391+
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
1392+
; ATTRIBUTOR-LABEL: define void @assume_nonnull
1393+
; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[P:%.*]]) #[[ATTR17]] {
1394+
; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #[[ATTR27]] [ "nonnull"(ptr [[P]]) ]
1395+
; ATTRIBUTOR-NEXT: ret void
1396+
;
1397+
call void @llvm.assume(i1 true) ["nonnull"(ptr %p)]
1398+
ret void
1399+
}
1400+
13501401
declare ptr @llvm.launder.invariant.group.p0(ptr)
13511402
declare ptr @llvm.strip.invariant.group.p0(ptr)

llvm/test/Transforms/PhaseOrdering/AArch64/infer-align-from-assumption.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ define i32 @earlycse_fn1(ptr %p) {
5050

5151
define i32 @load_assume_aligned(ptr %p) {
5252
; CHECK-LABEL: define i32 @load_assume_aligned(
53-
; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr {
53+
; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) local_unnamed_addr {
5454
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 4) ]
5555
; CHECK-NEXT: [[DOT0_COPYLOAD:%.*]] = load i32, ptr [[P]], align 4
5656
; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD]])
@@ -66,7 +66,7 @@ declare i32 @swap(i32)
6666

6767
define void @sroa_align_entry(ptr %p) {
6868
; CHECK-LABEL: define void @sroa_align_entry(
69-
; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
69+
; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
7070
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
7171
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I:%.*]] = load i64, ptr [[P]], align 8
7272
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[DOT0_COPYLOAD_I_I_I]] to ptr
@@ -96,7 +96,7 @@ define ptr @sroa_fn1(ptr %p) {
9696

9797
define ptr @sroa_fn2(ptr %p) {
9898
; CHECK-LABEL: define ptr @sroa_fn2(
99-
; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
99+
; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
100100
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
101101
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I:%.*]] = load i64, ptr [[P]], align 8
102102
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[DOT0_COPYLOAD_I_I]] to ptr
@@ -109,7 +109,7 @@ define ptr @sroa_fn2(ptr %p) {
109109

110110
define i64 @sroa_fn3(ptr %0) {
111111
; CHECK-LABEL: define i64 @sroa_fn3(
112-
; CHECK-SAME: ptr [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] {
112+
; CHECK-SAME: ptr readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] {
113113
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP0]], i64 8) ]
114114
; CHECK-NEXT: [[DOT0_COPYLOAD_I:%.*]] = load i64, ptr [[TMP0]], align 8
115115
; CHECK-NEXT: ret i64 [[DOT0_COPYLOAD_I]]

0 commit comments

Comments
 (0)