brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.9 KiB · c15bd77 Raw
469 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"5 6; Test cases designed for the nosync function attribute.7; FIXME's are used to indicate problems and missing attributes.8 9; struct RT {10;   char A;11;   int B[10][20];12;   char C;13; };14; struct ST {15;   int X;16;   double Y;17;   struct RT Z;18; };19;20; int *foo(struct ST *s) {21;   return &s[1].Z.B[5][13];22; }23 24; TEST 125; non-convergent and readnone implies nosync26%struct.RT = type { i8, [10 x [20 x i32]], i8 }27%struct.ST = type { i32, double, %struct.RT }28 29;.30; CHECK: @a = common global i32 0, align 431;.32define ptr @foo(ptr %s) nounwind optsize ssp memory(none) uwtable {33; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable34; CHECK-LABEL: define {{[^@]+}}@foo35; CHECK-SAME: (ptr nofree readnone "no-capture-maybe-returned" [[S:%.*]]) #[[ATTR0:[0-9]+]] {36; CHECK-NEXT:  entry:37; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], ptr [[S]], i64 1, i32 2, i32 1, i64 5, i64 1338; CHECK-NEXT:    ret ptr [[ARRAYIDX]]39;40entry:41  %arrayidx = getelementptr inbounds %struct.ST, ptr %s, i64 1, i32 2, i32 1, i64 5, i64 1342  ret ptr %arrayidx43}44 45; TEST 246; atomic load with monotonic ordering47; int load_monotonic(_Atomic int *num) {48;   int n = atomic_load_explicit(num, memory_order_relaxed);49;   return n;50; }51 52define i32 @load_monotonic(ptr nocapture readonly %arg) norecurse nounwind uwtable {53; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable54; CHECK-LABEL: define {{[^@]+}}@load_monotonic55; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {56; CHECK-NEXT:    [[I:%.*]] = load atomic i32, ptr [[ARG]] monotonic, align 457; CHECK-NEXT:    ret i32 [[I]]58;59  %i = load atomic i32, ptr %arg monotonic, align 460  ret i32 %i61}62 63 64; TEST 365; atomic store with monotonic ordering.66; void store_monotonic(_Atomic int *num) {67;   atomic_load_explicit(num, memory_order_relaxed);68; }69 70define void @store_monotonic(ptr nocapture %arg) norecurse nounwind uwtable {71; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable72; CHECK-LABEL: define {{[^@]+}}@store_monotonic73; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {74; CHECK-NEXT:    store atomic i32 10, ptr [[ARG]] monotonic, align 475; CHECK-NEXT:    ret void76;77  store atomic i32 10, ptr %arg monotonic, align 478  ret void79}80 81; TEST 4 - negative, should not deduce nosync82; atomic load with acquire ordering.83; int load_acquire(_Atomic int *num) {84;   int n = atomic_load_explicit(num, memory_order_acquire);85;   return n;86; }87 88define i32 @load_acquire(ptr nocapture readonly %arg) norecurse nounwind uwtable {89; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable90; CHECK-LABEL: define {{[^@]+}}@load_acquire91; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR2:[0-9]+]] {92; CHECK-NEXT:    [[I:%.*]] = load atomic i32, ptr [[ARG]] acquire, align 493; CHECK-NEXT:    ret i32 [[I]]94;95  %i = load atomic i32, ptr %arg acquire, align 496  ret i32 %i97}98 99; TEST 5 - negative, should not deduce nosync100; atomic load with release ordering101; void load_release(_Atomic int *num) {102;   atomic_store_explicit(num, 10, memory_order_release);103; }104 105define void @load_release(ptr nocapture %arg) norecurse nounwind uwtable {106; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable107; CHECK-LABEL: define {{[^@]+}}@load_release108; CHECK-SAME: (ptr nofree noundef writeonly align 4 captures(none) [[ARG:%.*]]) #[[ATTR2]] {109; CHECK-NEXT:    store atomic volatile i32 10, ptr [[ARG]] release, align 4110; CHECK-NEXT:    ret void111;112  store atomic volatile i32 10, ptr %arg release, align 4113  ret void114}115 116; TEST 6 - negative volatile, relaxed atomic117 118define void @load_volatile_release(ptr nocapture %arg) norecurse nounwind uwtable {119; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable120; CHECK-LABEL: define {{[^@]+}}@load_volatile_release121; CHECK-SAME: (ptr nofree noundef writeonly align 4 captures(none) [[ARG:%.*]]) #[[ATTR2]] {122; CHECK-NEXT:    store atomic volatile i32 10, ptr [[ARG]] release, align 4123; CHECK-NEXT:    ret void124;125  store atomic volatile i32 10, ptr %arg release, align 4126  ret void127}128 129; TEST 7 - negative, should not deduce nosync130; volatile store.131; void volatile_store(volatile int *num) {132;   *num = 14;133; }134 135define void @volatile_store(ptr %arg) norecurse nounwind uwtable {136; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable137; CHECK-LABEL: define {{[^@]+}}@volatile_store138; CHECK-SAME: (ptr nofree noundef align 4 [[ARG:%.*]]) #[[ATTR2]] {139; CHECK-NEXT:    store volatile i32 14, ptr [[ARG]], align 4140; CHECK-NEXT:    ret void141;142  store volatile i32 14, ptr %arg, align 4143  ret void144}145 146; TEST 8 - negative, should not deduce nosync147; volatile load.148; int volatile_load(volatile int *num) {149;   int n = *num;150;   return n;151; }152 153define i32 @volatile_load(ptr %arg) norecurse nounwind uwtable {154; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable155; CHECK-LABEL: define {{[^@]+}}@volatile_load156; CHECK-SAME: (ptr nofree noundef align 4 [[ARG:%.*]]) #[[ATTR2]] {157; CHECK-NEXT:    [[I:%.*]] = load volatile i32, ptr [[ARG]], align 4158; CHECK-NEXT:    ret i32 [[I]]159;160  %i = load volatile i32, ptr %arg, align 4161  ret i32 %i162}163 164; TEST 9165 166; CHECK: Function Attrs: noinline nosync nounwind uwtable167declare void @nosync_function() noinline nounwind uwtable nosync168 169define void @call_nosync_function() noinline nounwind uwtable {170; CHECK: Function Attrs: noinline nosync nounwind uwtable171; CHECK-LABEL: define {{[^@]+}}@call_nosync_function172; CHECK-SAME: () #[[ATTR3:[0-9]+]] {173; CHECK-NEXT:    tail call void @nosync_function() #[[ATTR4:[0-9]+]]174; CHECK-NEXT:    ret void175;176  tail call void @nosync_function() noinline nounwind uwtable177  ret void178}179 180; TEST 10 - negative, should not deduce nosync181 182; CHECK: Function Attrs: noinline nounwind uwtable183declare void @might_sync() noinline nounwind uwtable184 185define void @call_might_sync() noinline nounwind uwtable {186; CHECK: Function Attrs: noinline nounwind uwtable187; CHECK-LABEL: define {{[^@]+}}@call_might_sync188; CHECK-SAME: () #[[ATTR4]] {189; CHECK-NEXT:    tail call void @might_sync() #[[ATTR4]]190; CHECK-NEXT:    ret void191;192  tail call void @might_sync() noinline nounwind uwtable193  ret void194}195 196; TEST 11 - positive, should deduce nosync197; volatile operation in same scc but dead. Call volatile_load defined in TEST 8.198 199define i32 @scc1(ptr %arg) noinline nounwind uwtable {200; CHECK: Function Attrs: nofree noinline nounwind memory(argmem: readwrite) uwtable201; CHECK-LABEL: define {{[^@]+}}@scc1202; CHECK-SAME: (ptr nofree [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {203; CHECK-NEXT:    tail call void @scc2(ptr nofree [[ARG]]) #[[ATTR20:[0-9]+]]204; CHECK-NEXT:    [[VAL:%.*]] = tail call i32 @volatile_load(ptr nofree noundef align 4 [[ARG]]) #[[ATTR20]]205; CHECK-NEXT:    ret i32 [[VAL]]206;207  tail call void @scc2(ptr %arg)208  %val = tail call i32 @volatile_load(ptr %arg)209  ret i32 %val210}211 212define void @scc2(ptr %arg) noinline nounwind uwtable {213; CHECK: Function Attrs: nofree noinline nounwind memory(argmem: readwrite) uwtable214; CHECK-LABEL: define {{[^@]+}}@scc2215; CHECK-SAME: (ptr nofree [[ARG:%.*]]) #[[ATTR5]] {216; CHECK-NEXT:    [[I:%.*]] = tail call i32 @scc1(ptr nofree [[ARG]]) #[[ATTR20]]217; CHECK-NEXT:    ret void218;219  %i = tail call i32 @scc1(ptr %arg)220  ret void221}222 223; TEST 12 - fences, negative224;225; void foo1(int *a, std::atomic<bool> flag){226;   *a = 100;227;   atomic_thread_fence(std::memory_order_release);228;   flag.store(true, std::memory_order_relaxed);229; }230;231; void bar(int *a, std::atomic<bool> flag){232;   while(!flag.load(std::memory_order_relaxed))233;     ;234;235;   atomic_thread_fence(std::memory_order_acquire);236;   int b = *a;237; }238 239%"struct.std::atomic" = type { %"struct.std::__atomic_base" }240%"struct.std::__atomic_base" = type { i8 }241 242define void @foo1(ptr %arg, ptr %arg1) {243; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn244; CHECK-LABEL: define {{[^@]+}}@foo1245; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ARG1:%.*]]) #[[ATTR6:[0-9]+]] {246; CHECK-NEXT:    store i32 100, ptr [[ARG]], align 4247; CHECK-NEXT:    fence release248; CHECK-NEXT:    store atomic i8 1, ptr [[ARG1]] monotonic, align 1249; CHECK-NEXT:    ret void250;251  store i32 100, ptr %arg, align 4252  fence release253  store atomic i8 1, ptr %arg1 monotonic, align 1254  ret void255}256 257define void @bar(ptr %arg, ptr %arg1) {258; CHECK: Function Attrs: nofree norecurse nounwind259; CHECK-LABEL: define {{[^@]+}}@bar260; CHECK-SAME: (ptr nofree readnone captures(none) [[ARG:%.*]], ptr nofree nonnull readonly captures(none) dereferenceable(1) [[ARG1:%.*]]) #[[ATTR7:[0-9]+]] {261; CHECK-NEXT:    br label [[BB2:%.*]]262; CHECK:       bb2:263; CHECK-NEXT:    [[I3:%.*]] = load atomic i8, ptr [[ARG1]] monotonic, align 1264; CHECK-NEXT:    [[I4:%.*]] = and i8 [[I3]], 1265; CHECK-NEXT:    [[I5:%.*]] = icmp eq i8 [[I4]], 0266; CHECK-NEXT:    br i1 [[I5]], label [[BB2]], label [[BB6:%.*]]267; CHECK:       bb6:268; CHECK-NEXT:    fence acquire269; CHECK-NEXT:    ret void270;271  br label %bb2272 273bb2:274  %i3 = load atomic i8, ptr %arg1 monotonic, align 1275  %i4 = and i8 %i3, 1276  %i5 = icmp eq i8 %i4, 0277  br i1 %i5, label %bb2, label %bb6278 279bb6:280  fence acquire281  ret void282}283 284; TEST 13 - Fence syncscope("singlethread") seq_cst285define void @foo1_singlethread(ptr %arg, ptr %arg1) {286; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn287; CHECK-LABEL: define {{[^@]+}}@foo1_singlethread288; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ARG1:%.*]]) #[[ATTR8:[0-9]+]] {289; CHECK-NEXT:    store i32 100, ptr [[ARG]], align 4290; CHECK-NEXT:    fence syncscope("singlethread") release291; CHECK-NEXT:    store atomic i8 1, ptr [[ARG1]] monotonic, align 1292; CHECK-NEXT:    ret void293;294  store i32 100, ptr %arg, align 4295  fence syncscope("singlethread") release296  store atomic i8 1, ptr %arg1 monotonic, align 1297  ret void298}299 300define void @bar_singlethread(ptr %arg, ptr %arg1) {301; CHECK: Function Attrs: nofree norecurse nosync nounwind302; CHECK-LABEL: define {{[^@]+}}@bar_singlethread303; CHECK-SAME: (ptr nofree readnone captures(none) [[ARG:%.*]], ptr nofree nonnull readonly captures(none) dereferenceable(1) [[ARG1:%.*]]) #[[ATTR9:[0-9]+]] {304; CHECK-NEXT:    br label [[BB2:%.*]]305; CHECK:       bb2:306; CHECK-NEXT:    [[I3:%.*]] = load atomic i8, ptr [[ARG1]] monotonic, align 1307; CHECK-NEXT:    [[I4:%.*]] = and i8 [[I3]], 1308; CHECK-NEXT:    [[I5:%.*]] = icmp eq i8 [[I4]], 0309; CHECK-NEXT:    br i1 [[I5]], label [[BB2]], label [[BB6:%.*]]310; CHECK:       bb6:311; CHECK-NEXT:    fence syncscope("singlethread") acquire312; CHECK-NEXT:    ret void313;314  br label %bb2315 316bb2:317  %i3 = load atomic i8, ptr %arg1 monotonic, align 1318  %i4 = and i8 %i3, 1319  %i5 = icmp eq i8 %i4, 0320  br i1 %i5, label %bb2, label %bb6321 322bb6:323  fence syncscope("singlethread") acquire324  ret void325}326 327declare void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 %len, i1 %isvolatile)328declare void @llvm.memset.p0.i32(ptr %dest, i8 %val, i32 %len, i1 %isvolatile)329 330; TEST 14 - negative, checking volatile intrinsics.331 332; It is odd to add nocapture but a result of the llvm.memcpy nocapture.333;334define i32 @memcpy_volatile(ptr %ptr1, ptr %ptr2) {335; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)336; CHECK-LABEL: define {{[^@]+}}@memcpy_volatile337; CHECK-SAME: (ptr nofree writeonly captures(none) [[PTR1:%.*]], ptr nofree readonly captures(none) [[PTR2:%.*]]) #[[ATTR12:[0-9]+]] {338; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr nofree writeonly captures(none) [[PTR1]], ptr nofree readonly captures(none) [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR21:[0-9]+]]339; CHECK-NEXT:    ret i32 4340;341  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 8, i1 true)342  ret i32 4343}344 345; TEST 15 - positive, non-volatile intrinsic.346 347; It is odd to add nocapture but a result of the llvm.memset nocapture.348;349define i32 @memset_non_volatile(ptr %ptr1, i8 %val) {350; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)351; CHECK-LABEL: define {{[^@]+}}@memset_non_volatile352; CHECK-SAME: (ptr nofree writeonly captures(none) [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR13:[0-9]+]] {353; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr nofree writeonly captures(none) [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR22:[0-9]+]]354; CHECK-NEXT:    ret i32 4355;356  call void @llvm.memset.p0.i32(ptr %ptr1, i8 %val, i32 8, i1 false)357  ret i32 4358}359 360; TEST 16 - negative, inline assembly.361 362define i32 @inline_asm_test(i32 %x) {363; CHECK-LABEL: define {{[^@]+}}@inline_asm_test364; CHECK-SAME: (i32 [[X:%.*]]) {365; CHECK-NEXT:    [[I:%.*]] = call i32 asm sideeffect "bswap $0", "=r,r"(i32 [[X]])366; CHECK-NEXT:    ret i32 4367;368  %i = call i32 asm sideeffect "bswap $0", "=r,r"(i32 %x)369  ret i32 4370}371 372declare void @readnone_test() convergent readnone373 374; TEST 17 - negative. Convergent375define void @convergent_readnone() {376; CHECK: Function Attrs: memory(none)377; CHECK-LABEL: define {{[^@]+}}@convergent_readnone378; CHECK-SAME: () #[[ATTR15:[0-9]+]] {379; CHECK-NEXT:    call void @readnone_test()380; CHECK-NEXT:    ret void381;382  call void @readnone_test()383  ret void384}385 386; CHECK: Function Attrs: nounwind387declare void @llvm.x86.sse2.clflush(ptr)388@a = common global i32 0, align 4389 390; TEST 18 - negative. Synchronizing intrinsic391 392define void @i_totally_sync() {393; CHECK: Function Attrs: nounwind394; CHECK-LABEL: define {{[^@]+}}@i_totally_sync395; CHECK-SAME: () #[[ATTR16:[0-9]+]] {396; CHECK-NEXT:    tail call void @llvm.x86.sse2.clflush(ptr noundef nonnull align 4 dereferenceable(4) @a)397; CHECK-NEXT:    ret void398;399  tail call void @llvm.x86.sse2.clflush(ptr @a)400  ret void401}402 403declare float @llvm.cos.f32(float %val) readnone404 405; TEST 19 - positive, readnone & non-convergent intrinsic.406 407define i32 @cos_test(float %x) {408; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)409; CHECK-LABEL: define {{[^@]+}}@cos_test410; CHECK-SAME: (float [[X:%.*]]) #[[ATTR18:[0-9]+]] {411; CHECK-NEXT:    ret i32 4412;413  %i = call float @llvm.cos.f32(float %x)414  ret i32 4415}416 417define float @cos_test2(float %x) {418; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)419; CHECK-LABEL: define {{[^@]+}}@cos_test2420; CHECK-SAME: (float [[X:%.*]]) #[[ATTR18]] {421; CHECK-NEXT:    [[C:%.*]] = call nofpclass(inf) float @llvm.cos.f32(float [[X]]) #[[ATTR23:[0-9]+]]422; CHECK-NEXT:    ret float [[C]]423;424  %c = call float @llvm.cos.f32(float %x)425  ret float %c426}427 428declare void @unknown()429define void @nosync_convergent_callee_test() {430; CHECK: Function Attrs: nosync memory(none)431; CHECK-LABEL: define {{[^@]+}}@nosync_convergent_callee_test432; CHECK-SAME: () #[[ATTR19:[0-9]+]] {433; CHECK-NEXT:    call void @unknown() #[[ATTR24:[0-9]+]]434; CHECK-NEXT:    ret void435;436  call void @unknown() nosync convergent readnone437  ret void438}439;.440; CHECK: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable }441; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable }442; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable }443; CHECK: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable }444; CHECK: attributes #[[ATTR4]] = { noinline nounwind uwtable }445; CHECK: attributes #[[ATTR5]] = { nofree noinline nounwind memory(argmem: readwrite) uwtable }446; CHECK: attributes #[[ATTR6]] = { mustprogress nofree norecurse nounwind willreturn }447; CHECK: attributes #[[ATTR7]] = { nofree norecurse nounwind }448; CHECK: attributes #[[ATTR8]] = { mustprogress nofree norecurse nosync nounwind willreturn }449; CHECK: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind }450; CHECK: attributes #[[ATTR10:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }451; CHECK: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }452; CHECK: attributes #[[ATTR12]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }453; CHECK: attributes #[[ATTR13]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }454; CHECK: attributes #[[ATTR14:[0-9]+]] = { convergent memory(none) }455; CHECK: attributes #[[ATTR15]] = { memory(none) }456; CHECK: attributes #[[ATTR16]] = { nounwind }457; CHECK: attributes #[[ATTR17:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }458; CHECK: attributes #[[ATTR18]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }459; CHECK: attributes #[[ATTR19]] = { nosync memory(none) }460; CHECK: attributes #[[ATTR20]] = { nofree nounwind }461; CHECK: attributes #[[ATTR21]] = { nofree willreturn }462; CHECK: attributes #[[ATTR22]] = { nofree willreturn memory(write) }463; CHECK: attributes #[[ATTR23]] = { nofree nosync willreturn }464; CHECK: attributes #[[ATTR24]] = { convergent nosync memory(none) }465;.466;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:467; CGSCC: {{.*}}468; TUNIT: {{.*}}469