// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -x c++ %s -debug-info-kind=line-tables-only -emit-llvm -o - \ // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-CXX // RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \ // RUN: | FileCheck %s // Check the stores to `retval` allocas and branches to `return` block are in // the same atom group. They are both rank 1, which could in theory introduce // an extra step in some optimized code. This low risk currently feels an // acceptable for keeping the code a bit simpler (as opposed to adding // scaffolding to make the store rank 2). // Also check that in the case of a single return (no control flow) the // return instruction inherits the atom group of the branch to the return // block when the blocks get folded togather. #ifdef __cplusplus #define nomangle extern "C" #else #define nomangle #endif int g; nomangle float a() { // CHECK: float @a() if (g) // CHECK: if.then: // CHECK-NEXT: %1 = load i32, ptr @g{{.*}}, !dbg [[G2R3:!.*]] // CHECK-NEXT: %conv = sitofp i32 %1 to float{{.*}}, !dbg [[G2R2:!.*]] // CHECK-NEXT: store float %conv, ptr %retval{{.*}}, !dbg [[G2R1:!.*]] // CHECK-NEXT: br label %return{{.*}}, !dbg [[G2R1]] return g; // CHECK: if.end: // CHECK-NEXT: store float 1.000000e+00, ptr %retval{{.*}}, !dbg [[G3R1:!.*]] // CHECK-NEXT: br label %return, !dbg [[G3R1]] // CHECK: return: // CHECK-NEXT: %2 = load float, ptr %retval{{.*}}, !dbg [[G4R2:!.*]] // CHECK-NEXT: ret float %2{{.*}}, !dbg [[G4R1:!.*]] return 1; } // CHECK: void @b() // CHECK: ret void{{.*}}, !dbg [[B_G1R1:!.*]] nomangle void b() { return; } // CHECK: i32 @c() // CHECK: %add = add{{.*}}, !dbg [[C_G1R2:!.*]] // CHECK: ret i32 %add{{.*}}, !dbg [[C_G1R1:!.*]] nomangle int c() { return g + 1; } // NOTE: (return) (g = 1) are two separate atoms. // CHECK: i32 @d() // CHECK: store{{.*}}, !dbg [[D_G2R1:!.*]] // CHECK: ret i32 1{{.*}}, !dbg [[D_G1R1:!.*]] nomangle int d() { return g = 1; } // The implicit return here get the line number of the closing brace; make it // key to match existing behaviour. // CHECK: void @e() // CHECK: ret void, !dbg [[E_G1R1:!.*]] nomangle void e() {} #ifdef __cplusplus // CHECK-CXX: ptr @_Z1fRi int &f(int &r) { // Include ctrl-flow to stop ret value store being elided. if (r) // CHECK-CXX: if.then: // CHECK-CXX-NEXT: %2 = load ptr, ptr %r.addr{{.*}}, !dbg [[F_G2R2:!.*]], !nonnull // CHECK-CXX-NEXT: store ptr %2, ptr %retval{{.*}}, !dbg [[F_G2R1:!.*]] // CHECK-CXX-NEXT: br label %return, !dbg [[F_G2R1:!.*]] return r; // CHECK-CXX: if.end: // CHECK-CXX-NEXT: store ptr @g, ptr %retval{{.*}}, !dbg [[F_G3R1:!.*]] // CHECK-CXX-NEXT: br label %return, !dbg [[F_G3R1:!.*]] // CHECK-CXX: return: // CHECK-CXX-NEXT: %3 = load ptr, ptr %retval{{.*}}, !dbg [[F_G4R2:!.*]] // CHECK-CXX-NEXT: ret ptr %3, !dbg [[F_G4R1:!.*]] return g; } #endif // CHECK: [[G2R3]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 3) // CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2) // CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1) // CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1) // CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2) // CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1) // CHECK: [[B_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) // CHECK: [[C_G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2) // CHECK: [[C_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) // CHECK: [[D_G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1) // CHECK: [[D_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) // CHECK: [[E_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1) // CHECK-CXX: [[F_G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2) // CHECK-CXX: [[F_G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1) // CHECK-CXX: [[F_G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1) // CHECK-CXX: [[F_G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2) // CHECK-CXX: [[F_G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)