diff options
Diffstat (limited to 'clang/test/CIR/CodeGen')
-rw-r--r-- | clang/test/CIR/CodeGen/goto.cpp | 27 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/label.c | 32 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/throws.cpp | 21 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/vla.c | 285 |
4 files changed, 358 insertions, 7 deletions
diff --git a/clang/test/CIR/CodeGen/goto.cpp b/clang/test/CIR/CodeGen/goto.cpp index 48cb44e..257c255 100644 --- a/clang/test/CIR/CodeGen/goto.cpp +++ b/clang/test/CIR/CodeGen/goto.cpp @@ -205,6 +205,8 @@ extern "C" void case_follow_label(int v) { // CIR: cir.func dso_local @case_follow_label // CIR: cir.switch // CIR: cir.case(equal, [#cir.int<1> : !s32i]) { +// CIR: cir.br ^bb1 +// CIR: ^bb1: // CIR: cir.label "label" // CIR: cir.case(equal, [#cir.int<2> : !s32i]) { // CIR: cir.call @action1() @@ -215,9 +217,11 @@ extern "C" void case_follow_label(int v) { // LLVM: define dso_local void @case_follow_label // LLVM: switch i32 {{.*}}, label %[[SWDEFAULT:.*]] [ -// LLVM: i32 1, label %[[LABEL:.*]] +// LLVM: i32 1, label %[[CASE1:.*]] // LLVM: i32 2, label %[[CASE2:.*]] // LLVM: ] +// LLVM: [[CASE1]]: +// LLVM: br label %[[LABEL:.*]] // LLVM: [[LABEL]]: // LLVM: br label %[[CASE2]] // LLVM: [[CASE2]]: @@ -303,3 +307,24 @@ extern "C" void default_follow_label(int v) { // OGCG: br label %label // OGCG: sw.epilog: // OGCG: ret void + +void g3() { +label: + goto label; +} + +// CIR: cir.func dso_local @_Z2g3v +// CIR: cir.br ^bb1 +// CIR: ^bb1: +// CIR: cir.label "label" +// CIR: cir.goto "label" + +// LLVM: define dso_local void @_Z2g3v() +// LLVM: br label %1 +// LLVM: 1: +// LLVM: br label %1 + +// OGCG: define dso_local void @_Z2g3v() +// OGCG: br label %label +// OGCG: label: +// OGCG: br label %label diff --git a/clang/test/CIR/CodeGen/label.c b/clang/test/CIR/CodeGen/label.c index a050094..f5345ef 100644 --- a/clang/test/CIR/CodeGen/label.c +++ b/clang/test/CIR/CodeGen/label.c @@ -11,10 +11,14 @@ labelA: } // CIR: cir.func no_proto dso_local @label +// CIR: cir.br ^bb1 +// CIR: ^bb1: // CIR: cir.label "labelA" // CIR: cir.return // LLVM:define dso_local void @label +// LLVM: br label %1 +// LLVM: 1: // LLVM: ret void // OGCG: define dso_local void @label @@ -29,15 +33,19 @@ labelC: } // CIR: cir.func no_proto dso_local @multiple_labels -// CIR: cir.label "labelB" // CIR: cir.br ^bb1 -// CIR: ^bb1: // pred: ^bb0 +// CIR: ^bb1: +// CIR: cir.label "labelB" +// CIR: cir.br ^bb2 +// CIR: ^bb2: // CIR: cir.label "labelC" // CIR: cir.return // LLVM: define dso_local void @multiple_labels() // LLVM: br label %1 // LLVM: 1: +// LLVM: br label %2 +// LLVM: 2: // LLVM: ret void // OGCG: define dso_local void @multiple_labels @@ -56,6 +64,8 @@ labelD: // CIR: cir.func dso_local @label_in_if // CIR: cir.if {{.*}} { +// CIR: cir.br ^bb1 +// CIR: ^bb1: // CIR: cir.label "labelD" // CIR: [[LOAD:%.*]] = cir.load align(4) [[COND:%.*]] : !cir.ptr<!s32i>, !s32i // CIR: [[INC:%.*]] = cir.unary(inc, %3) nsw : !s32i, !s32i @@ -68,15 +78,17 @@ labelD: // LLVM: 3: // LLVM: [[LOAD:%.*]] = load i32, ptr [[COND:%.*]], align 4 // LLVM: [[CMP:%.*]] = icmp ne i32 [[LOAD]], 0 -// LLVM: br i1 [[CMP]], label %6, label %9 +// LLVM: br i1 [[CMP]], label %6, label %10 // LLVM: 6: +// LLVM: br label %7 +// LLVM: 7: // LLVM: [[LOAD2:%.*]] = load i32, ptr [[COND]], align 4 // LLVM: [[ADD1:%.*]] = add nsw i32 [[LOAD2]], 1 // LLVM: store i32 [[ADD1]], ptr [[COND]], align 4 -// LLVM: br label %9 -// LLVM: 9: // LLVM: br label %10 // LLVM: 10: +// LLVM: br label %11 +// LLVM: 11: // LLVM: ret void // OGCG: define dso_local void @label_in_if @@ -142,11 +154,15 @@ end: return; } // CIR: cir.func no_proto dso_local @labelWithoutMatch +// CIR: cir.br ^bb1 +// CIR: ^bb1: // CIR: cir.label "end" // CIR: cir.return // CIR: } // LLVM: define dso_local void @labelWithoutMatch +// LLVM: br label %1 +// LLVM: 1: // LLVM: ret void // OGCG: define dso_local void @labelWithoutMatch @@ -167,13 +183,17 @@ void foo() { // CIR: cir.func no_proto dso_local @foo // CIR: cir.scope { -// CIR: cir.label "label" // CIR: %0 = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["agg.tmp0"] +// CIR: cir.br ^bb1 +// CIR: ^bb1: +// CIR: cir.label "label" // LLVM:define dso_local void @foo() { // LLVM: [[ALLOC:%.*]] = alloca %struct.S, i64 1, align 1 // LLVM: br label %2 // LLVM:2: +// LLVM: br label %3 +// LLVM:3: // LLVM: [[CALL:%.*]] = call %struct.S @get() // LLVM: store %struct.S [[CALL]], ptr [[ALLOC]], align 1 // LLVM: [[LOAD:%.*]] = load %struct.S, ptr [[ALLOC]], align 1 diff --git a/clang/test/CIR/CodeGen/throws.cpp b/clang/test/CIR/CodeGen/throws.cpp index ff6aa62..4255d43 100644 --- a/clang/test/CIR/CodeGen/throws.cpp +++ b/clang/test/CIR/CodeGen/throws.cpp @@ -123,3 +123,24 @@ void paren_expr() { (throw 0, 1 + 2); } // OGCG: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 4) // OGCG: store i32 0, ptr %[[EXCEPTION_ADDR]], align 16 // OGCG: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTIi, ptr null) + +void throw_complex_expr() { + throw __builtin_complex(1.1f, 2.2f); +} + +// CIR: %[[EXCEPTION_ADDR:.*]] = cir.alloc.exception 8 -> !cir.ptr<!cir.complex<!cir.float>> +// CIR: %[[EXCEPTION_VALUE:.*]] = cir.const #cir.const_complex<#cir.fp<1.100000e+00> : !cir.float, #cir.fp<2.200000e+00> : !cir.float> : !cir.complex<!cir.float> +// CIR: cir.store{{.*}} %[[EXCEPTION_VALUE]], %[[EXCEPTION_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>> +// CIR: cir.throw %[[EXCEPTION_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, @_ZTICf +// CIR: cir.unreachable + +// LLVM: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 8) +// LLVM: store { float, float } { float 0x3FF19999A0000000, float 0x40019999A0000000 }, ptr %[[EXCEPTION_ADDR]], align 16 +// LLVM: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTICf, ptr null) + +// OGCG: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 8) +// OGCG: %[[EXCEPTION_REAL:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[EXCEPTION_ADDR]], i32 0, i32 0 +// OGCG: %[[EXCEPTION_IMAG:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[EXCEPTION_ADDR]], i32 0, i32 1 +// OGCG: store float 0x3FF19999A0000000, ptr %[[EXCEPTION_REAL]], align 16 +// OGCG: store float 0x40019999A0000000, ptr %[[EXCEPTION_IMAG]], align 4 +// OGCG: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTICf, ptr null) diff --git a/clang/test/CIR/CodeGen/vla.c b/clang/test/CIR/CodeGen/vla.c new file mode 100644 index 0000000..e2adf45 --- /dev/null +++ b/clang/test/CIR/CodeGen/vla.c @@ -0,0 +1,285 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -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 -Wno-unused-value -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 -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +void f0(int len) { + int arr[len]; +} + +// CIR: cir.func{{.*}} @f0(%[[LEN_ARG:.*]]: !s32i {{.*}}) +// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init] +// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] +// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]] +// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]] +// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i +// CIR: %[[STACK_PTR:.*]] = cir.stacksave +// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]] +// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[LEN_SIZE_T]] : !u64i, ["arr"] +// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]] +// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]] + +// LLVM: define{{.*}} void @f0(i32 %[[LEN_ARG:.*]]) { +// LLVM: %[[LEN_ADDR:.*]] = alloca i32 +// LLVM: %[[SAVED_STACK:.*]] = alloca ptr +// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// LLVM: %[[LEN_SIZE_T:.*]] = sext i32 %[[LEN]] to i64 +// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[LEN_SIZE_T]] +// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +// Note: VLA_EXPR0 below is emitted to capture debug info. + +// OGCG: define{{.*}} void @f0(i32 {{.*}} %[[LEN_ARG:.*]]) +// OGCG: %[[LEN_ADDR:.*]] = alloca i32 +// OGCG: %[[SAVED_STACK:.*]] = alloca ptr +// OGCG: %[[VLA_EXPR0:.*]] = alloca i64 +// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64 +// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[LEN_SIZE_T]] +// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]] +// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +void f1(int len) { + int arr[16][len]; +} + +// CIR: cir.func{{.*}} @f1(%[[LEN_ARG:.*]]: !s32i {{.*}}) +// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init] +// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] +// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]] +// CIR: %[[SIXTEEN:.*]] = cir.const #cir.int<16> : !s32i +// CIR: %[[SIXTEEN_SIZE_T:.*]] = cir.cast integral %[[SIXTEEN]] : !s32i -> !u64i +// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]] +// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i +// CIR: %[[STACK_PTR:.*]] = cir.stacksave +// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]] +// CIR: %[[TOTAL_LEN:.*]] = cir.binop(mul, %[[SIXTEEN_SIZE_T]], %[[LEN_SIZE_T]]) nuw +// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN]] : !u64i, ["arr"] +// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]] +// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]] + +// LLVM: define{{.*}} void @f1(i32 %[[LEN_ARG:.*]]) { +// LLVM: %[[LEN_ADDR:.*]] = alloca i32 +// LLVM: %[[SAVED_STACK:.*]] = alloca ptr +// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// LLVM: %[[LEN_SIZE_T:.*]] = sext i32 %[[LEN]] to i64 +// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// LLVM: %[[TOTAL_LEN:.*]] = mul nuw i64 16, %[[LEN_SIZE_T]] +// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN]] +// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +// Note: VLA_EXPR0 below is emitted to capture debug info. + +// OGCG: define{{.*}} void @f1(i32 {{.*}} %[[LEN_ARG:.*]]) +// OGCG: %[[LEN_ADDR:.*]] = alloca i32 +// OGCG: %[[SAVED_STACK:.*]] = alloca ptr +// OGCG: %[[VLA_EXPR0:.*]] = alloca i64 +// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64 +// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// OGCG: %[[TOTAL_LEN:.*]] = mul nuw i64 16, %[[LEN_SIZE_T]] +// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN]] +// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]] +// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +void f2(int len) { + int arr[len + 4]; +} + +// CIR: cir.func{{.*}} @f2(%[[LEN_ARG:.*]]: !s32i {{.*}}) +// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init] +// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] +// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]] +// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]] +// CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s32i +// CIR: %[[TOTAL_LEN:.*]] = cir.binop(add, %[[LEN]], %[[FOUR]]) nsw : !s32i +// CIR: %[[TOTAL_LEN_SIZE_T:.*]] = cir.cast integral %[[TOTAL_LEN]] : !s32i -> !u64i +// CIR: %[[STACK_PTR:.*]] = cir.stacksave +// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]] +// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN_SIZE_T]] : !u64i, ["arr"] +// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]] +// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]] + +// LLVM: define{{.*}} void @f2(i32 %[[LEN_ARG:.*]]) { +// LLVM: %[[LEN_ADDR:.*]] = alloca i32 +// LLVM: %[[SAVED_STACK:.*]] = alloca ptr +// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// LLVM: %[[TOTAL_LEN:.*]] = add nsw i32 %[[LEN]], 4 +// LLVM: %[[TOTAL_LEN_SIZE_T:.*]] = sext i32 %[[TOTAL_LEN]] to i64 +// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN_SIZE_T]] +// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +// Note: VLA_EXPR0 below is emitted to capture debug info. + +// OGCG: define{{.*}} void @f2(i32 {{.*}} %[[LEN_ARG:.*]]) +// OGCG: %[[LEN_ADDR:.*]] = alloca i32 +// OGCG: %[[SAVED_STACK:.*]] = alloca ptr +// OGCG: %[[VLA_EXPR0:.*]] = alloca i64 +// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// OGCG: %[[TOTAL_LEN:.*]] = add nsw i32 %[[LEN]], 4 +// OGCG: %[[TOTAL_LEN_SIZE_T:.*]] = zext i32 %[[TOTAL_LEN]] to i64 +// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN_SIZE_T]] +// OGCG: store i64 %[[TOTAL_LEN_SIZE_T]], ptr %[[VLA_EXPR0]] +// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +void f3(unsigned len) { + char s1[len]; + unsigned i = 0u; + while (++i < len) { + char s2[i]; + } +} + +// CIR: cir.func{{.*}} @f3(%[[LEN_ARG:.*]]: !u32i {{.*}}) +// CIR: %[[LEN_ADDR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["len", init] +// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] +// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]] +// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]] +// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !u32i -> !u64i +// CIR: %[[STACK_PTR:.*]] = cir.stacksave +// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]] +// CIR: %[[S1:.*]] = cir.alloca !s8i, !cir.ptr<!s8i>, %[[LEN_SIZE_T]] : !u64i, ["s1"] +// CIR: %[[I:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["i", init] +// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !u32i +// CIR: cir.store{{.*}} %[[ZERO]], %[[I]] +// CIR: cir.scope { +// CIR: cir.while { +// CIR: %[[CUR_I:.*]] = cir.load{{.*}} %[[I]] +// CIR: %[[NEXT:.*]] = cir.unary(inc, %[[CUR_I]]) +// CIR: cir.store{{.*}} %[[NEXT]], %[[I]] +// CIR: %[[LEN2:.*]] = cir.load{{.*}} %[[LEN_ADDR]] +// CIR: %[[CMP:.*]] = cir.cmp(lt, %[[NEXT]], %[[LEN2]]) +// CIR: cir.condition(%[[CMP]]) +// CIR: } do { +// CIR: cir.scope { +// CIR: %[[SAVED_STACK2:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] +// CIR: %[[I_LEN:.*]] = cir.load{{.*}} %[[I]] +// CIR: %[[I_LEN_SIZE_T2:.*]] = cir.cast integral %[[I_LEN]] : !u32i -> !u64i +// CIR: %[[STACK_PTR2:.*]] = cir.stacksave +// CIR: cir.store{{.*}} %[[STACK_PTR2]], %[[SAVED_STACK2]] +// CIR: %[[S2:.*]] = cir.alloca !s8i, !cir.ptr<!s8i>, %[[I_LEN_SIZE_T2]] : !u64i, ["s2"] +// CIR: %[[SAVED_RESTORE_PTR2:.*]] = cir.load{{.*}} %[[SAVED_STACK2]] +// CIR: cir.stackrestore %[[SAVED_RESTORE_PTR2]] +// CIR: } +// CIR: cir.yield +// CIR: } +// CIR: } +// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]] +// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]] + +// LLVM: define{{.*}} void @f3(i32 %[[LEN_ARG:.*]]) { +// LLVM: %[[SAVED_STACK2:.*]] = alloca ptr +// LLVM: %[[LEN_ADDR:.*]] = alloca i32 +// LLVM: %[[SAVED_STACK:.*]] = alloca ptr +// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// LLVM: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64 +// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// LLVM: %[[S1:.*]] = alloca i8, i64 %[[LEN_SIZE_T]] +// LLVM: %[[I:.*]] = alloca i32 +// LLVM: store i32 0, ptr %[[I]] +// LLVM: br label %[[WHILE_START:.*]] +// LLVM: [[WHILE_START]]: +// LLVM: br label %[[WHILE_COND:.*]] +// LLVM: [[WHILE_COND]]: +// LLVM: %[[CUR_I:.*]] = load i32, ptr %[[I]] +// LLVM: %[[NEXT:.*]] = add i32 %[[CUR_I]], 1 +// LLVM: store i32 %[[NEXT]], ptr %[[I]] +// LLVM: %[[LEN2:.*]] = load i32, ptr %[[LEN_ADDR]] +// LLVM: %[[CMP:.*]] = icmp ult i32 %[[NEXT]], %[[LEN2]] +// LLVM: br i1 %[[CMP]], label %[[WHILE_BODY:.*]], label %[[WHILE_END:.*]] +// LLVM: [[WHILE_BODY]]: +// LLVM: br label %[[WHILE_BODY2:.*]] +// LLVM: [[WHILE_BODY2]]: +// LLVM: %[[I_LEN:.*]] = load i32, ptr %[[I]] +// LLVM: %[[I_LEN_SIZE_T2:.*]] = zext i32 %[[I_LEN]] to i64 +// LLVM: %[[STACK_PTR2:.*]] = call ptr @llvm.stacksave.p0() +// LLVM: store ptr %[[STACK_PTR2]], ptr %[[SAVED_STACK2]] +// LLVM: %[[S2:.*]] = alloca i8, i64 %[[I_LEN_SIZE_T2]] +// LLVM: %[[STACK_RESTORE_PTR2:.*]] = load ptr, ptr %[[SAVED_STACK2]] +// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR2]]) +// LLVM: br label %[[WHILE_BODY_END:.*]] +// LLVM: [[WHILE_BODY_END]]: +// LLVM: br label %[[WHILE_COND]] +// LLVM: [[WHILE_END]]: +// LLVM: br label %[[F3_END:.*]] +// LLVM: [[F3_END]]: +// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + +// Note: VLA_EXPR0 and VLA_EXPR1 below are emitted to capture debug info. + +// OGCG: define{{.*}} void @f3(i32 {{.*}} %[[LEN_ARG:.*]]) +// OGCG: %[[LEN_ADDR:.*]] = alloca i32 +// OGCG: %[[SAVED_STACK:.*]] = alloca ptr +// OGCG: %[[VLA_EXPR0:.*]] = alloca i64 +// OGCG: %[[I:.*]] = alloca i32 +// OGCG: %[[SAVED_STACK1:.*]] = alloca ptr +// OGCG: %[[VLA_EXPR1:.*]] = alloca i64 +// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]] +// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]] +// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64 +// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0() +// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]] +// OGCG: %[[S1:.*]] = alloca i8, i64 %[[LEN_SIZE_T]] +// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]] +// OGCG: br label %[[WHILE_COND:.*]] +// OGCG: [[WHILE_COND]]: +// OGCG: %[[CUR_I:.*]] = load i32, ptr %[[I]] +// OGCG: %[[NEXT:.*]] = add i32 %[[CUR_I]], 1 +// OGCG: store i32 %[[NEXT]], ptr %[[I]] +// OGCG: %[[LEN2:.*]] = load i32, ptr %[[LEN_ADDR]] +// OGCG: %[[CMP:.*]] = icmp ult i32 %[[NEXT]], %[[LEN2]] +// OGCG: br i1 %[[CMP]], label %[[WHILE_BODY:.*]], label %[[WHILE_END:.*]] +// OGCG: [[WHILE_BODY]]: +// OGCG: %[[I_LEN:.*]] = load i32, ptr %[[I]] +// OGCG: %[[I_LEN_SIZE_T:.*]] = zext i32 %[[I_LEN]] to i64 +// OGCG: %[[STACK_PTR1:.*]] = call ptr @llvm.stacksave.p0() +// OGCG: store ptr %[[STACK_PTR1]], ptr %[[SAVED_STACK1]] +// OGCG: %[[S2:.*]] = alloca i8, i64 %[[I_LEN_SIZE_T]] +// OGCG: store i64 %[[I_LEN_SIZE_T]], ptr %[[VLA_EXPR1]] +// OGCG: %[[STACK_RESTORE_PTR1:.*]] = load ptr, ptr %[[SAVED_STACK1]] +// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR1]]) +// OGCG: br label %[[WHILE_COND]] +// OGCG: [[WHILE_END]]: +// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]] +// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]]) + + +// The following test case is disabled because it runs into a bug (unrelated +// to VLA) in the handling of cleanups in loops with break statements. +// +// void f4(unsigned len) { +// char s1[len]; +// while (1) { +// char s2[len]; +// if (1) +// break; +// } +// } +
\ No newline at end of file |