614 lines · cpp
1// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR3// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM5// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG7 8void l0() {9 for (;;) {10 }11}12 13// CIR: cir.func{{.*}} @_Z2l0v14// CIR: cir.scope {15// CIR: cir.for : cond {16// CIR: %[[TRUE:.*]] = cir.const #true17// CIR: cir.condition(%[[TRUE]])18// CIR: } body {19// CIR: cir.yield20// CIR: } step {21// CIR: cir.yield22// CIR: }23// CIR: }24// CIR: cir.return25// CIR: }26 27// LLVM: define{{.*}} void @_Z2l0v(){{.*}}28// LLVM: br label %[[LABEL1:.*]]29// LLVM: [[LABEL1]]:30// LLVM: br label %[[LABEL2:.*]]31// LLVM: [[LABEL2]]:32// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL5:.*]]33// LLVM: [[LABEL3]]:34// LLVM: br label %[[LABEL4:.*]]35// LLVM: [[LABEL4]]:36// LLVM: br label %[[LABEL2]]37// LLVM: [[LABEL5]]:38// LLVM: br label %[[LABEL6:.*]]39// LLVM: [[LABEL6]]:40// LLVM: ret void41 42// OGCG: define{{.*}} void @_Z2l0v()43// OGCG: entry:44// OGCG: br label %[[FOR_COND:.*]]45// OGCG: [[FOR_COND]]:46// OGCG: br label %[[FOR_COND]]47 48void l1() {49 for (int i = 0; ; ) {50 }51}52 53// CIR: cir.func{{.*}} @_Z2l1v54// CIR-NEXT: cir.scope {55// CIR-NEXT: %[[I:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}56// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i57// CIR-NEXT: cir.store{{.*}} %[[ZERO]], %[[I]] : !s32i, !cir.ptr<!s32i>58// CIR-NEXT: cir.for : cond {59// CIR-NEXT: %[[TRUE:.*]] = cir.const #true60// CIR-NEXT: cir.condition(%[[TRUE]])61// CIR-NEXT: } body {62// CIR-NEXT: cir.yield63// CIR-NEXT: } step {64// CIR-NEXT: cir.yield65// CIR-NEXT: }66// CIR-NEXT: }67// CIR-NEXT: cir.return68// CIR-NEXT: }69 70// LLVM: define{{.*}} void @_Z2l1v(){{.*}}71// LLVM: %[[I:.*]] = alloca i32, i64 1, align 472// LLVM: br label %[[LABEL1:.*]]73// LLVM: [[LABEL1]]:74// LLVM: store i32 0, ptr %[[I]], align 475// LLVM: br label %[[LABEL2:.*]]76// LLVM: [[LABEL2]]:77// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL5:.*]]78// LLVM: [[LABEL3]]:79// LLVM: br label %[[LABEL4:.*]]80// LLVM: [[LABEL4]]:81// LLVM: br label %[[LABEL2]]82// LLVM: [[LABEL5]]:83// LLVM: br label %[[LABEL6:.*]]84// LLVM: [[LABEL6]]:85// LLVM: ret void86 87// OGCG: define{{.*}} void @_Z2l1v()88// OGCG: entry:89// OGCG: %[[I:.*]] = alloca i32, align 490// OGCG: store i32 0, ptr %[[I]], align 491// OGCG: br label %[[FOR_COND:.*]]92// OGCG: [[FOR_COND]]:93// OGCG: br label %[[FOR_COND]]94 95void l2() {96 for (;;) {97 int i = 0;98 }99}100 101// CIR: cir.func{{.*}} @_Z2l2v102// CIR-NEXT: cir.scope {103// CIR-NEXT: cir.for : cond {104// CIR-NEXT: %[[TRUE:.*]] = cir.const #true105// CIR-NEXT: cir.condition(%[[TRUE]])106// CIR-NEXT: } body {107// CIR-NEXT: cir.scope {108// CIR-NEXT: %[[I:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}109// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i110// CIR-NEXT: cir.store{{.*}} %[[ZERO]], %[[I]] : !s32i, !cir.ptr<!s32i>111// CIR-NEXT: }112// CIR-NEXT: cir.yield113// CIR-NEXT: } step {114// CIR-NEXT: cir.yield115// CIR-NEXT: }116// CIR-NEXT: }117// CIR-NEXT: cir.return118// CIR-NEXT: }119 120// LLVM: define{{.*}} void @_Z2l2v(){{.*}}121// LLVM: %[[I:.*]] = alloca i32, i64 1, align 4122// LLVM: br label %[[LABEL1:.*]]123// LLVM: [[LABEL1]]:124// LLVM: br label %[[LABEL2:.*]]125// LLVM: [[LABEL2]]:126// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL5:.*]]127// LLVM: [[LABEL3]]:128// LLVM: store i32 0, ptr %[[I]], align 4129// LLVM: br label %[[LABEL4:.*]]130// LLVM: [[LABEL4]]:131// LLVM: br label %[[LABEL2]]132// LLVM: [[LABEL5]]:133// LLVM: br label %[[LABEL6:.*]]134// LLVM: [[LABEL6]]:135// LLVM: ret void136 137// OGCG: define{{.*}} void @_Z2l2v()138// OGCG: entry:139// OGCG: %[[I:.*]] = alloca i32, align 4140// OGCG: br label %[[FOR_COND:.*]]141// OGCG: [[FOR_COND]]:142// OGCG: store i32 0, ptr %[[I]], align 4143// OGCG: br label %[[FOR_COND]]144 145// This is the same as l2 but without a compound statement for the body.146void l3() {147 for (;;)148 int i = 0;149}150 151// CIR: cir.func{{.*}} @_Z2l3v152// CIR-NEXT: cir.scope {153// CIR-NEXT: %[[I:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}154// CIR-NEXT: cir.for : cond {155// CIR-NEXT: %[[TRUE:.*]] = cir.const #true156// CIR-NEXT: cir.condition(%[[TRUE]])157// CIR-NEXT: } body {158// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i159// CIR-NEXT: cir.store{{.*}} %[[ZERO]], %[[I]] : !s32i, !cir.ptr<!s32i>160// CIR-NEXT: cir.yield161// CIR-NEXT: } step {162// CIR-NEXT: cir.yield163// CIR-NEXT: }164// CIR-NEXT: }165// CIR-NEXT: cir.return166// CIR-NEXT: }167 168// LLVM: define{{.*}} void @_Z2l3v(){{.*}}169// LLVM: %[[I:.*]] = alloca i32, i64 1, align 4170// LLVM: br label %[[LABEL1:.*]]171// LLVM: [[LABEL1]]:172// LLVM: br label %[[LABEL2:.*]]173// LLVM: [[LABEL2]]:174// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL5:.*]]175// LLVM: [[LABEL3]]:176// LLVM: store i32 0, ptr %[[I]], align 4177// LLVM: br label %[[LABEL4:.*]]178// LLVM: [[LABEL4]]:179// LLVM: br label %[[LABEL2]]180// LLVM: [[LABEL5]]:181// LLVM: br label %[[LABEL6:.*]]182// LLVM: [[LABEL6]]:183// LLVM: ret void184 185// OGCG: define{{.*}} void @_Z2l3v()186// OGCG: entry:187// OGCG: %[[I:.*]] = alloca i32, align 4188// OGCG: br label %[[FOR_COND:.*]]189// OGCG: [[FOR_COND]]:190// OGCG: store i32 0, ptr %[[I]], align 4191// OGCG: br label %[[FOR_COND]]192 193void l4() {194 int a[10];195 for (int n : a)196 ;197}198 199// CIR: cir.func{{.*}} @_Z2l4v200// CIR: %[[A_ADDR:.*]] = cir.alloca {{.*}} ["a"]201// CIR: cir.scope {202// CIR: %[[RANGE_ADDR:.*]] = cir.alloca {{.*}} ["__range1", init, const]203// CIR: %[[BEGIN_ADDR:.*]] = cir.alloca {{.*}} ["__begin1", init]204// CIR: %[[END_ADDR:.*]] = cir.alloca {{.*}} ["__end1", init]205// CIR: %[[N_ADDR:.*]] = cir.alloca {{.*}} ["n", init]206// CIR: cir.store{{.*}} %[[A_ADDR]], %[[RANGE_ADDR]]207// CIR: %[[RANGE_LOAD:.*]] = cir.load{{.*}} %[[RANGE_ADDR]]208// CIR: %[[RANGE_CAST:.*]] = cir.cast array_to_ptrdecay %[[RANGE_LOAD]] : {{.*}}209// CIR: cir.store{{.*}} %[[RANGE_CAST]], %[[BEGIN_ADDR]]210// CIR: %[[BEGIN:.*]] = cir.load{{.*}} %[[RANGE_ADDR]]211// CIR: %[[BEGIN_CAST:.*]] = cir.cast array_to_ptrdecay %[[BEGIN]] : {{.*}}212// CIR: %[[TEN:.*]] = cir.const #cir.int<10>213// CIR: %[[END_PTR:.*]] = cir.ptr_stride %[[BEGIN_CAST]], %[[TEN]] : ({{.*}}, {{.*}})214// CIR: cir.store{{.*}} %[[END_PTR]], %[[END_ADDR]]215// CIR: cir.for : cond {216// CIR: %[[CUR:.*]] = cir.load{{.*}} %[[BEGIN_ADDR]]217// CIR: %[[END:.*]] = cir.load{{.*}} %[[END_ADDR]]218// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[CUR]], %[[END]])219// CIR: cir.condition(%[[CMP]])220// CIR: } body {221// CIR: %[[CUR:.*]] = cir.load deref{{.*}} %[[BEGIN_ADDR]]222// CIR: %[[N:.*]] = cir.load{{.*}} %[[CUR]]223// CIR: cir.store{{.*}} %[[N]], %[[N_ADDR]]224// CIR: cir.yield225// CIR: } step {226// CIR: %[[CUR:.*]] = cir.load{{.*}} %[[BEGIN_ADDR]]227// CIR: %[[ONE:.*]] = cir.const #cir.int<1>228// CIR: %[[NEXT:.*]] = cir.ptr_stride %[[CUR]], %[[ONE]] : ({{.*}}, {{.*}})229// CIR: cir.store{{.*}} %[[NEXT]], %[[BEGIN_ADDR]]230// CIR: cir.yield231// CIR: }232// CIR: }233 234// LLVM: define{{.*}} void @_Z2l4v(){{.*}} {235// LLVM: %[[RANGE_ADDR:.*]] = alloca ptr236// LLVM: %[[BEGIN_ADDR:.*]] = alloca ptr237// LLVM: %[[END_ADDR:.*]] = alloca ptr238// LLVM: %[[N_ADDR:.*]] = alloca i32239// LLVM: %[[A_ADDR:.*]] = alloca [10 x i32]240// LLVM: br label %[[SETUP:.*]]241// LLVM: [[SETUP]]:242// LLVM: store ptr %[[A_ADDR]], ptr %[[RANGE_ADDR]]243// LLVM: %[[BEGIN:.*]] = load ptr, ptr %[[RANGE_ADDR]]244// LLVM: %[[BEGIN_CAST:.*]] = getelementptr i32, ptr %[[BEGIN]], i32 0245// LLVM: store ptr %[[BEGIN_CAST]], ptr %[[BEGIN_ADDR]]246// LLVM: %[[RANGE:.*]] = load ptr, ptr %[[RANGE_ADDR]]247// LLVM: %[[RANGE_CAST:.*]] = getelementptr i32, ptr %[[RANGE]], i32 0248// LLVM: %[[END_PTR:.*]] = getelementptr i32, ptr %[[RANGE_CAST]], i64 10249// LLVM: store ptr %[[END_PTR]], ptr %[[END_ADDR]]250// LLVM: br label %[[COND:.*]]251// LLVM: [[COND]]:252// LLVM: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]253// LLVM: %[[END:.*]] = load ptr, ptr %[[END_ADDR]]254// LLVM: %[[CMP:.*]] = icmp ne ptr %[[BEGIN]], %[[END]]255// LLVM: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]]256// LLVM: [[BODY]]:257// LLVM: %[[CUR:.*]] = load ptr, ptr %[[BEGIN_ADDR]]258// LLVM: %[[A_CUR:.*]] = load i32, ptr %[[CUR]]259// LLVM: store i32 %[[A_CUR]], ptr %[[N_ADDR]]260// LLVM: br label %[[STEP:.*]]261// LLVM: [[STEP]]:262// LLVM: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]263// LLVM: %[[NEXT:.*]] = getelementptr i32, ptr %[[BEGIN]], i64 1264// LLVM: store ptr %[[NEXT]], ptr %[[BEGIN_ADDR]]265// LLVM: br label %[[COND]]266// LLVM: [[END]]:267// LLVM: br label %[[EXIT:.*]]268// LLVM: [[EXIT]]:269// LLVM: ret void270 271// OGCG: define{{.*}} void @_Z2l4v()272// OGCG: %[[A_ADDR:.*]] = alloca [10 x i32]273// OGCG: %[[RANGE_ADDR:.*]] = alloca ptr274// OGCG: %[[BEGIN_ADDR:.*]] = alloca ptr275// OGCG: %[[END_ADDR:.*]] = alloca ptr276// OGCG: %[[N_ADDR:.*]] = alloca i32277// OGCG: store ptr %[[A_ADDR]], ptr %[[RANGE_ADDR]]278// OGCG: %[[BEGIN:.*]] = load ptr, ptr %[[RANGE_ADDR]]279// OGCG: %[[BEGIN_CAST:.*]] = getelementptr inbounds [10 x i32], ptr %[[BEGIN]], i64 0, i64 0280// OGCG: store ptr %[[BEGIN_CAST]], ptr %[[BEGIN_ADDR]]281// OGCG: %[[RANGE:.*]] = load ptr, ptr %[[RANGE_ADDR]]282// OGCG: %[[RANGE_CAST:.*]] = getelementptr inbounds [10 x i32], ptr %[[RANGE]], i64 0, i64 0283// OGCG: %[[END_PTR:.*]] = getelementptr inbounds i32, ptr %[[RANGE_CAST]], i64 10284// OGCG: store ptr %[[END_PTR]], ptr %[[END_ADDR]]285// OGCG: br label %[[COND:.*]]286// OGCG: [[COND]]:287// OGCG: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]288// OGCG: %[[END:.*]] = load ptr, ptr %[[END_ADDR]]289// OGCG: %[[CMP:.*]] = icmp ne ptr %[[BEGIN]], %[[END]]290// OGCG: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]]291// OGCG: [[BODY]]:292// OGCG: %[[CUR:.*]] = load ptr, ptr %[[BEGIN_ADDR]]293// OGCG: %[[A_CUR:.*]] = load i32, ptr %[[CUR]]294// OGCG: store i32 %[[A_CUR]], ptr %[[N_ADDR]]295// OGCG: br label %[[STEP:.*]]296// OGCG: [[STEP]]:297// OGCG: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]298// OGCG: %[[NEXT:.*]] = getelementptr inbounds nuw i32, ptr %[[BEGIN]], i32 1299// OGCG: store ptr %[[NEXT]], ptr %[[BEGIN_ADDR]]300// OGCG: br label %[[COND]]301// OGCG: [[END]]:302// OGCG: ret void303 304void l5() {305 for (int arr[]{1,2,3,4}; auto x : arr) {} 306}307 308// CIR: cir.func{{.*}} @_Z2l5v309// CIR: cir.scope {310// CIR: %[[ARR_ADDR:.*]] = cir.alloca {{.*}} ["arr", init]311// CIR: %[[RANGE_ADDR:.*]] = cir.alloca {{.*}} ["__range1", init, const]312// CIR: %[[BEGIN_ADDR:.*]] = cir.alloca {{.*}} ["__begin1", init]313// CIR: %[[END_ADDR:.*]] = cir.alloca {{.*}} ["__end1", init]314// CIR: %[[X_ADDR:.*]] = cir.alloca {{.*}} ["x", init]315// CIR: %[[ARR_INIT:.*]] = cir.const #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i]>316// CIR: cir.store{{.*}} %[[ARR_INIT]], %[[ARR_ADDR]]317// CIR: cir.store{{.*}} %[[ARR_ADDR]], %[[RANGE_ADDR]]318// CIR: %[[RANGE_LOAD:.*]] = cir.load %[[RANGE_ADDR]]319// CIR: %[[RANGE_CAST:.*]] = cir.cast array_to_ptrdecay %[[RANGE_LOAD]] : {{.*}}320// CIR: cir.store{{.*}} %[[RANGE_CAST]], %[[BEGIN_ADDR]]321// CIR: %[[BEGIN:.*]] = cir.load{{.*}} %[[RANGE_ADDR]]322// CIR: %[[BEGIN_CAST:.*]] = cir.cast array_to_ptrdecay %[[BEGIN]] : {{.*}}323// CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s64i324// CIR: %[[END_PTR:.*]] = cir.ptr_stride %[[BEGIN_CAST]], %[[FOUR]] : ({{.*}}, {{.*}})325// CIR: cir.store{{.*}} %[[END_PTR]], %[[END_ADDR]]326// CIR: cir.for : cond {327// CIR: %[[CUR:.*]] = cir.load{{.*}} %[[BEGIN_ADDR]]328// CIR: %[[END:.*]] = cir.load{{.*}} %[[END_ADDR]]329// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[CUR]], %[[END]])330// CIR: cir.condition(%[[CMP]])331// CIR: } body {332// CIR: %[[CUR:.*]] = cir.load deref{{.*}} %[[BEGIN_ADDR]]333// CIR: %[[X:.*]] = cir.load{{.*}} %[[CUR]]334// CIR: cir.store{{.*}} %[[X]], %[[X_ADDR]]335// CIR: cir.yield336// CIR: } step {337// CIR: %[[CUR:.*]] = cir.load{{.*}} %[[BEGIN_ADDR]]338// CIR: %[[ONE:.*]] = cir.const #cir.int<1>339// CIR: %[[NEXT:.*]] = cir.ptr_stride %[[CUR]], %[[ONE]] : ({{.*}}, {{.*}})340// CIR: cir.store{{.*}} %[[NEXT]], %[[BEGIN_ADDR]]341// CIR: cir.yield342// CIR: }343// CIR: }344 345// LLVM: define{{.*}} void @_Z2l5v(){{.*}} {346// LLVM: %[[ARR_ADDR:.*]] = alloca [4 x i32]347// LLVM: %[[RANGE_ADDR:.*]] = alloca ptr348// LLVM: %[[BEGIN_ADDR:.*]] = alloca ptr349// LLVM: %[[END_ADDR:.*]] = alloca ptr350// LLVM: %[[X_ADDR:.*]] = alloca i32351// LLVM: br label %[[SETUP:.*]]352// LLVM: [[SETUP]]:353// LLVM: store [4 x i32] [i32 1, i32 2, i32 3, i32 4], ptr %[[ARR_ADDR]]354// LLVM: store ptr %[[ARR_ADDR]], ptr %[[RANGE_ADDR]]355// LLVM: %[[BEGIN:.*]] = load ptr, ptr %[[RANGE_ADDR]]356// LLVM: %[[BEGIN_CAST:.*]] = getelementptr i32, ptr %[[BEGIN]], i32 0357// LLVM: store ptr %[[BEGIN_CAST]], ptr %[[BEGIN_ADDR]]358// LLVM: %[[RANGE:.*]] = load ptr, ptr %[[RANGE_ADDR]]359// LLVM: %[[RANGE_CAST:.*]] = getelementptr i32, ptr %[[RANGE]], i32 0360// LLVM: %[[END_PTR:.*]] = getelementptr i32, ptr %[[RANGE_CAST]], i64 4361// LLVM: store ptr %[[END_PTR]], ptr %[[END_ADDR]]362// LLVM: br label %[[COND:.*]]363// LLVM: [[COND]]:364// LLVM: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]365// LLVM: %[[END:.*]] = load ptr, ptr %[[END_ADDR]]366// LLVM: %[[CMP:.*]] = icmp ne ptr %[[BEGIN]], %[[END]]367// LLVM: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]]368// LLVM: [[BODY]]:369// LLVM: %[[CUR:.*]] = load ptr, ptr %[[BEGIN_ADDR]]370// LLVM: %[[ARR_CUR:.*]] = load i32, ptr %[[CUR]]371// LLVM: store i32 %[[ARR_CUR]], ptr %[[X_ADDR]]372// LLVM: br label %[[STEP:.*]]373// LLVM: [[STEP]]:374// LLVM: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]375// LLVM: %[[NEXT:.*]] = getelementptr i32, ptr %[[BEGIN]], i64 1376// LLVM: store ptr %[[NEXT]], ptr %[[BEGIN_ADDR]]377// LLVM: br label %[[COND]]378// LLVM: [[END]]:379// LLVM: br label %[[EXIT:.*]]380// LLVM: [[EXIT]]:381// LLVM: ret void382 383// OGCG: define{{.*}} void @_Z2l5v()384// OGCG: %[[ARR_ADDR:.*]] = alloca [4 x i32]385// OGCG: %[[RANGE_ADDR:.*]] = alloca ptr386// OGCG: %[[BEGIN_ADDR:.*]] = alloca ptr387// OGCG: %[[END_ADDR:.*]] = alloca ptr388// OGCG: %[[X_ADDR:.*]] = alloca i32389// OGCG: call void @llvm.memcpy.p0.p0.i64390// OGCG: store ptr %[[ARR_ADDR]], ptr %[[RANGE_ADDR]]391// OGCG: %[[BEGIN:.*]] = load ptr, ptr %[[RANGE_ADDR]]392// OGCG: %[[BEGIN_CAST:.*]] = getelementptr inbounds [4 x i32], ptr %[[BEGIN]], i64 0, i64 0393// OGCG: store ptr %[[BEGIN_CAST]], ptr %[[BEGIN_ADDR]]394// OGCG: %[[RANGE:.*]] = load ptr, ptr %[[RANGE_ADDR]]395// OGCG: %[[RANGE_CAST:.*]] = getelementptr inbounds [4 x i32], ptr %[[RANGE]], i64 0, i64 0396// OGCG: %[[END_PTR:.*]] = getelementptr inbounds i32, ptr %[[RANGE_CAST]], i64 4397// OGCG: store ptr %[[END_PTR]], ptr %[[END_ADDR]]398// OGCG: br label %[[COND:.*]]399// OGCG: [[COND]]:400// OGCG: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]401// OGCG: %[[END:.*]] = load ptr, ptr %[[END_ADDR]]402// OGCG: %[[CMP:.*]] = icmp ne ptr %[[BEGIN]], %[[END]]403// OGCG: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]]404// OGCG: [[BODY]]:405// OGCG: %[[CUR:.*]] = load ptr, ptr %[[BEGIN_ADDR]]406// OGCG: %[[ARR_CUR:.*]] = load i32, ptr %[[CUR]]407// OGCG: store i32 %[[ARR_CUR]], ptr %[[X_ADDR]]408// OGCG: br label %[[STEP:.*]]409// OGCG: [[STEP]]:410// OGCG: %[[BEGIN:.*]] = load ptr, ptr %[[BEGIN_ADDR]]411// OGCG: %[[NEXT:.*]] = getelementptr inbounds nuw i32, ptr %[[BEGIN]], i32 1412// OGCG: store ptr %[[NEXT]], ptr %[[BEGIN_ADDR]]413// OGCG: br label %[[COND]]414// OGCG: [[END]]:415// OGCG: ret void416 417void test_do_while_false() {418 do {419 } while (0);420}421 422// CIR: cir.func{{.*}} @_Z19test_do_while_falsev()423// CIR-NEXT: cir.scope {424// CIR-NEXT: cir.do {425// CIR-NEXT: cir.yield426// CIR-NEXT: } while {427// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i428// CIR-NEXT: %[[FALSE:.*]] = cir.cast int_to_bool %[[ZERO]] : !s32i -> !cir.bool429// CIR-NEXT: cir.condition(%[[FALSE]])430 431// LLVM: define{{.*}} void @_Z19test_do_while_falsev(){{.*}}432// LLVM: br label %[[LABEL1:.*]]433// LLVM: [[LABEL1]]:434// LLVM: br label %[[LABEL3:.*]]435// LLVM: [[LABEL2:.*]]:436// LLVM: br i1 false, label %[[LABEL3]], label %[[LABEL4:.*]]437// LLVM: [[LABEL3]]:438// LLVM: br label %[[LABEL2]]439// LLVM: [[LABEL4]]:440// LLVM: br label %[[LABEL5:.*]]441// LLVM: [[LABEL5]]:442// LLVM: ret void443 444// OGCG: define{{.*}} void @_Z19test_do_while_falsev()445// OGCG: entry:446// OGCG: br label %[[DO_BODY:.*]]447// OGCG: [[DO_BODY]]:448// OGCG: br label %[[DO_END:.*]]449// OGCG: [[DO_END]]:450// OGCG: ret void451 452void test_empty_while_true() {453 while (true) {454 return;455 }456}457 458// CIR: cir.func{{.*}} @_Z21test_empty_while_truev()459// CIR-NEXT: cir.scope {460// CIR-NEXT: cir.while {461// CIR-NEXT: %[[TRUE:.*]] = cir.const #true462// CIR-NEXT: cir.condition(%[[TRUE]])463// CIR-NEXT: } do {464// CIR-NEXT: cir.scope {465// CIR-NEXT: cir.return466// CIR-NEXT: }467// CIR-NEXT: cir.yield468 469// LLVM: define{{.*}} void @_Z21test_empty_while_truev(){{.*}}470// LLVM: br label %[[LABEL1:.*]]471// LLVM: [[LABEL1]]:472// LLVM: br label %[[LABEL2:.*]]473// LLVM: [[LABEL2]]:474// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL6:.*]]475// LLVM: [[LABEL3]]:476// LLVM: br label %[[LABEL4]]477// LLVM: [[LABEL4]]:478// LLVM: ret void479// LLVM: [[LABEL5:.*]]:480// LLVM-SAME: ; No predecessors!481// LLVM: br label %[[LABEL2:.*]]482// LLVM: [[LABEL6]]:483// LLVM: br label %[[LABEL7:.*]]484// LLVM: [[LABEL7]]:485// LLVM: ret void486 487// OGCG: define{{.*}} void @_Z21test_empty_while_truev()488// OGCG: entry:489// OGCG: br label %[[WHILE_BODY:.*]]490// OGCG: [[WHILE_BODY]]:491// OGCG: ret void492 493void unreachable_after_continue() {494 for (;;) {495 continue;496 int x = 1;497 }498}499 500// CIR: cir.func{{.*}} @_Z26unreachable_after_continuev()501// CIR: cir.scope {502// CIR: cir.for : cond {503// CIR: %[[TRUE:.*]] = cir.const #true504// CIR: cir.condition(%[[TRUE]])505// CIR: } body {506// CIR: cir.scope {507// CIR: %[[X:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}508// CIR: cir.continue509// CIR: ^bb1: // no predecessors510// CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i511// CIR: cir.store{{.*}} %[[ONE]], %[[X]] : !s32i, !cir.ptr<!s32i>512// CIR: cir.yield513// CIR: }514// CIR: cir.yield515// CIR: } step {516// CIR: cir.yield517// CIR: }518// CIR: }519// CIR: cir.return520// CIR: }521 522// LLVM: define{{.*}} void @_Z26unreachable_after_continuev(){{.*}}523// LLVM: %[[X:.*]] = alloca i32, i64 1, align 4524// LLVM: br label %[[LABEL1:.*]]525// LLVM: [[LABEL1]]:526// LLVM: br label %[[LABEL2:.*]]527// LLVM: [[LABEL2]]:528// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL8:.*]]529// LLVM: [[LABEL3]]:530// LLVM: br label %[[LABEL4:.*]]531// LLVM: [[LABEL4]]:532// LLVM: br label %[[LABEL7:.*]]533// LLVM: [[LABEL5:.*]]:534// LLVM-SAME: ; No predecessors!535// LLVM: store i32 1, ptr %[[X]], align 4536// LLVM: br label %[[LABEL6:.*]]537// LLVM: [[LABEL6]]:538// LLVM: br label %[[LABEL7:.*]]539// LLVM: [[LABEL7]]:540// LLVM: br label %[[LABEL2]]541// LLVM: [[LABEL8]]:542// LLVM: br label %[[LABEL9:]]543// LLVM: [[LABEL9]]:544// LLVM: ret void545 546// OGCG: define{{.*}} void @_Z26unreachable_after_continuev()547// OGCG: entry:548// OGCG: %[[X:.*]] = alloca i32, align 4549// OGCG: br label %[[FOR_COND:.*]]550// OGCG: [[FOR_COND]]:551// OGCG: br label %[[FOR_COND]]552 553void unreachable_after_break() {554 for (;;) {555 break;556 int x = 1;557 }558}559 560// CIR: cir.func{{.*}} @_Z23unreachable_after_breakv()561// CIR: cir.scope {562// CIR: cir.for : cond {563// CIR: %[[TRUE:.*]] = cir.const #true564// CIR: cir.condition(%[[TRUE]])565// CIR: } body {566// CIR: cir.scope {567// CIR: %[[X:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}568// CIR: cir.break569// CIR: ^bb1: // no predecessors570// CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i571// CIR: cir.store{{.*}} %[[ONE]], %[[X]] : !s32i, !cir.ptr<!s32i>572// CIR: cir.yield573// CIR: }574// CIR: cir.yield575// CIR: } step {576// CIR: cir.yield577// CIR: }578// CIR: }579// CIR: cir.return580// CIR: }581 582// LLVM: define{{.*}} void @_Z23unreachable_after_breakv(){{.*}}583// LLVM: %[[X:.*]] = alloca i32, i64 1, align 4584// LLVM: br label %[[LABEL1:.*]]585// LLVM: [[LABEL1]]:586// LLVM: br label %[[LABEL2:.*]]587// LLVM: [[LABEL2]]:588// LLVM: br i1 true, label %[[LABEL3:.*]], label %[[LABEL8:.*]]589// LLVM: [[LABEL3]]:590// LLVM: br label %[[LABEL4:.*]]591// LLVM: [[LABEL4]]:592// LLVM: br label %[[LABEL8]]593// LLVM: [[LABEL5:.*]]:594// LLVM-SAME: ; No predecessors!595// LLVM: store i32 1, ptr %[[X]], align 4596// LLVM: br label %[[LABEL6:.*]]597// LLVM: [[LABEL6]]:598// LLVM: br label %[[LABEL7:.*]]599// LLVM: [[LABEL7]]:600// LLVM: br label %[[LABEL2]]601// LLVM: [[LABEL8]]:602// LLVM: br label %[[LABEL9:]]603// LLVM: [[LABEL9]]:604// LLVM: ret void605 606// OGCG: define{{.*}} void @_Z23unreachable_after_breakv()607// OGCG: entry:608// OGCG: %[[X:.*]] = alloca i32, align 4609// OGCG: br label %[[FOR_COND:.*]]610// OGCG: [[FOR_COND]]:611// OGCG: br label %[[FOR_END:.*]]612// OGCG: [[FOR_END]]:613// OGCG: ret void614