blob: fafe7e1d1918a2c1b7b8029a6c60330a99f963bc [file] [edit]
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
struct StructWithDestructor {
~StructWithDestructor();
};
void use(StructWithDestructor &a);
void test_goto_within_cleanup(bool cond) {
StructWithDestructor a;
if (cond)
goto end;
use(a);
end:
use(a);
}
// CIR-LABEL: cir.func {{.*}} @_Z24test_goto_within_cleanupb
// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!rec_StructWithDestructor>
// CIR: cir.cleanup.scope {
// CIR: cir.scope {
// CIR: cir.if {{.*}} {
// CIR: cir.goto "end"
// CIR: }
// CIR: }
// CIR: cir.call @_Z3useR20StructWithDestructor(%[[A_ADDR]])
// CIR: cir.br ^[[BB_LABEL:bb[0-9]+]]
// CIR: ^[[BB_LABEL]]:
// CIR: cir.label "end"
// CIR: cir.call @_Z3useR20StructWithDestructor(%[[A_ADDR]])
// CIR: cir.yield
// CIR: } cleanup normal {
// CIR: cir.call @_ZN20StructWithDestructorD1Ev(%[[A_ADDR]])
// CIR: cir.yield
// CIR: }
// CIR: cir.return
// LLVM-LABEL: define dso_local void @_Z24test_goto_within_cleanupb(i1 noundef %{{.*}})
// LLVM: %[[COND_ADDR:.*]] = alloca i8
// LLVM: %[[A_ADDR:.*]] = alloca %struct.StructWithDestructor
// LLVM: %[[COND_BYTE:.*]] = load i8, ptr %[[COND_ADDR]]
// LLVM: %[[COND_BIT:.*]] = trunc i8 %[[COND_BYTE]] to i1
// LLVM: br i1 %[[COND_BIT]], label %[[GOTO_BB:.*]], label %[[FALLTHROUGH:.*]]
// LLVM: [[GOTO_BB]]:
// LLVM: br label %[[LABEL_BB:[0-9]+]]
// LLVM: [[FALLTHROUGH]]:
// LLVM: br label %[[USE_BB:.*]]
// LLVM: [[USE_BB]]:
// LLVM: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// LLVM: br label %[[LABEL_BB]]
// LLVM: [[LABEL_BB]]:
// LLVM: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// LLVM: br label %[[CLEANUP:.*]]
// LLVM: [[CLEANUP]]:
// LLVM: call void @_ZN20StructWithDestructorD1Ev(ptr {{.*}} %[[A_ADDR]])
// LLVM-NOT: call void @_ZN20StructWithDestructorD1Ev
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z24test_goto_within_cleanupb(i1 noundef zeroext %cond)
// OGCG: %[[A_ADDR:.*]] = alloca %struct.StructWithDestructor
// OGCG: br i1 %{{.*}}, label %if.then, label %if.end
// OGCG: if.then:
// OGCG: br label %end
// OGCG: if.end:
// OGCG: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// OGCG: br label %end
// OGCG: end:
// OGCG: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// OGCG: call void @_ZN20StructWithDestructorD1Ev(ptr {{.*}} %[[A_ADDR]])
// OGCG-NOT: call void @_ZN20StructWithDestructorD1Ev
// OGCG: ret void
void test_goto_jump_into_nested_op(bool cond1, bool cond2) {
StructWithDestructor a;
if (cond1)
goto skip;
use(a);
if (cond2) {
skip:
use(a);
}
}
// CIR-LABEL: cir.func {{.*}} @_Z29test_goto_jump_into_nested_opbb
// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!rec_StructWithDestructor>
// CIR: cir.cleanup.scope {
// CIR: cir.scope {
// CIR: cir.if {{.*}} {
// CIR: cir.goto "skip"
// CIR: }
// CIR: }
// CIR: cir.call @_Z3useR20StructWithDestructor(%[[A_ADDR]])
// CIR: cir.scope {
// CIR: cir.if {{.*}} {
// CIR: cir.br ^[[BB_LABEL:bb[0-9]+]]
// CIR: ^[[BB_LABEL]]:
// CIR: cir.label "skip"
// CIR: cir.call @_Z3useR20StructWithDestructor(%[[A_ADDR]])
// CIR: cir.yield
// CIR: }
// CIR: }
// CIR: cir.yield
// CIR: } cleanup normal {
// CIR: cir.call @_ZN20StructWithDestructorD1Ev(%[[A_ADDR]])
// CIR: cir.yield
// CIR: }
// CIR: cir.return
// LLVM-LABEL: define dso_local void @_Z29test_goto_jump_into_nested_opbb(i1 noundef %{{.*}}, i1 noundef %{{.*}})
// LLVM: %[[COND1_ADDR:.*]] = alloca i8
// LLVM: %[[COND2_ADDR:.*]] = alloca i8
// LLVM: %[[A_ADDR:.*]] = alloca %struct.StructWithDestructor
// LLVM: %[[COND1_BYTE:.*]] = load i8, ptr %[[COND1_ADDR]]
// LLVM: %[[COND1_BIT:.*]] = trunc i8 %[[COND1_BYTE]] to i1
// LLVM: br i1 %[[COND1_BIT]], label %[[GOTO_BB:.*]], label %[[FALLTHROUGH:.*]]
// LLVM: [[GOTO_BB]]:
// LLVM: br label %[[SKIP_BB:[0-9]+]]
// LLVM: [[FALLTHROUGH]]:
// LLVM: br label %[[USE_BB:.*]]
// LLVM: [[USE_BB]]:
// LLVM: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// LLVM: br label %[[COND2_BB:.*]]
// LLVM: [[COND2_BB]]:
// LLVM: %[[COND2_BYTE:.*]] = load i8, ptr %[[COND2_ADDR]]
// LLVM: %[[COND2_BIT:.*]] = trunc i8 %[[COND2_BYTE]] to i1
// LLVM: br i1 %[[COND2_BIT]], label %[[GOTO_BB2:.*]], label %[[MERGE:.*]]
// LLVM: [[GOTO_BB2]]:
// LLVM: br label %[[SKIP_BB]]
// LLVM: [[SKIP_BB]]:
// LLVM: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// LLVM: br label %[[MERGE]]
// LLVM: [[MERGE]]:
// LLVM: br label %[[CLEANUP:.*]]
// LLVM: [[CLEANUP]]:
// LLVM: call void @_ZN20StructWithDestructorD1Ev(ptr {{.*}} %[[A_ADDR]])
// LLVM-NOT: call void @_ZN20StructWithDestructorD1Ev
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z29test_goto_jump_into_nested_opbb(i1 noundef zeroext %cond1, i1 noundef zeroext %cond2)
// OGCG: %[[COND1_ADDR:.*]] = alloca i8
// OGCG: %[[COND2_ADDR:.*]] = alloca i8
// OGCG: %[[A_ADDR:.*]] = alloca %struct.StructWithDestructor
// OGCG: %[[COND1_BYTE:.*]] = load i8, ptr %[[COND1_ADDR]]
// OGCG: %[[COND1_BIT:.*]] = icmp ne i8 %[[COND1_BYTE]], 0
// OGCG: br i1 %[[COND1_BIT]], label %if.then, label %if.end
// OGCG: if.then:
// OGCG: br label %skip
// OGCG: if.end:
// OGCG: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// OGCG: %[[COND2_BYTE:.*]] = load i8, ptr %[[COND2_ADDR]]
// OGCG: %[[COND2_BIT:.*]] = icmp ne i8 %[[COND2_BYTE]], 0
// OGCG: br i1 %[[COND2_BIT]], label %if.then{{[0-9]+}}, label %[[ENDIF:if\.end[0-9]+]]
// OGCG: if.then{{[0-9]+}}:
// OGCG: br label %skip
// OGCG: skip:
// OGCG: call void @_Z3useR20StructWithDestructor(ptr {{.*}} %[[A_ADDR]])
// OGCG: br label %[[ENDIF]]
// OGCG: [[ENDIF]]:
// OGCG: call void @_ZN20StructWithDestructorD1Ev(ptr {{.*}} %[[A_ADDR]])
// OGCG-NOT: call void @_ZN20StructWithDestructorD1Ev
// OGCG: ret void