forked from OSchip/llvm-project
[Attributor] Annotate the memory behavior of call site arguments
Especially for callbacks, annotating the call site arguments is important. Doing so exposed a too strong dependence of AAMemoryBehavior on AANoCapture since we handle the case of potentially captured pointers explicitly. The changes to the tests are all mechanical.
This commit is contained in:
parent
23a6ae2b06
commit
2888019871
|
@ -4933,7 +4933,8 @@ ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
|
|||
// it is, any information derived would be irrelevant anyway as we cannot
|
||||
// check the potential aliases introduced by the capture. However, no need
|
||||
// to fall back to anythign less optimistic than the function state.
|
||||
const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
|
||||
const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
|
||||
*this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
|
||||
if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
|
||||
S.intersectAssumedBits(FnMemAssumedState);
|
||||
return ChangeStatus::CHANGED;
|
||||
|
@ -5822,7 +5823,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
|
|||
getOrCreateAAFor<AAIsDead>(CSRetPos);
|
||||
}
|
||||
|
||||
for (int i = 0, e = Callee->arg_size(); i < e; i++) {
|
||||
for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
|
||||
|
||||
IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
|
||||
|
||||
|
@ -5847,6 +5848,10 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
|
|||
// Call site argument attribute "align".
|
||||
getOrCreateAAFor<AAAlign>(CSArgPos);
|
||||
|
||||
// Call site argument attribute
|
||||
// "readnone/readonly/writeonly/..."
|
||||
getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
|
||||
|
||||
// Call site argument attribute "nofree".
|
||||
getOrCreateAAFor<AANoFree>(CSArgPos);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ define i32 @f(i32 %x) {
|
|||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32
|
||||
; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[X_ADDR]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]])
|
||||
; CHECK-NEXT: ret i32 [[TMP1]]
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -34,7 +34,7 @@ F:
|
|||
|
||||
define i32 @foo() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@foo()
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nofree null)
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nofree readonly null)
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
%X = call i32 @callee(i1 false, i32* null) ; <i32> [#uses=1]
|
||||
|
|
|
@ -27,7 +27,7 @@ define void @no_promote(<4 x i64>* %arg) #1 {
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(32) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(32) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -65,7 +65,7 @@ define void @promote(<4 x i64>* %arg) #0 {
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(32) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(32) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
|
|
@ -28,7 +28,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -67,7 +67,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -106,7 +106,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -145,7 +145,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -184,7 +184,7 @@ define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -223,7 +223,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -262,7 +262,7 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %ar
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -301,7 +301,7 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %ar
|
|||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nocapture nofree nonnull writeonly align 32 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 32 dereferenceable(64) [[TMP]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
|
|
@ -36,7 +36,7 @@ define i32 @test(i32* %X) {
|
|||
; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
||||
; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4
|
||||
; CHECK-NEXT: call void @f(%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval [[X]], i32 zeroext 0)
|
||||
; CHECK-NEXT: call void @f(%struct.ss* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval [[X]], i32 zeroext 0)
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -21,7 +21,7 @@ define internal i32 @caller(i32* %B) {
|
|||
; CHECK-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i32
|
||||
; CHECK-NEXT: store i32 1, i32* [[A]], align 4
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%A = alloca i32
|
||||
|
@ -34,7 +34,7 @@ define i32 @callercaller() {
|
|||
; CHECK-LABEL: define {{[^@]+}}@callercaller()
|
||||
; CHECK-NEXT: [[B:%.*]] = alloca i32
|
||||
; CHECK-NEXT: store i32 2, i32* [[B]], align 4
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B]])
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
%B = alloca i32
|
||||
|
|
|
@ -33,7 +33,7 @@ define i32 @test(i32* %X) {
|
|||
; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
||||
; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4
|
||||
; CHECK-NEXT: call void @f(%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval [[X]])
|
||||
; CHECK-NEXT: call void @f(%struct.ss* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval [[X]])
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -51,8 +51,8 @@ define i32 @main() nounwind {
|
|||
; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
||||
; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4
|
||||
; CHECK-NEXT: call void @f(%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[S]])
|
||||
; CHECK-NEXT: call void @g(%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[S]])
|
||||
; CHECK-NEXT: call void @f(%struct.ss* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]])
|
||||
; CHECK-NEXT: call void @g(%struct.ss* noalias nocapture nofree nonnull readonly byval align 32 dereferenceable(12) [[S]])
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -21,7 +21,7 @@ entry:
|
|||
define i32 @caller() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller()
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @test(i32** nofree nonnull align 8 dereferenceable(8) @G2)
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @test(i32** nofree nonnull readonly align 8 dereferenceable(8) @G2)
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -26,7 +26,7 @@ F:
|
|||
define i32 @foo() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@foo()
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 true, i32* noalias nofree undef)
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 true, i32* noalias nofree readnone undef)
|
||||
; CHECK-NEXT: ret i32 17
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -10,7 +10,7 @@ define internal i32 @callee(i1 %C, i32* %P) {
|
|||
; CHECK: T:
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: F:
|
||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P:%.*]], align 4
|
||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
br i1 %C, label %T, label %F
|
||||
|
@ -27,7 +27,7 @@ define i32 @foo() {
|
|||
; CHECK-LABEL: define {{[^@]+}}@foo()
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i32
|
||||
; CHECK-NEXT: store i32 17, i32* [[A]], align 4
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
%A = alloca i32 ; <i32*> [#uses=2]
|
||||
|
|
|
@ -15,7 +15,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||
define void @run() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@run()
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @CaptureAStruct(%struct.Foo* nofree nonnull align 8 dereferenceable(16) @a)
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @CaptureAStruct(%struct.Foo* nofree nonnull readonly align 8 dereferenceable(16) @a)
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: entry.split:
|
||||
; CHECK-NEXT: unreachable
|
||||
|
|
|
@ -55,7 +55,7 @@ define i32 @main() {
|
|||
; GLOBALOPT_ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
||||
; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 1, i32* [[F0]], align 4
|
||||
; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 2, i32* [[F1]], align 4
|
||||
; GLOBALOPT_ATTRIBUTOR-NEXT: [[R:%.*]] = call fastcc i32 @f(%struct.ss* noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]])
|
||||
; GLOBALOPT_ATTRIBUTOR-NEXT: [[R:%.*]] = call fastcc i32 @f(%struct.ss* noalias nocapture nofree nonnull readonly align 4 dereferenceable(8) [[S]])
|
||||
; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 [[R]]
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -11,7 +11,7 @@ target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
|
|||
define i32 @bar() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@bar() addrspace(1)
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call addrspace(1) i32 @foo(i32* nofree nonnull align 4 dereferenceable(4) undef)
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call addrspace(1) i32 @foo(i32* nofree nonnull readnone align 4 dereferenceable(4) undef)
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: entry.split:
|
||||
; CHECK-NEXT: unreachable
|
||||
|
|
|
@ -23,7 +23,7 @@ define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
|
|||
; CHECK-NEXT: ret void
|
||||
; CHECK: cpad:
|
||||
; CHECK-NEXT: [[PAD:%.*]] = cleanuppad within none []
|
||||
; CHECK-NEXT: call void @callee(i8* noalias nofree undef) [ "funclet"(token [[PAD]]) ]
|
||||
; CHECK-NEXT: call void @callee(i8* noalias nofree readnone undef) [ "funclet"(token [[PAD]]) ]
|
||||
; CHECK-NEXT: cleanupret from [[PAD]] unwind to caller
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -10,7 +10,7 @@ define i32 @fn2() local_unnamed_addr {
|
|||
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32*
|
||||
; CHECK-NEXT: call fastcc void @fn1(i32* nofree [[TMP3]])
|
||||
; CHECK-NEXT: call fastcc void @fn1(i32* nofree readonly [[TMP3]])
|
||||
; CHECK-NEXT: ret i32 undef
|
||||
;
|
||||
%1 = load i32, i32* @b, align 4
|
||||
|
|
|
@ -8,7 +8,7 @@ define void @caller() #0 {
|
|||
; CHECK-LABEL: define {{[^@]+}}@caller()
|
||||
; CHECK-NEXT: [[X:%.*]] = alloca i32
|
||||
; CHECK-NEXT: store i32 42, i32* [[X]], align 4
|
||||
; CHECK-NEXT: call void @promote_i32_ptr(i32* noalias nocapture nonnull align 4 dereferenceable(4) [[X]]), !prof !0
|
||||
; CHECK-NEXT: call void @promote_i32_ptr(i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[X]]), !prof !0
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%x = alloca i32
|
||||
|
|
|
@ -40,7 +40,7 @@ define i32 @main() {
|
|||
; CHECK-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !7
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa !7
|
||||
; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !4
|
||||
; CHECK-NEXT: call fastcc void @fn(i32* nofree nonnull align 4 dereferenceable(4) @g, i64* nofree nonnull align 8 dereferenceable(8) undef)
|
||||
; CHECK-NEXT: call fastcc void @fn(i32* nofree nonnull readonly align 4 dereferenceable(4) @g, i64* nofree nonnull readonly align 8 dereferenceable(8) undef)
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -28,7 +28,7 @@ define void @f() {
|
|||
; CHECK-LABEL: define {{[^@]+}}@f()
|
||||
; CHECK-NEXT: [[R:%.*]] = alloca i32
|
||||
; CHECK-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }
|
||||
; CHECK-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret align 4 dereferenceable(4) [[R]])
|
||||
; CHECK-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%r = alloca i32
|
||||
|
|
|
@ -18,7 +18,7 @@ define i32 @main(i32 %argc, i8** nocapture readnone %argv) #0 {
|
|||
; CHECK-LABEL: define {{[^@]+}}@main
|
||||
; CHECK-SAME: (i32 [[ARGC:%.*]], i8** nocapture nofree readnone [[ARGV:%.*]])
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: tail call void (i8*, i8*, i8*, i8*, i8*, ...) @callee_t0f(i8* undef, i8* undef, i8* undef, i8* undef, i8* undef, %struct.tt0* byval align 8 @t45)
|
||||
; CHECK-NEXT: tail call void (i8*, i8*, i8*, i8*, i8*, ...) @callee_t0f(i8* undef, i8* undef, i8* undef, i8* undef, i8* undef, %struct.tt0* nonnull byval align 8 dereferenceable(16) @t45)
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -52,8 +52,8 @@ entry:
|
|||
define i32 @unions() nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@unions()
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @vfu1(%struct.MYstr* nofree nonnull byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* nofree nonnull byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: call void @vfu1(%struct.MYstr* nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: ret i32 [[RESULT]]
|
||||
;
|
||||
entry:
|
||||
|
@ -66,11 +66,11 @@ define internal i32 @vfu2_v2(%struct.MYstr* byval align 4 %u) nounwind readonly
|
|||
; CHECK-LABEL: define {{[^@]+}}@vfu2_v2
|
||||
; CHECK-SAME: (%struct.MYstr* nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]])
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* %u, i32 0, i32 1
|
||||
; CHECK-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1
|
||||
; CHECK-NEXT: store i32 99, i32* [[Z]], align 4
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* %u, i32 0, i32 1
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* %u, i32 0, i32 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
|
||||
|
@ -91,8 +91,8 @@ entry:
|
|||
define i32 @unions_v2() nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@unions_v2()
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @vfu1(%struct.MYstr* nofree nonnull byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* nofree nonnull byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: call void @vfu1(%struct.MYstr* nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
|
||||
; CHECK-NEXT: ret i32 [[RESULT]]
|
||||
;
|
||||
entry:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s
|
||||
;
|
||||
; void bar(int, float, double);
|
||||
;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --turn off
|
||||
; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
@ -130,12 +130,14 @@ define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
|
|||
ret i8* %6
|
||||
}
|
||||
|
||||
; UTC_ARGS: --turn=on
|
||||
|
||||
; TEST 7
|
||||
; Better than IR information
|
||||
define align 4 i32* @test7(i32* align 32 %p) #0 {
|
||||
; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7
|
||||
; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
|
||||
; ATTRIBUTOR-NEXT: ret i32* [[P:%.*]]
|
||||
; ATTRIBUTOR-NEXT: ret i32* [[P]]
|
||||
;
|
||||
tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
|
||||
ret i32* %p
|
||||
|
@ -144,13 +146,12 @@ define align 4 i32* @test7(i32* align 32 %p) #0 {
|
|||
; TEST 7b
|
||||
; Function Attrs: nounwind readnone ssp uwtable
|
||||
define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
|
||||
;
|
||||
; ATTRIBUTOR-LABEL: define {{[^@]+}}@f1b
|
||||
; ATTRIBUTOR-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
|
||||
; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0:%.*]], null
|
||||
; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
|
||||
; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
|
||||
; ATTRIBUTOR: 3:
|
||||
; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b(i8* nofree nonnull align 8 dereferenceable(1) @a1)
|
||||
; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b(i8* nofree nonnull readnone align 8 dereferenceable(1) @a1)
|
||||
; ATTRIBUTOR-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8
|
||||
; ATTRIBUTOR-NEXT: store i8 [[L]], i8* @a1, align 8
|
||||
; ATTRIBUTOR-NEXT: br label [[TMP5]]
|
||||
|
@ -180,10 +181,10 @@ define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
|
|||
; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* @a1, null
|
||||
; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
|
||||
; ATTRIBUTOR: 3:
|
||||
; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
|
||||
; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
|
||||
; ATTRIBUTOR-NEXT: br label [[TMP7:%.*]]
|
||||
; ATTRIBUTOR: 5:
|
||||
; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = tail call i8* @f3b(i8* nofree nonnull align 16 dereferenceable(1) @a2)
|
||||
; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = tail call i8* @f3b(i8* nofree nonnull readnone align 16 dereferenceable(1) @a2)
|
||||
; ATTRIBUTOR-NEXT: br label [[TMP7]]
|
||||
; ATTRIBUTOR: 7:
|
||||
; ATTRIBUTOR-NEXT: [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ]
|
||||
|
@ -214,7 +215,7 @@ define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
|
|||
; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* @a2, null
|
||||
; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
|
||||
; ATTRIBUTOR: 3:
|
||||
; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull align 16 dereferenceable(1) @a2)
|
||||
; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull readnone align 16 dereferenceable(1) @a2)
|
||||
; ATTRIBUTOR-NEXT: br label [[TMP5]]
|
||||
; ATTRIBUTOR: 5:
|
||||
; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ @a1, [[TMP1:%.*]] ]
|
||||
|
@ -235,13 +236,14 @@ define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
|
|||
define align 4 i32* @test7b(i32* align 32 %p) #0 {
|
||||
; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7b
|
||||
; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
|
||||
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* nofree nonnull align 8 dereferenceable(1) @a1)
|
||||
; ATTRIBUTOR-NEXT: ret i32* [[P:%.*]]
|
||||
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* nofree nonnull readnone align 8 dereferenceable(1) @a1)
|
||||
; ATTRIBUTOR-NEXT: ret i32* [[P]]
|
||||
;
|
||||
tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
|
||||
ret i32* %p
|
||||
}
|
||||
|
||||
; UTC_ARGS: --turn=off
|
||||
|
||||
; TEST 8
|
||||
define void @test8_helper() {
|
||||
|
@ -250,11 +252,11 @@ define void @test8_helper() {
|
|||
%ptr2 = tail call align 8 i32* @unknown()
|
||||
|
||||
tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
|
||||
; ATTRIBUTOR: tail call void @test8(i32* align 4 %ptr1, i32* align 4 %ptr1, i32* %ptr0)
|
||||
; ATTRIBUTOR: tail call void @test8(i32* readnone align 4 %ptr1, i32* readnone align 4 %ptr1, i32* readnone %ptr0)
|
||||
tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
|
||||
; ATTRIBUTOR: tail call void @test8(i32* align 8 %ptr2, i32* align 4 %ptr1, i32* align 4 %ptr1)
|
||||
; ATTRIBUTOR: tail call void @test8(i32* readnone align 8 %ptr2, i32* readnone align 4 %ptr1, i32* readnone align 4 %ptr1)
|
||||
tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
|
||||
; ATTRIBUTOR: tail call void @test8(i32* align 8 %ptr2, i32* align 4 %ptr1, i32* align 4 %ptr1)
|
||||
; ATTRIBUTOR: tail call void @test8(i32* readnone align 8 %ptr2, i32* readnone align 4 %ptr1, i32* readnone align 4 %ptr1)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
@ -339,7 +341,7 @@ define i64 @test11(i32* %p) {
|
|||
}
|
||||
|
||||
; TEST 12
|
||||
; Test for deduction using must-be-executed-context and GEP instruction
|
||||
; Test for deduction using must-be-executed-context and GEP instruction
|
||||
|
||||
; FXIME: %p should have nonnull
|
||||
; ATTRIBUTOR: define i64 @test12-1(i32* nocapture nofree readonly align 16 %p)
|
||||
|
@ -366,7 +368,7 @@ define void @test12-3(i32* align 4 %p) {
|
|||
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
|
||||
%arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
|
||||
store i64 0, i64* %arrayidx1, align 16
|
||||
ret void
|
||||
ret void
|
||||
}
|
||||
|
||||
; ATTRIBUTOR: define void @test12-4(i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) %p)
|
||||
|
@ -374,7 +376,7 @@ define void @test12-4(i32* align 4 %p) {
|
|||
%p-cast = bitcast i32* %p to i64*
|
||||
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
|
||||
store i64 0, i64* %arrayidx0, align 16
|
||||
ret void
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @use(i64*) willreturn nounwind
|
||||
|
@ -385,7 +387,7 @@ define void @test12-5(i32* align 4 %p) {
|
|||
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
|
||||
%arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
|
||||
tail call void @use(i64* align 16 %arrayidx1)
|
||||
ret void
|
||||
ret void
|
||||
}
|
||||
|
||||
; ATTRIBUTOR: define void @test12-6(i32* align 16 %p)
|
||||
|
@ -393,7 +395,7 @@ define void @test12-6(i32* align 4 %p) {
|
|||
%p-cast = bitcast i32* %p to i64*
|
||||
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
|
||||
tail call void @use(i64* align 16 %arrayidx0)
|
||||
ret void
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind uwtable noinline }
|
||||
|
|
|
@ -768,7 +768,7 @@ define internal void @useless_arg_sink(i32* %a) {
|
|||
|
||||
; CHECK: define internal void @useless_arg_almost_sink(i32* nocapture nofree readnone %a)
|
||||
define internal void @useless_arg_almost_sink(i32* %a) {
|
||||
; CHECK: call void @useless_arg_sink(i32* nofree undef)
|
||||
; CHECK: call void @useless_arg_sink(i32* nofree readnone undef)
|
||||
call void @useless_arg_sink(i32* %a)
|
||||
ret void
|
||||
}
|
||||
|
@ -776,7 +776,7 @@ define internal void @useless_arg_almost_sink(i32* %a) {
|
|||
; Check we do not annotate the function interface of this weak function.
|
||||
; CHECK: define weak_odr void @useless_arg_ext(i32* %a)
|
||||
define weak_odr void @useless_arg_ext(i32* %a) {
|
||||
; CHECK: call void @useless_arg_almost_sink(i32* nofree undef)
|
||||
; CHECK: call void @useless_arg_almost_sink(i32* nofree readnone undef)
|
||||
call void @useless_arg_almost_sink(i32* %a)
|
||||
ret void
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ define internal void @internal(void (i8*)* %fp) {
|
|||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
|
||||
; CHECK-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
|
||||
; CHECK-NEXT: call void [[FP:%.*]](i8* bitcast (void (i32*)* @foo to i8*))
|
||||
; CHECK-NEXT: call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
|
||||
; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
|
||||
; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
|
||||
; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
|
||||
; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
|
||||
|
@ -24,7 +24,7 @@ define internal void @internal(void (i8*)* %fp) {
|
|||
; DECL_CS-NEXT: entry:
|
||||
; DECL_CS-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
; DECL_CS-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
|
||||
; DECL_CS-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
|
||||
; DECL_CS-NEXT: call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
|
||||
; DECL_CS-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
|
||||
; DECL_CS-NEXT: call void @callback1(void (i32*)* nonnull @foo)
|
||||
; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
|
||||
|
@ -52,7 +52,7 @@ define void @external(void (i8*)* %fp) {
|
|||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
|
||||
; CHECK-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
|
||||
; CHECK-NEXT: call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
|
||||
; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
|
||||
; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
|
||||
; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
|
||||
|
@ -67,7 +67,7 @@ define void @external(void (i8*)* %fp) {
|
|||
; DECL_CS-NEXT: entry:
|
||||
; DECL_CS-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
; DECL_CS-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
|
||||
; DECL_CS-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
|
||||
; DECL_CS-NEXT: call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
|
||||
; DECL_CS-NEXT: call void @callback1(void (i32*)* nonnull @foo)
|
||||
; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
|
||||
; DECL_CS-NEXT: call void @callback2(void (i8*)* [[FP]])
|
||||
|
@ -92,10 +92,10 @@ entry:
|
|||
}
|
||||
|
||||
define internal void @foo(i32* %a) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@foo
|
||||
; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]])
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
; ALL-LABEL: define {{[^@]+}}@foo
|
||||
; ALL-SAME: (i32* nocapture nofree readnone [[A:%.*]])
|
||||
; ALL-NEXT: entry:
|
||||
; ALL-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
ret void
|
||||
|
|
|
@ -199,14 +199,14 @@ bb1: ; preds = %bb
|
|||
|
||||
bb4: ; preds = %bb1
|
||||
%tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
|
||||
; ATTRIBUTOR: %tmp5b = tail call nonnull i32* @f3(i32* nofree nonnull %tmp5)
|
||||
; ATTRIBUTOR: %tmp5b = tail call nonnull i32* @f3(i32* nofree nonnull readonly %tmp5)
|
||||
%tmp5b = tail call i32* @f3(i32* %tmp5)
|
||||
%tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1
|
||||
br label %bb9
|
||||
|
||||
bb6: ; preds = %bb1
|
||||
; FIXME: missing nonnull. It should be @f2(i32* nonnull %arg)
|
||||
; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* nofree %arg)
|
||||
; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* nofree readonly %arg)
|
||||
%tmp7 = tail call i32* @f2(i32* %arg)
|
||||
ret i32* %tmp7
|
||||
|
||||
|
@ -221,7 +221,7 @@ define internal i32* @f2(i32* %arg) {
|
|||
bb:
|
||||
|
||||
; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
|
||||
; ATTRIBUTOR: %tmp = tail call nonnull i32* @f1(i32* nofree %arg)
|
||||
; ATTRIBUTOR: %tmp = tail call nonnull i32* @f1(i32* nofree readonly %arg)
|
||||
%tmp = tail call i32* @f1(i32* %arg)
|
||||
ret i32* %tmp
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ define dso_local noalias i32* @f3(i32* %arg) {
|
|||
; ATTRIBUTOR: define dso_local noalias nonnull i32* @f3(i32* nofree readonly %arg)
|
||||
bb:
|
||||
; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
|
||||
; ATTRIBUTOR: %tmp = call nonnull i32* @f1(i32* nofree %arg)
|
||||
; ATTRIBUTOR: %tmp = call nonnull i32* @f1(i32* nofree readonly %arg)
|
||||
%tmp = call i32* @f1(i32* %arg)
|
||||
ret i32* %tmp
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ define i8 @parent7(i8* %a) {
|
|||
|
||||
|
||||
; ATTRIBUTOR-LABEL: @parent7(i8* nonnull %a)
|
||||
; ATTRIBUTOR-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull %a)
|
||||
; ATTRIBUTOR-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly %a)
|
||||
; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
|
||||
|
||||
; ATTRIBUTOR-NEXT: ret i8 [[RET]]
|
||||
|
|
|
@ -210,7 +210,7 @@ define internal i32* @test_inalloca(i32* inalloca %a) {
|
|||
}
|
||||
define i32* @complicated_args_inalloca() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@complicated_args_inalloca()
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree null)
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree writeonly null)
|
||||
; CHECK-NEXT: ret i32* [[CALL]]
|
||||
;
|
||||
%call = call i32* @test_inalloca(i32* null)
|
||||
|
@ -229,7 +229,7 @@ define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
|
|||
define void @complicated_args_sret(%struct.X** %b) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@complicated_args_sret
|
||||
; CHECK-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]])
|
||||
; CHECK-NEXT: call void @test_sret(%struct.X* nofree null, %struct.X** nocapture nofree writeonly [[B]])
|
||||
; CHECK-NEXT: call void @test_sret(%struct.X* nofree writeonly null, %struct.X** nocapture nofree writeonly [[B]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @test_sret(%struct.X* null, %struct.X** %b)
|
||||
|
@ -245,7 +245,7 @@ define internal %struct.X* @test_nest(%struct.X* nest %a) {
|
|||
}
|
||||
define %struct.X* @complicated_args_nest() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@complicated_args_nest()
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nofree null)
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nofree readnone null)
|
||||
; CHECK-NEXT: ret %struct.X* [[CALL]]
|
||||
;
|
||||
%call = call %struct.X* @test_nest(%struct.X* null)
|
||||
|
@ -266,7 +266,7 @@ define internal void @test_byval(%struct.X* byval %a) {
|
|||
}
|
||||
define void @complicated_args_byval() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval()
|
||||
; CHECK-NEXT: call void @test_byval(%struct.X* nofree nonnull align 8 dereferenceable(8) @S)
|
||||
; CHECK-NEXT: call void @test_byval(%struct.X* nofree nonnull readonly align 8 dereferenceable(8) @S)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @test_byval(%struct.X* @S)
|
||||
|
|
Loading…
Reference in New Issue