Skip to content

Commit a20fb93

Browse files
committed
[Attributor][NFC] Pre-commit test that exposes a bug
The functions should return 8, not 10, see TODOs.
1 parent a665cee commit a20fb93

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed

llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3176,6 +3176,216 @@ define internal i32 @recSimplify2() {
31763176
ret i32 %r
31773177
}
31783178

3179+
; TODO: Verify we do not return 10.
3180+
define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) {
3181+
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3182+
; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return
3183+
; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] {
3184+
; TUNIT-NEXT: entry:
3185+
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3186+
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3187+
; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR18]]
3188+
; TUNIT-NEXT: ret i32 10
3189+
;
3190+
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
3191+
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return
3192+
; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] {
3193+
; CGSCC-NEXT: entry:
3194+
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3195+
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3196+
; CGSCC-NEXT: call void @write_both(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR21]]
3197+
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3198+
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3199+
; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3200+
; CGSCC-NEXT: ret i32 [[ADD]]
3201+
;
3202+
entry:
3203+
%A = alloca i32, align 4
3204+
%B = alloca i32, align 4
3205+
%call = call ptr @passthrough(ptr noundef %A)
3206+
%call1 = call ptr @passthrough(ptr noundef %B)
3207+
call void @write_both(ptr noundef %call, ptr noundef %call1)
3208+
%0 = load i32, ptr %A, align 4
3209+
%1 = load i32, ptr %B, align 4
3210+
%add = add nsw i32 %0, %1
3211+
ret i32 %add
3212+
}
3213+
3214+
define internal void @write_both(ptr noundef %Q, ptr noundef %R) {
3215+
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
3216+
; CHECK-LABEL: define {{[^@]+}}@write_both
3217+
; CHECK-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Q:%.*]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0]] {
3218+
; CHECK-NEXT: entry:
3219+
; CHECK-NEXT: store i32 3, ptr [[Q]], align 4
3220+
; CHECK-NEXT: store i32 5, ptr [[R]], align 4
3221+
; CHECK-NEXT: ret void
3222+
;
3223+
entry:
3224+
store i32 3, ptr %Q, align 4
3225+
store i32 5, ptr %R, align 4
3226+
ret void
3227+
}
3228+
3229+
define internal ptr @passthrough(ptr noundef %P) {
3230+
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3231+
; CGSCC-LABEL: define {{[^@]+}}@passthrough
3232+
; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
3233+
; CGSCC-NEXT: entry:
3234+
; CGSCC-NEXT: ret ptr [[P]]
3235+
;
3236+
entry:
3237+
ret ptr %P
3238+
}
3239+
3240+
; TODO: Verify we do not return 10.
3241+
define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c) {
3242+
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3243+
; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_choice
3244+
; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR4]] {
3245+
; TUNIT-NEXT: entry:
3246+
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3247+
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3248+
; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR23:[0-9]+]]
3249+
; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
3250+
; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL1]]) #[[ATTR18]]
3251+
; TUNIT-NEXT: ret i32 10
3252+
;
3253+
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
3254+
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_choice
3255+
; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR3]] {
3256+
; CGSCC-NEXT: entry:
3257+
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3258+
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3259+
; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR28:[0-9]+]]
3260+
; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR28]]
3261+
; CGSCC-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL1]]) #[[ATTR21]]
3262+
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3263+
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3264+
; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3265+
; CGSCC-NEXT: ret i32 [[ADD]]
3266+
;
3267+
entry:
3268+
%A = alloca i32, align 4
3269+
%B = alloca i32, align 4
3270+
%call = call ptr @passthrough_choice(i1 %c, ptr noundef %A, ptr noundef %B)
3271+
%call1 = call ptr @passthrough_choice(i1 %c, ptr noundef %B, ptr noundef %A)
3272+
call void @write_both(ptr noundef %call, ptr noundef %call1)
3273+
%0 = load i32, ptr %A, align 4
3274+
%1 = load i32, ptr %B, align 4
3275+
%add = add nsw i32 %0, %1
3276+
ret i32 %add
3277+
}
3278+
3279+
define internal ptr @passthrough_choice(i1 %c, ptr noundef %P, ptr noundef %Q) {
3280+
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3281+
; CHECK-LABEL: define {{[^@]+}}@passthrough_choice
3282+
; CHECK-SAME: (i1 [[C:%.*]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] {
3283+
; CHECK-NEXT: entry:
3284+
; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], ptr [[P]], ptr [[Q]]
3285+
; CHECK-NEXT: ret ptr [[R]]
3286+
;
3287+
entry:
3288+
%R = select i1 %c, ptr %P, ptr %Q
3289+
ret ptr %R
3290+
}
3291+
3292+
; TODO: Verify we do not return 10.
3293+
define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) {
3294+
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3295+
; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1
3296+
; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] {
3297+
; TUNIT-NEXT: entry:
3298+
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3299+
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3300+
; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR18]]
3301+
; TUNIT-NEXT: ret i32 10
3302+
;
3303+
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
3304+
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1
3305+
; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] {
3306+
; CGSCC-NEXT: entry:
3307+
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3308+
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3309+
; CGSCC-NEXT: call void @write_both(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR21]]
3310+
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3311+
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3312+
; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3313+
; CGSCC-NEXT: ret i32 [[ADD]]
3314+
;
3315+
entry:
3316+
%A = alloca i32, align 4
3317+
%B = alloca i32, align 4
3318+
%call = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %A, ptr noundef %B)
3319+
%call1 = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %B, ptr noundef %A)
3320+
call void @write_both(ptr noundef %call, ptr noundef %call1)
3321+
%0 = load i32, ptr %A, align 4
3322+
%1 = load i32, ptr %B, align 4
3323+
%add = add nsw i32 %0, %1
3324+
ret i32 %add
3325+
}
3326+
3327+
; TODO: Verify we do not return 10.
3328+
define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) {
3329+
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3330+
; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2
3331+
; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] {
3332+
; TUNIT-NEXT: entry:
3333+
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3334+
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3335+
; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR18]]
3336+
; TUNIT-NEXT: ret i32 10
3337+
;
3338+
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
3339+
; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2
3340+
; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] {
3341+
; CGSCC-NEXT: entry:
3342+
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3343+
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3344+
; CGSCC-NEXT: call void @write_both(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]], ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR21]]
3345+
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3346+
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3347+
; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3348+
; CGSCC-NEXT: ret i32 [[ADD]]
3349+
;
3350+
entry:
3351+
%A = alloca i32, align 4
3352+
%B = alloca i32, align 4
3353+
%call = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %A, ptr noundef %B)
3354+
%call1 = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %B, ptr noundef %A)
3355+
call void @write_both(ptr noundef %call, ptr noundef %call1)
3356+
%0 = load i32, ptr %A, align 4
3357+
%1 = load i32, ptr %B, align 4
3358+
%add = add nsw i32 %0, %1
3359+
ret i32 %add
3360+
}
3361+
3362+
define internal ptr @passthrough_no_choice_true(i1 %c, ptr noundef %P, ptr noundef %Q) {
3363+
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3364+
; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_true
3365+
; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], i32 [[TMP0:%.*]]) #[[ATTR4]] {
3366+
; CGSCC-NEXT: entry:
3367+
; CGSCC-NEXT: [[Q_PRIV:%.*]] = alloca i32, align 4
3368+
; CGSCC-NEXT: store i32 [[TMP0]], ptr [[Q_PRIV]], align 4
3369+
; CGSCC-NEXT: ret ptr [[P]]
3370+
;
3371+
entry:
3372+
%R = select i1 %c, ptr %P, ptr %Q
3373+
ret ptr %R
3374+
}
3375+
define internal ptr @passthrough_no_choice_false(i1 %c, ptr noundef %P, ptr noundef %Q) {
3376+
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3377+
; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_false
3378+
; CGSCC-SAME: (i32 [[TMP0:%.*]], ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] {
3379+
; CGSCC-NEXT: entry:
3380+
; CGSCC-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4
3381+
; CGSCC-NEXT: store i32 [[TMP0]], ptr [[P_PRIV]], align 4
3382+
; CGSCC-NEXT: ret ptr [[Q]]
3383+
;
3384+
entry:
3385+
%R = select i1 %c, ptr %P, ptr %Q
3386+
ret ptr %R
3387+
}
3388+
31793389
declare void @llvm.assume(i1 noundef)
31803390

31813391

@@ -3238,6 +3448,7 @@ declare void @llvm.assume(i1 noundef)
32383448
; TUNIT: attributes #[[ATTR20]] = { norecurse }
32393449
; TUNIT: attributes #[[ATTR21]] = { nounwind }
32403450
; TUNIT: attributes #[[ATTR22]] = { nofree nosync nounwind willreturn }
3451+
; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn memory(none) }
32413452
;.
32423453
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
32433454
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -3267,6 +3478,7 @@ declare void @llvm.assume(i1 noundef)
32673478
; CGSCC: attributes #[[ATTR25]] = { nofree nounwind }
32683479
; CGSCC: attributes #[[ATTR26]] = { nofree nounwind willreturn }
32693480
; CGSCC: attributes #[[ATTR27]] = { nofree }
3481+
; CGSCC: attributes #[[ATTR28]] = { nofree nosync willreturn }
32703482
;.
32713483
; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
32723484
; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1}

0 commit comments

Comments
 (0)