diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index a1751c0ee3e48..601f2e5192d0d 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -720,6 +720,10 @@ CaptureInfo CallBase::getCaptureInfo(unsigned OpNo) const { return CI; } + // Bundles on assumes are captures(none). + if (getIntrinsicID() == Intrinsic::assume) + return CaptureInfo::none(); + // deopt operand bundles are captures(none) auto &BOI = getBundleOpInfoForOperand(OpNo); auto OBU = operandBundleFromBundleOpInfo(BOI); diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll index 9f9bc118fa525..60a4214548a72 100644 --- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll @@ -46,7 +46,7 @@ define void @c3(ptr %q) { ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) ; ATTRIBUTOR-LABEL: define void @c3 ; ATTRIBUTOR-SAME: (ptr nofree writeonly [[Q:%.*]]) #[[ATTR1]] { -; ATTRIBUTOR-NEXT: call void @c2(ptr nofree writeonly [[Q]]) #[[ATTR19:[0-9]+]] +; ATTRIBUTOR-NEXT: call void @c2(ptr nofree writeonly [[Q]]) #[[ATTR21:[0-9]+]] ; ATTRIBUTOR-NEXT: ret void ; call void @c2(ptr %q) @@ -232,7 +232,7 @@ define i1 @c7(ptr %q, i32 %bitno) { ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read) ; ATTRIBUTOR-LABEL: define i1 @c7 ; ATTRIBUTOR-SAME: (ptr nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] { -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = call ptr @lookup_bit(ptr nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR20:[0-9]+]] +; ATTRIBUTOR-NEXT: [[PTR:%.*]] = call ptr @lookup_bit(ptr nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR22:[0-9]+]] ; ATTRIBUTOR-NEXT: [[VAL:%.*]] = load i1, ptr [[PTR]], align 1 ; ATTRIBUTOR-NEXT: ret i1 [[VAL]] ; @@ -337,7 +337,7 @@ define void @nc2(ptr %p, ptr %q) { ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn ; ATTRIBUTOR-LABEL: define void @nc2 ; ATTRIBUTOR-SAME: (ptr nofree captures(none) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR5]] { -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i32 @nc1(ptr nofree [[Q]], ptr nofree captures(none) [[P]], i1 false) #[[ATTR21:[0-9]+]] +; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i32 @nc1(ptr nofree [[Q]], ptr nofree captures(none) [[P]], i1 false) #[[ATTR23:[0-9]+]] ; ATTRIBUTOR-NEXT: ret void ; %1 = call i32 @nc1(ptr %q, ptr %p, i1 0) ; [#uses=0] @@ -389,7 +389,7 @@ define void @readonly_nounwind_willreturn(ptr %p) { ; ATTRIBUTOR: Function Attrs: mustprogress nosync nounwind willreturn memory(read) ; ATTRIBUTOR-LABEL: define void @readonly_nounwind_willreturn ; ATTRIBUTOR-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR9:[0-9]+]] { -; ATTRIBUTOR-NEXT: call void @external_willreturn(ptr readonly captures(none) [[P]]) #[[ATTR22:[0-9]+]] +; ATTRIBUTOR-NEXT: call void @external_willreturn(ptr readonly captures(none) [[P]]) #[[ATTR24:[0-9]+]] ; ATTRIBUTOR-NEXT: ret void ; call void @external_willreturn(ptr %p) @@ -732,7 +732,7 @@ define void @nocaptureLaunder(ptr %p) { ; ATTRIBUTOR-LABEL: define void @nocaptureLaunder ; ATTRIBUTOR-SAME: (ptr nofree captures(none) [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR23:[0-9]+]] +; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR25:[0-9]+]] ; ATTRIBUTOR-NEXT: store i8 42, ptr [[B]], align 1 ; ATTRIBUTOR-NEXT: ret void ; @@ -754,7 +754,7 @@ define void @captureLaunder(ptr %p) { ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn ; ATTRIBUTOR-LABEL: define void @captureLaunder ; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR5]] { -; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR23]] +; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR25]] ; ATTRIBUTOR-NEXT: store ptr [[B]], ptr @g2, align 8 ; ATTRIBUTOR-NEXT: ret void ; @@ -776,7 +776,7 @@ define void @nocaptureStrip(ptr %p) { ; ATTRIBUTOR-LABEL: define void @nocaptureStrip ; ATTRIBUTOR-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR13:[0-9]+]] { ; ATTRIBUTOR-NEXT: entry: -; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR20]] +; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR22]] ; ATTRIBUTOR-NEXT: store i8 42, ptr [[B]], align 1 ; ATTRIBUTOR-NEXT: ret void ; @@ -798,7 +798,7 @@ define void @captureStrip(ptr %p) { ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) ; ATTRIBUTOR-LABEL: define void @captureStrip ; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR1]] { -; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR20]] +; ATTRIBUTOR-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR22]] ; ATTRIBUTOR-NEXT: store ptr [[B]], ptr @g3, align 8 ; ATTRIBUTOR-NEXT: ret void ; @@ -1033,13 +1033,13 @@ define void @readnone_indirec(ptr %f, ptr %p) { ; FNATTRS: Function Attrs: nofree nosync memory(none) ; FNATTRS-LABEL: define void @readnone_indirec ; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr readnone captures(address) [[P:%.*]]) #[[ATTR19:[0-9]+]] { -; FNATTRS-NEXT: call void [[F]](ptr [[P]]) #[[ATTR23:[0-9]+]] +; FNATTRS-NEXT: call void [[F]](ptr [[P]]) #[[ATTR25:[0-9]+]] ; FNATTRS-NEXT: ret void ; ; ATTRIBUTOR: Function Attrs: nosync memory(none) ; ATTRIBUTOR-LABEL: define void @readnone_indirec ; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[F:%.*]], ptr readnone [[P:%.*]]) #[[ATTR15:[0-9]+]] { -; ATTRIBUTOR-NEXT: call void [[F]](ptr [[P]]) #[[ATTR24:[0-9]+]] +; ATTRIBUTOR-NEXT: call void [[F]](ptr [[P]]) #[[ATTR26:[0-9]+]] ; ATTRIBUTOR-NEXT: ret void ; call void %f(ptr %p) readnone @@ -1347,5 +1347,56 @@ exit: ret void } +define void @assume_align(ptr %p) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) +; FNATTRS-LABEL: define void @assume_align +; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21:[0-9]+]] { +; FNATTRS-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ] +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) +; ATTRIBUTOR-LABEL: define void @assume_align +; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[P:%.*]]) #[[ATTR17:[0-9]+]] { +; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #[[ATTR27:[0-9]+]] [ "align"(ptr [[P]], i64 8) ] +; ATTRIBUTOR-NEXT: ret void +; + call void @llvm.assume(i1 true) ["align"(ptr %p, i64 8)] + ret void +} + +define void @assume_dereferenceable(ptr %p) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) +; FNATTRS-LABEL: define void @assume_dereferenceable +; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21]] { +; FNATTRS-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 8) ] +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) +; ATTRIBUTOR-LABEL: define void @assume_dereferenceable +; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[P:%.*]]) #[[ATTR17]] { +; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #[[ATTR27]] [ "dereferenceable"(ptr [[P]], i64 8) ] +; ATTRIBUTOR-NEXT: ret void +; + call void @llvm.assume(i1 true) ["dereferenceable"(ptr %p, i64 8)] + ret void +} + +define void @assume_nonnull(ptr %p) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) +; FNATTRS-LABEL: define void @assume_nonnull +; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21]] { +; FNATTRS-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]) ] +; FNATTRS-NEXT: ret void +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) +; ATTRIBUTOR-LABEL: define void @assume_nonnull +; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[P:%.*]]) #[[ATTR17]] { +; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #[[ATTR27]] [ "nonnull"(ptr [[P]]) ] +; ATTRIBUTOR-NEXT: ret void +; + call void @llvm.assume(i1 true) ["nonnull"(ptr %p)] + ret void +} + declare ptr @llvm.launder.invariant.group.p0(ptr) declare ptr @llvm.strip.invariant.group.p0(ptr) diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/infer-align-from-assumption.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/infer-align-from-assumption.ll index 889f25c79c10f..4196625e6bd21 100644 --- a/llvm/test/Transforms/PhaseOrdering/AArch64/infer-align-from-assumption.ll +++ b/llvm/test/Transforms/PhaseOrdering/AArch64/infer-align-from-assumption.ll @@ -50,7 +50,7 @@ define i32 @earlycse_fn1(ptr %p) { define i32 @load_assume_aligned(ptr %p) { ; CHECK-LABEL: define i32 @load_assume_aligned( -; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr { +; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) local_unnamed_addr { ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 4) ] ; CHECK-NEXT: [[DOT0_COPYLOAD:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD]]) @@ -66,7 +66,7 @@ declare i32 @swap(i32) define void @sroa_align_entry(ptr %p) { ; CHECK-LABEL: define void @sroa_align_entry( -; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ] ; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I:%.*]] = load i64, ptr [[P]], align 8 ; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[DOT0_COPYLOAD_I_I_I]] to ptr @@ -96,7 +96,7 @@ define ptr @sroa_fn1(ptr %p) { define ptr @sroa_fn2(ptr %p) { ; CHECK-LABEL: define ptr @sroa_fn2( -; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ] ; CHECK-NEXT: [[DOT0_COPYLOAD_I_I:%.*]] = load i64, ptr [[P]], align 8 ; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[DOT0_COPYLOAD_I_I]] to ptr @@ -109,7 +109,7 @@ define ptr @sroa_fn2(ptr %p) { define i64 @sroa_fn3(ptr %0) { ; CHECK-LABEL: define i64 @sroa_fn3( -; CHECK-SAME: ptr [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] { +; CHECK-SAME: ptr readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] { ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP0]], i64 8) ] ; CHECK-NEXT: [[DOT0_COPYLOAD_I:%.*]] = load i64, ptr [[TMP0]], align 8 ; CHECK-NEXT: ret i64 [[DOT0_COPYLOAD_I]]