diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll index 621c6cf94313e..516b80b1e237b 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -59,12 +59,12 @@ define i32 @main() nounwind { ; TUNIT-NEXT: store i32 1, ptr [[S]], align 32 ; TUNIT-NEXT: [[VAL4:%.*]] = getelementptr [[STRUCT_SS]], ptr [[S]], i32 0, i32 1 ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[S]], align 8 -; TUNIT-NEXT: [[S_B41:%.*]] = getelementptr i8, ptr [[S]], i64 4 -; TUNIT-NEXT: [[TMP1:%.*]] = load i64, ptr [[S_B41]], align 8 +; TUNIT-NEXT: [[S_B4:%.*]] = getelementptr i8, ptr [[S]], i64 4 +; TUNIT-NEXT: [[TMP1:%.*]] = load i64, ptr [[S_B4]], align 8 ; TUNIT-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[S]], align 32 -; TUNIT-NEXT: [[S_B4:%.*]] = getelementptr i8, ptr [[S]], i64 4 -; TUNIT-NEXT: [[TMP3:%.*]] = load i64, ptr [[S_B4]], align 32 +; TUNIT-NEXT: [[S_B41:%.*]] = getelementptr i8, ptr [[S]], i64 4 +; TUNIT-NEXT: [[TMP3:%.*]] = load i64, ptr [[S_B41]], align 32 ; TUNIT-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) #[[ATTR1]] ; TUNIT-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] ; TUNIT-NEXT: ret i32 [[A]] diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll index a209ee2ebe064..249119a77a4d0 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -139,12 +139,12 @@ define i32 @unions_v2() nounwind { ; TUNIT-SAME: () #[[ATTR2]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[TMP0:%.*]] = load i8, ptr @mystr, align 8 -; TUNIT-NEXT: [[MYSTR_B4:%.*]] = getelementptr i8, ptr @mystr, i64 4 -; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[MYSTR_B4]], align 8 +; TUNIT-NEXT: [[MYSTR_B41:%.*]] = getelementptr i8, ptr @mystr, i64 4 +; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[MYSTR_B41]], align 8 ; TUNIT-NEXT: call void @vfu1(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR2]] ; TUNIT-NEXT: [[TMP2:%.*]] = load i8, ptr @mystr, align 8 -; TUNIT-NEXT: [[MYSTR_B41:%.*]] = getelementptr i8, ptr @mystr, i64 4 -; TUNIT-NEXT: [[TMP3:%.*]] = load i32, ptr [[MYSTR_B41]], align 8 +; TUNIT-NEXT: [[MYSTR_B4:%.*]] = getelementptr i8, ptr @mystr, i64 4 +; TUNIT-NEXT: [[TMP3:%.*]] = load i32, ptr [[MYSTR_B4]], align 8 ; TUNIT-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR3]] ; TUNIT-NEXT: ret i32 [[RESULT]] ; diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll index 343b6b9dd433c..d1c331ce19651 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll @@ -62,13 +62,13 @@ define %0 @caller(i1 %Q) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller ; TUNIT-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] [[FOO:@[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR1:[0-9]+]] +; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @[[FOO:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: ret [[TMP0]] [[X]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller ; CGSCC-SAME: (i1 noundef [[Q:%.*]]) #[[ATTR1:[0-9]+]] { -; CGSCC-NEXT: [[X:%.*]] = call [[TMP0:%.*]] [[FOO:@[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR2:[0-9]+]] +; CGSCC-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @[[FOO:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR2:[0-9]+]] ; CGSCC-NEXT: ret [[TMP0]] [[X]] ; %X = call %0 @foo(i1 %Q) @@ -87,10 +87,10 @@ define i32 @caller2(i1 %Q) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@caller2 ; TUNIT-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] [[FOO:@[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR1]] +; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @[[FOO]](i1 noundef [[Q]]) #[[ATTR1]] ; TUNIT-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0 ; TUNIT-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1 -; TUNIT-NEXT: [[Y:%.*]] = call [[TMP0]] [[BAR:@[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR1]] +; TUNIT-NEXT: [[Y:%.*]] = call [[TMP0]] @[[BAR:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR1]] ; TUNIT-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0 ; TUNIT-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1 ; TUNIT-NEXT: [[M:%.*]] = add i32 [[A]], [[C]] @@ -101,10 +101,10 @@ define i32 @caller2(i1 %Q) { ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@caller2 ; CGSCC-SAME: (i1 noundef [[Q:%.*]]) #[[ATTR1]] { -; CGSCC-NEXT: [[X:%.*]] = call [[TMP0:%.*]] [[FOO:@[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR2]] +; CGSCC-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @[[FOO]](i1 noundef [[Q]]) #[[ATTR2]] ; CGSCC-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0 ; CGSCC-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1 -; CGSCC-NEXT: [[Y:%.*]] = call [[TMP0]] [[BAR:@[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR2]] +; CGSCC-NEXT: [[Y:%.*]] = call [[TMP0]] @[[BAR:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](i1 noundef [[Q]]) #[[ATTR2]] ; CGSCC-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0 ; CGSCC-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1 ; CGSCC-NEXT: [[M:%.*]] = add i32 [[A]], [[C]] diff --git a/llvm/test/Transforms/Attributor/assumes_info.ll b/llvm/test/Transforms/Attributor/assumes_info.ll index df7d7ddd13356..088739ec5b812 100644 --- a/llvm/test/Transforms/Attributor/assumes_info.ll +++ b/llvm/test/Transforms/Attributor/assumes_info.ll @@ -119,9 +119,11 @@ attributes #3 = { "llvm.assume"="B,C,A" } ; TUNIT: attributes #[[ATTR0]] = { "llvm.assume"="A" } ; TUNIT: attributes #[[ATTR1]] = { "llvm.assume"="A,B" } ; TUNIT: attributes #[[ATTR2]] = { "llvm.assume"="A,B,C" } +; TUNIT: attributes #[[ATTR3:[0-9]+]] = { "llvm.assume"="B,C,A" } ;. ; CGSCC: attributes #[[ATTR0]] = { "llvm.assume"="A" } ; CGSCC: attributes #[[ATTR1]] = { "llvm.assume"="A,B" } ; CGSCC: attributes #[[ATTR2]] = { "llvm.assume"="A,B,C" } ; CGSCC: attributes #[[ATTR3]] = { "llvm.assume"="B" } +; CGSCC: attributes #[[ATTR4:[0-9]+]] = { "llvm.assume"="B,C,A" } ;. diff --git a/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll b/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll index f8f374ab66141..2f64cdbca2010 100644 --- a/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll +++ b/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll @@ -189,6 +189,7 @@ define i32 @test_ncheck2(i32 %0) #0 { attributes #0 = { noinline nounwind sspstrong uwtable} +;. ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable } ; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn memory(none) } ;. diff --git a/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll b/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll index 32c08ee92ddef..585b6ef10c4fe 100644 --- a/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll +++ b/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll @@ -192,6 +192,7 @@ define i32 @test_ncheck2(i32 %0) #0 { attributes #0 = { noinline nounwind sspstrong uwtable} +;. ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable } ; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn memory(none) } ;. diff --git a/llvm/test/Transforms/Attributor/phi_bug_pointer_info.ll b/llvm/test/Transforms/Attributor/phi_bug_pointer_info.ll index bb423e10f2c72..b4a2192c25faa 100644 --- a/llvm/test/Transforms/Attributor/phi_bug_pointer_info.ll +++ b/llvm/test/Transforms/Attributor/phi_bug_pointer_info.ll @@ -17,7 +17,30 @@ ; CHECK: - c: %1 = load i32, ptr %val2, align 4 ; CHECK: - 6 - %ret = load i32, ptr %x, align 4 ; CHECK: - c: +;. +; CHECK: @globalBytes = internal global [1024 x i8] zeroinitializer +;. define dso_local i32 @phi_different_offsets(ptr nocapture %val, ptr nocapture %val2, i1 %cmp) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn +; CHECK-LABEL: define dso_local i32 @phi_different_offsets +; CHECK-SAME: (ptr nocapture nofree readonly [[VAL:%.*]], ptr nocapture nofree readonly [[VAL2:%.*]], i1 noundef [[CMP:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: [[FIELD2:%.*]] = getelementptr i32, ptr @globalBytes, i32 2 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4 +; CHECK-NEXT: store i32 [[TMP0]], ptr [[FIELD2]], align 8 +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: else: +; CHECK-NEXT: [[FIELD8:%.*]] = getelementptr i32, ptr @globalBytes, i32 8 +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[VAL2]], align 4 +; CHECK-NEXT: store i32 [[TMP1]], ptr [[FIELD8]], align 16 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[X:%.*]] = phi ptr [ [[FIELD2]], [[THEN]] ], [ [[FIELD8]], [[ELSE]] ] +; CHECK-NEXT: [[RET:%.*]] = load i32, ptr [[X]], align 8 +; CHECK-NEXT: ret i32 [[RET]] +; entry: br i1 %cmp, label %then, label %else @@ -39,3 +62,6 @@ end: ret i32 %ret } +;. +; CHECK: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn } +;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll index 20b52c3fcd85a..9ff51e97d6e15 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll @@ -106,7 +106,7 @@ define ptr @t2(ptr %this, ptr %this.addr, ptr %this1) { ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @foo.1(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4:[0-9]+]] +; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[FOO_1:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4:[0-9]+]] ; TUNIT-NEXT: [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; TUNIT-NEXT: ret ptr [[TEST_RET]] ; @@ -115,7 +115,7 @@ define ptr @t2(ptr %this, ptr %this.addr, ptr %this1) { ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2:[0-9]+]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @foo.1(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8:[0-9]+]] +; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[FOO_1:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8:[0-9]+]] ; CGSCC-NEXT: [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; CGSCC-NEXT: ret ptr [[TEST_RET]] ; @@ -205,7 +205,7 @@ define ptr @foo(ptr %this, ptr %this.addr, ptr %this1) { ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @bar.5(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]] +; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[BAR_5:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]] ; TUNIT-NEXT: [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; TUNIT-NEXT: ret ptr [[FOO_RET]] ; @@ -214,7 +214,7 @@ define ptr @foo(ptr %this, ptr %this.addr, ptr %this1) { ; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2]] { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @bar.5(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] +; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[BAR_5:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] ; CGSCC-NEXT: [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0 ; CGSCC-NEXT: ret ptr [[FOO_RET]] ; @@ -317,7 +317,7 @@ define weak_odr void @t3() { ; CHECK: for.cond: ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: -; CHECK-NEXT: [[CALL4:%.*]] = call [[S_2:%.*]] @t3.helper() +; CHECK-NEXT: [[CALL4:%.*]] = call [[S_2:%.*]] @[[T3_HELPER:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]]() ; CHECK-NEXT: ret void ; entry: @@ -380,8 +380,8 @@ define dso_local void @spam() { ; TUNIT-NEXT: store i32 [[X]], ptr [[TMP]], align 4 ; TUNIT-NEXT: br label [[BB16:%.*]] ; TUNIT: bb16: -; TUNIT-NEXT: [[TRUETMP18:%.*]] = icmp eq i32 [[X]], 0 -; TUNIT-NEXT: br i1 [[TRUETMP18]], label [[BB35:%.*]], label [[BB19:%.*]] +; TUNIT-NEXT: [[TMP18:%.*]] = icmp eq i32 [[X]], 0 +; TUNIT-NEXT: br i1 [[TMP18]], label [[BB35:%.*]], label [[BB19:%.*]] ; TUNIT: bb19: ; TUNIT-NEXT: br label [[BB23:%.*]] ; TUNIT: bb23: @@ -404,8 +404,8 @@ define dso_local void @spam() { ; CGSCC-NEXT: store i32 [[X]], ptr [[TMP]], align 4 ; CGSCC-NEXT: br label [[BB16:%.*]] ; CGSCC: bb16: -; CGSCC-NEXT: [[TRUETMP18:%.*]] = icmp eq i32 [[X]], 0 -; CGSCC-NEXT: br i1 [[TRUETMP18]], label [[BB35:%.*]], label [[BB19:%.*]] +; CGSCC-NEXT: [[TMP18:%.*]] = icmp eq i32 [[X]], 0 +; CGSCC-NEXT: br i1 [[TMP18]], label [[BB35:%.*]], label [[BB19:%.*]] ; CGSCC: bb19: ; CGSCC-NEXT: br label [[BB23:%.*]] ; CGSCC: bb23: @@ -467,7 +467,7 @@ define double @t4(ptr %this, ptr %this.addr, ptr %this1) { ; TUNIT-NEXT: entry: ; TUNIT-NEXT: [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]] +; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[T4A:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]] ; TUNIT-NEXT: ret double 0.000000e+00 ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) @@ -476,7 +476,7 @@ define double @t4(ptr %this, ptr %this.addr, ptr %this1) { ; CGSCC-NEXT: entry: ; CGSCC-NEXT: [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 -; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] +; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[T4A:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]] ; CGSCC-NEXT: [[TMP0:%.*]] = extractvalue [[S]] [[CALL]], 0 ; CGSCC-NEXT: ret double 0.000000e+00 ; @@ -615,12 +615,21 @@ entry: ; CGSCC: attributes #[[ATTR8]] = { nofree nounwind willreturn } ; CGSCC: attributes #[[ATTR9]] = { nofree nounwind willreturn memory(readwrite) } ;. -; CHECK: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]} -; CHECK: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} -; CHECK: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50} -; CHECK: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50} -; CHECK: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2} -; CHECK: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2} -; CHECK: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2} -; CHECK: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3} +; TUNIT: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]} +; TUNIT: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +; TUNIT: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50} +; TUNIT: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50} +; TUNIT: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2} +; TUNIT: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2} +; TUNIT: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2} +; TUNIT: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3} +;. +; CGSCC: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]} +; CGSCC: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +; CGSCC: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50} +; CGSCC: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50} +; CGSCC: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2} +; CGSCC: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2} +; CGSCC: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2} +; CGSCC: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3} ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll index 06a52ce936eec..f7f92e3c87a62 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -3176,6 +3176,216 @@ define internal i32 @recSimplify2() { ret i32 %r } +; TODO: Verify we do not return 10. +define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) { +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return +; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 +; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]] +; TUNIT-NEXT: ret i32 10 +; +; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return +; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 +; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]] +; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; CGSCC-NEXT: ret i32 [[ADD]] +; +entry: + %A = alloca i32, align 4 + %B = alloca i32, align 4 + %call = call ptr @passthrough(ptr noundef %A) + %call1 = call ptr @passthrough(ptr noundef %B) + call void @write_both(ptr noundef %call, ptr noundef %call1) + %0 = load i32, ptr %A, align 4 + %1 = load i32, ptr %B, align 4 + %add = add nsw i32 %0, %1 + ret i32 %add +} + +define internal void @write_both(ptr noundef %Q, ptr noundef %R) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) +; CHECK-LABEL: define {{[^@]+}}@write_both +; 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]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: store i32 3, ptr [[Q]], align 4 +; CHECK-NEXT: store i32 5, ptr [[R]], align 4 +; CHECK-NEXT: ret void +; +entry: + store i32 3, ptr %Q, align 4 + store i32 5, ptr %R, align 4 + ret void +} + +define internal ptr @passthrough(ptr noundef %P) { +; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@passthrough +; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: ret ptr [[P]] +; +entry: + ret ptr %P +} + +; TODO: Verify we do not return 10. +define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c) { +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_choice +; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR4]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 +; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]+]] +; 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]] +; 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]] +; TUNIT-NEXT: ret i32 10 +; +; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn +; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_choice +; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR3]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 +; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]+]] +; 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]] +; 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]] +; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; CGSCC-NEXT: ret i32 [[ADD]] +; +entry: + %A = alloca i32, align 4 + %B = alloca i32, align 4 + %call = call ptr @passthrough_choice(i1 %c, ptr noundef %A, ptr noundef %B) + %call1 = call ptr @passthrough_choice(i1 %c, ptr noundef %B, ptr noundef %A) + call void @write_both(ptr noundef %call, ptr noundef %call1) + %0 = load i32, ptr %A, align 4 + %1 = load i32, ptr %B, align 4 + %add = add nsw i32 %0, %1 + ret i32 %add +} + +define internal ptr @passthrough_choice(i1 %c, ptr noundef %P, ptr noundef %Q) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CHECK-LABEL: define {{[^@]+}}@passthrough_choice +; 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]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], ptr [[P]], ptr [[Q]] +; CHECK-NEXT: ret ptr [[R]] +; +entry: + %R = select i1 %c, ptr %P, ptr %Q + ret ptr %R +} + +; TODO: Verify we do not return 10. +define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) { +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1 +; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 +; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]] +; TUNIT-NEXT: ret i32 10 +; +; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1 +; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 +; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]] +; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; CGSCC-NEXT: ret i32 [[ADD]] +; +entry: + %A = alloca i32, align 4 + %B = alloca i32, align 4 + %call = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %A, ptr noundef %B) + %call1 = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %B, ptr noundef %A) + call void @write_both(ptr noundef %call, ptr noundef %call1) + %0 = load i32, ptr %A, align 4 + %1 = load i32, ptr %B, align 4 + %add = add nsw i32 %0, %1 + ret i32 %add +} + +; TODO: Verify we do not return 10. +define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) { +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2 +; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4 +; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]] +; TUNIT-NEXT: ret i32 10 +; +; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2 +; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4 +; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4 +; 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]] +; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4 +; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4 +; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; CGSCC-NEXT: ret i32 [[ADD]] +; +entry: + %A = alloca i32, align 4 + %B = alloca i32, align 4 + %call = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %A, ptr noundef %B) + %call1 = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %B, ptr noundef %A) + call void @write_both(ptr noundef %call, ptr noundef %call1) + %0 = load i32, ptr %A, align 4 + %1 = load i32, ptr %B, align 4 + %add = add nsw i32 %0, %1 + ret i32 %add +} + +define internal ptr @passthrough_no_choice_true(i1 %c, ptr noundef %P, ptr noundef %Q) { +; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_true +; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], i32 [[TMP0:%.*]]) #[[ATTR4]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[Q_PRIV:%.*]] = alloca i32, align 4 +; CGSCC-NEXT: store i32 [[TMP0]], ptr [[Q_PRIV]], align 4 +; CGSCC-NEXT: ret ptr [[P]] +; +entry: + %R = select i1 %c, ptr %P, ptr %Q + ret ptr %R +} +define internal ptr @passthrough_no_choice_false(i1 %c, ptr noundef %P, ptr noundef %Q) { +; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_false +; CGSCC-SAME: (i32 [[TMP0:%.*]], ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4 +; CGSCC-NEXT: store i32 [[TMP0]], ptr [[P_PRIV]], align 4 +; CGSCC-NEXT: ret ptr [[Q]] +; +entry: + %R = select i1 %c, ptr %P, ptr %Q + ret ptr %R +} + declare void @llvm.assume(i1 noundef) @@ -3238,6 +3448,7 @@ declare void @llvm.assume(i1 noundef) ; TUNIT: attributes #[[ATTR20]] = { norecurse } ; TUNIT: attributes #[[ATTR21]] = { nounwind } ; TUNIT: attributes #[[ATTR22]] = { nofree nosync nounwind willreturn } +; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn memory(none) } ;. ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) } ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) } @@ -3267,6 +3478,7 @@ declare void @llvm.assume(i1 noundef) ; CGSCC: attributes #[[ATTR25]] = { nofree nounwind } ; CGSCC: attributes #[[ATTR26]] = { nofree nounwind willreturn } ; CGSCC: attributes #[[ATTR27]] = { nofree } +; CGSCC: attributes #[[ATTR28]] = { nofree nosync willreturn } ;. ; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} ; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1}