169 lines · c
1// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -x c++ -std=c++17 %s -debug-info-kind=line-tables-only -emit-llvm -o - -gno-column-info \2// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank3// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - -gno-column-info \4// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank5 6// Check that atomic handling code gets Key Instruction annotations.7 8_Atomic(unsigned int) x;9unsigned int y;10void fun() {11 unsigned int r1 = __c11_atomic_fetch_add(&x,- 1, __ATOMIC_RELAXED);12// CHECK: store i32 -1, ptr %.atomictmp, align 4, !dbg [[LINE11_G2R1:!.*]]13// CHECK-NEXT: %0 = load i32, ptr %.atomictmp, align 4, !dbg [[LINE11:!.*]]14// CHECK-NEXT: %1 = atomicrmw add ptr @x, i32 %0 monotonic, align 4, !dbg [[LINE11_G2R2:!.*]]15// CHECK-NEXT: store i32 %1, ptr %atomic-temp, align 4, !dbg [[LINE11_G2R1]]16// CHECK-NEXT: %2 = load i32, ptr %atomic-temp, align 4, !dbg [[LINE11_G1R2:!.*]]17// CHECK-NEXT: store i32 %2, ptr %r1, align 4, !dbg [[LINE11_G1R1:!.*]]18 19 unsigned int r2 = __c11_atomic_load(&x, __ATOMIC_RELAXED);20// CHECK-NEXT: %3 = load atomic i32, ptr @x monotonic, align 4, !dbg [[LINE19_G4R2:!.*]]21// CHECK-NEXT: store i32 %3, ptr %atomic-temp1, align 4, !dbg [[LINE19_G4R1:!.*]]22// CHECK-NEXT: %4 = load i32, ptr %atomic-temp1, align 4, !dbg [[LINE19_G3R2:!.*]]23// CHECK-NEXT: store i32 %4, ptr %r2, align 4, !dbg [[LINE19_G3R1:!.*]]24 25 __c11_atomic_store(&x, 2, __ATOMIC_RELAXED);26// CHECK-NEXT: store i32 2, ptr %.atomictmp2, align 4, !dbg [[LINE25_G5R1:!.*]]27// CHECK-NEXT: %5 = load i32, ptr %.atomictmp2, align 4, !dbg [[LINE25_G5R2:!.*]]28// CHECK-NEXT: store atomic i32 %5, ptr @x monotonic, align 4, !dbg [[LINE25_G5R1:!.*]]29 30 int r3 = __atomic_test_and_set(&x, __ATOMIC_RELAXED);31// CHECK-NEXT: %6 = atomicrmw xchg ptr @x, i8 1 monotonic, align 4, !dbg [[LINE30:!.*]]32// CHECK-NEXT: %tobool = icmp ne i8 %6, 0, !dbg [[LINE30_G7R3:!.*]]33// CHECK-NEXT: %storedv = zext i1 %tobool to i8, !dbg [[LINE30_G7R2:!.*]]34// CHECK-NEXT: store i8 %storedv, ptr %atomic-temp3, align 1, !dbg [[LINE30_G7R1:!.*]]35// CHECK-NEXT: %7 = load i8, ptr %atomic-temp3, align 1, !dbg [[LINE30_G6R4:!.*]]36// CHECK-NEXT: %loadedv = trunc i8 %7 to i1, !dbg [[LINE30_G6R3:!.*]]37// CHECK-NEXT: %conv = zext i1 %loadedv to i32, !dbg [[LINE30_G6R2:!.*]]38// CHECK-NEXT: store i32 %conv, ptr %r3, align 4, !dbg [[LINE30_G6R1:!.*]]39 40 __atomic_clear(&x, __ATOMIC_RELAXED);41// CHECK-NEXT: store atomic i8 0, ptr @x monotonic, align 4, !dbg [[LINE40_G8R1:!.*]]42 43 int r4 = __c11_atomic_exchange(&x, 2,__ATOMIC_RELAXED);44// CHECK-NEXT: store i32 2, ptr %.atomictmp4, align 4, !dbg [[LINE43_G10R1:!.*]]45// CHECK-NEXT: %8 = load i32, ptr %.atomictmp4, align 4, !dbg [[LINE43:!.*]]46// CHECK-NEXT: %9 = atomicrmw xchg ptr @x, i32 %8 monotonic, align 4, !dbg [[LINE43_G10R2:!.*]]47// CHECK-NEXT: store i32 %9, ptr %atomic-temp5, align 4, !dbg [[LINE43_G10R1:!.*]]48// CHECK-NEXT: %10 = load i32, ptr %atomic-temp5, align 4, !dbg [[LINE43_G9R2:!.*]]49// CHECK-NEXT: store i32 %10, ptr %r4, align 4, !dbg [[LINE43_G9R1:!.*]]50 51 int r5 = __atomic_compare_exchange(&y, &y, &y, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);52// CHECK-NEXT: %11 = load i32, ptr @y, align 4, !dbg [[LINE51:!.*]]53// CHECK-NEXT: %12 = load i32, ptr @y, align 4, !dbg [[LINE51]]54// CHECK-NEXT: %13 = cmpxchg ptr @y, i32 %11, i32 %12 monotonic monotonic, align 4, !dbg [[LINE51]]55// CHECK-NEXT: %14 = extractvalue { i32, i1 } %13, 0, !dbg [[LINE51_G12R2:!.*]]56// CHECK-NEXT: %15 = extractvalue { i32, i1 } %13, 1, !dbg [[LINE51_G12R3:!.*]]57// CHECK-NEXT: br i1 %15, label %cmpxchg.continue, label %cmpxchg.store_expected, !dbg [[LINE51]]58// CHECK: cmpxchg.store_expected:59// CHECK-NEXT: store i32 %14, ptr @y, align 4, !dbg [[LINE51_G12R1:!.*]]60// CHECK-NEXT: br label %cmpxchg.continue, !dbg [[LINE51]]61// CHECK: cmpxchg.continue:62// CHECK-NEXT: %storedv6 = zext i1 %15 to i8, !dbg [[LINE51_G12R2]]63// CHECK-NEXT: store i8 %storedv6, ptr %cmpxchg.bool, align 1, !dbg [[LINE51_G12R1]]64// CHECK-NEXT: %16 = load i8, ptr %cmpxchg.bool, align 1, !dbg [[LINE51_G11R4:!.*]]65// CHECK-NEXT: %loadedv7 = trunc i8 %16 to i1, !dbg [[LINE51_G11R3:!.*]]66// CHECK-NEXT: %conv8 = zext i1 %loadedv7 to i32, !dbg [[LINE51_G11R2:!.*]]67// CHECK-NEXT: store i32 %conv8, ptr %r5, align 4, !dbg [[LINE51_G11R1:!.*]]68 69 int r6 = __c11_atomic_compare_exchange_strong(&x, &y, 42, __ATOMIC_RELAXED, __ATOMIC_RELAXED);70// CHECK-NEXT: store i32 42, ptr %.atomictmp9, align 4, !dbg [[LINE69_G14R1:!.*]]71// CHECK-NEXT: %17 = load i32, ptr @y, align 4, !dbg [[LINE69:!.*]]72// CHECK-NEXT: %18 = load i32, ptr %.atomictmp9, align 4, !dbg [[LINE69]]73// CHECK-NEXT: %19 = cmpxchg ptr @x, i32 %17, i32 %18 monotonic monotonic, align 4, !dbg [[LINE69]]74// CHECK-NEXT: %20 = extractvalue { i32, i1 } %19, 0, !dbg [[LINE69_G14R2:!.*]]75// CHECK-NEXT: %21 = extractvalue { i32, i1 } %19, 1, !dbg [[LINE69_G14R3:!.*]]76// CHECK-NEXT: br i1 %21, label %cmpxchg.continue12, label %cmpxchg.store_expected11, !dbg [[LINE69]]77// CHECK: cmpxchg.store_expected11:78// CHECK-NEXT: store i32 %20, ptr @y, align 4, !dbg [[LINE69_G14R1:!.*]]79// CHECK-NEXT: br label %cmpxchg.continue12, !dbg [[LINE69]]80// CHECK: cmpxchg.continue12:81// CHECK-NEXT: %storedv13 = zext i1 %21 to i8, !dbg [[LINE69_G14R2]]82// CHECK-NEXT: store i8 %storedv13, ptr %cmpxchg.bool10, align 1, !dbg [[LINE69_G14R1:!.*]]83// CHECK-NEXT: %22 = load i8, ptr %cmpxchg.bool10, align 1, !dbg [[LINE69_G13R4:!.*]]84// CHECK-NEXT: %loadedv14 = trunc i8 %22 to i1, !dbg [[LINE69_G13R3:!.*]]85// CHECK-NEXT: %conv15 = zext i1 %loadedv14 to i32, !dbg [[LINE69_G13R2:!.*]]86// CHECK-NEXT: store i32 %conv15, ptr %r6, align 4, !dbg [[LINE69_G13R1:!.*]]87 88 int r7 = __c11_atomic_compare_exchange_weak(&x, &y, 43, __ATOMIC_RELAXED, __ATOMIC_RELAXED);89// CHECK-NEXT: store i32 43, ptr %.atomictmp16, align 4, !dbg [[LINE88_G16R1:!.*]]90// CHECK-NEXT: %23 = load i32, ptr @y, align 4, !dbg [[LINE88:!.*]]91// CHECK-NEXT: %24 = load i32, ptr %.atomictmp16, align 4, !dbg [[LINE88]]92// CHECK-NEXT: %25 = cmpxchg weak ptr @x, i32 %23, i32 %24 monotonic monotonic, align 4, !dbg [[LINE88]]93// CHECK-NEXT: %26 = extractvalue { i32, i1 } %25, 0, !dbg [[LINE88_G16R2:!.*]]94// CHECK-NEXT: %27 = extractvalue { i32, i1 } %25, 1, !dbg [[LINE88_G16R3:!.*]]95// CHECK-NEXT: br i1 %27, label %cmpxchg.continue19, label %cmpxchg.store_expected18, !dbg [[LINE88]]96// CHECK: cmpxchg.store_expected18:97// CHECK-NEXT: store i32 %26, ptr @y, align 4, !dbg [[LINE88_G16R1]]98// CHECK-NEXT: br label %cmpxchg.continue19, !dbg [[LINE88]]99// CHECK: cmpxchg.continue19:100// CHECK-NEXT: %storedv20 = zext i1 %27 to i8, !dbg [[LINE88_G16R2]]101// CHECK-NEXT: store i8 %storedv20, ptr %cmpxchg.bool17, align 1, !dbg [[LINE88_G16R1]]102// CHECK-NEXT: %28 = load i8, ptr %cmpxchg.bool17, align 1, !dbg [[LINE88_G15R4:!.*]]103// CHECK-NEXT: %loadedv21 = trunc i8 %28 to i1, !dbg [[LINE88_G15R3:!.*]]104// CHECK-NEXT: %conv22 = zext i1 %loadedv21 to i32, !dbg [[LINE88_G15R2:!.*]]105// CHECK-NEXT: store i32 %conv22, ptr %r7, align 4, !dbg [[LINE88_G15R1:!.*]]106 107// CHECK: ret{{.*}}, !dbg [[RET:!.*]]108}109 110// CHECK: [[LINE11_G2R1]] = !DILocation(line: 11, scope: ![[#]], atomGroup: 2, atomRank: 1)111// CHECK: [[LINE11]] = !DILocation(line: 11, scope: ![[#]])112// CHECK: [[LINE11_G2R2]] = !DILocation(line: 11, scope: ![[#]], atomGroup: 2, atomRank: 2)113// CHECK: [[LINE11_G1R2]] = !DILocation(line: 11, scope: ![[#]], atomGroup: 1, atomRank: 2)114// CHECK: [[LINE11_G1R1]] = !DILocation(line: 11, scope: ![[#]], atomGroup: 1, atomRank: 1)115 116// CHECK: [[LINE19_G4R2]] = !DILocation(line: 19, scope: ![[#]], atomGroup: 4, atomRank: 2)117// CHECK: [[LINE19_G4R1]] = !DILocation(line: 19, scope: ![[#]], atomGroup: 4, atomRank: 1)118// CHECK: [[LINE19_G3R2]] = !DILocation(line: 19, scope: ![[#]], atomGroup: 3, atomRank: 2)119// CHECK: [[LINE19_G3R1]] = !DILocation(line: 19, scope: ![[#]], atomGroup: 3, atomRank: 1)120 121// CHECK: [[LINE25_G5R1]] = !DILocation(line: 25, scope: ![[#]], atomGroup: 5, atomRank: 1)122// CHECK: [[LINE25_G5R2]] = !DILocation(line: 25, scope: ![[#]], atomGroup: 5, atomRank: 2)123 124// CHECK: [[LINE30]] = !DILocation(line: 30, scope: ![[#]])125// CHECK: [[LINE30_G7R3]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 7, atomRank: 3)126// CHECK: [[LINE30_G7R2]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 7, atomRank: 2)127// CHECK: [[LINE30_G7R1]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 7, atomRank: 1)128// CHECK: [[LINE30_G6R4]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 6, atomRank: 4)129// CHECK: [[LINE30_G6R3]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 6, atomRank: 3)130// CHECK: [[LINE30_G6R2]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 6, atomRank: 2)131// CHECK: [[LINE30_G6R1]] = !DILocation(line: 30, scope: ![[#]], atomGroup: 6, atomRank: 1)132 133// CHECK: [[LINE40_G8R1]] = !DILocation(line: 40, scope: ![[#]], atomGroup: 8, atomRank: 1)134 135// CHECK: [[LINE43_G10R1]] = !DILocation(line: 43, scope: ![[#]], atomGroup: 10, atomRank: 1)136// CHECK: [[LINE43]] = !DILocation(line: 43, scope: ![[#]])137// CHECK: [[LINE43_G10R2]] = !DILocation(line: 43, scope: ![[#]], atomGroup: 10, atomRank: 2)138// CHECK: [[LINE43_G9R2]] = !DILocation(line: 43, scope: ![[#]], atomGroup: 9, atomRank: 2)139// CHECK: [[LINE43_G9R1]] = !DILocation(line: 43, scope: ![[#]], atomGroup: 9, atomRank: 1)140 141// CHECK: [[LINE51]] = !DILocation(line: 51, scope: ![[#]])142// CHECK: [[LINE51_G12R2]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 12, atomRank: 2)143// CHECK: [[LINE51_G12R3]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 12, atomRank: 3)144// CHECK: [[LINE51_G12R1]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 12, atomRank: 1)145// CHECK: [[LINE51_G11R4]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 11, atomRank: 4)146// CHECK: [[LINE51_G11R3]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 11, atomRank: 3)147// CHECK: [[LINE51_G11R2]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 11, atomRank: 2)148// CHECK: [[LINE51_G11R1]] = !DILocation(line: 51, scope: ![[#]], atomGroup: 11, atomRank: 1)149 150// CHECK: [[LINE69_G14R1]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 14, atomRank: 1)151// CHECK: [[LINE69]] = !DILocation(line: 69, scope: ![[#]])152// CHECK: [[LINE69_G14R2]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 14, atomRank: 2)153// CHECK: [[LINE69_G14R3]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 14, atomRank: 3)154// CHECK: [[LINE69_G13R4]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 13, atomRank: 4)155// CHECK: [[LINE69_G13R3]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 13, atomRank: 3)156// CHECK: [[LINE69_G13R2]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 13, atomRank: 2)157// CHECK: [[LINE69_G13R1]] = !DILocation(line: 69, scope: ![[#]], atomGroup: 13, atomRank: 1)158 159// CHECK: [[LINE88_G16R1]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 16, atomRank: 1)160// CHECK: [[LINE88]] = !DILocation(line: 88, scope: ![[#]])161// CHECK: [[LINE88_G16R2]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 16, atomRank: 2)162// CHECK: [[LINE88_G16R3]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 16, atomRank: 3)163// CHECK: [[LINE88_G15R4]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 15, atomRank: 4)164// CHECK: [[LINE88_G15R3]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 15, atomRank: 3)165// CHECK: [[LINE88_G15R2]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 15, atomRank: 2)166// CHECK: [[LINE88_G15R1]] = !DILocation(line: 88, scope: ![[#]], atomGroup: 15, atomRank: 1)167 168// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 17, atomRank: 1)169