343 lines · c
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG7 8void f0(int len) {9 int arr[len];10}11 12// CIR: cir.func{{.*}} @f0(%[[LEN_ARG:.*]]: !s32i {{.*}})13// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]14// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]15// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]16// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]17// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i18// CIR: %[[STACK_PTR:.*]] = cir.stacksave19// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]20// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[LEN_SIZE_T]] : !u64i, ["arr"]21// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]22// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]23 24// LLVM: define{{.*}} void @f0(i32 %[[LEN_ARG:.*]])25// LLVM: %[[LEN_ADDR:.*]] = alloca i3226// LLVM: %[[SAVED_STACK:.*]] = alloca ptr27// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]28// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]29// LLVM: %[[LEN_SIZE_T:.*]] = sext i32 %[[LEN]] to i6430// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()31// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]32// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[LEN_SIZE_T]]33// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]34// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])35 36// Note: VLA_EXPR0 below is emitted to capture debug info.37 38// OGCG: define{{.*}} void @f0(i32 {{.*}} %[[LEN_ARG:.*]])39// OGCG: %[[LEN_ADDR:.*]] = alloca i3240// OGCG: %[[SAVED_STACK:.*]] = alloca ptr41// OGCG: %[[VLA_EXPR0:.*]] = alloca i6442// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]43// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]44// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i6445// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()46// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]47// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[LEN_SIZE_T]]48// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]]49// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]50// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])51 52void f1(int len) {53 int arr[16][len];54}55 56// CIR: cir.func{{.*}} @f1(%[[LEN_ARG:.*]]: !s32i {{.*}})57// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]58// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]59// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]60// CIR: %[[SIXTEEN:.*]] = cir.const #cir.int<16> : !s32i61// CIR: %[[SIXTEEN_SIZE_T:.*]] = cir.cast integral %[[SIXTEEN]] : !s32i -> !u64i62// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]63// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i64// CIR: %[[STACK_PTR:.*]] = cir.stacksave65// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]66// CIR: %[[TOTAL_LEN:.*]] = cir.binop(mul, %[[SIXTEEN_SIZE_T]], %[[LEN_SIZE_T]]) nuw67// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN]] : !u64i, ["arr"]68// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]69// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]70 71// LLVM: define{{.*}} void @f1(i32 %[[LEN_ARG:.*]])72// LLVM: %[[LEN_ADDR:.*]] = alloca i3273// LLVM: %[[SAVED_STACK:.*]] = alloca ptr74// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]75// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]76// LLVM: %[[LEN_SIZE_T:.*]] = sext i32 %[[LEN]] to i6477// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()78// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]79// LLVM: %[[TOTAL_LEN:.*]] = mul nuw i64 16, %[[LEN_SIZE_T]]80// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN]]81// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]82// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])83 84// Note: VLA_EXPR0 below is emitted to capture debug info.85 86// OGCG: define{{.*}} void @f1(i32 {{.*}} %[[LEN_ARG:.*]])87// OGCG: %[[LEN_ADDR:.*]] = alloca i3288// OGCG: %[[SAVED_STACK:.*]] = alloca ptr89// OGCG: %[[VLA_EXPR0:.*]] = alloca i6490// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]91// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]92// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i6493// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()94// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]95// OGCG: %[[TOTAL_LEN:.*]] = mul nuw i64 16, %[[LEN_SIZE_T]]96// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN]]97// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]]98// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]99// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])100 101void f2(int len) {102 int arr[len + 4];103}104 105// CIR: cir.func{{.*}} @f2(%[[LEN_ARG:.*]]: !s32i {{.*}})106// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]107// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]108// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]109// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]110// CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s32i111// CIR: %[[TOTAL_LEN:.*]] = cir.binop(add, %[[LEN]], %[[FOUR]]) nsw : !s32i112// CIR: %[[TOTAL_LEN_SIZE_T:.*]] = cir.cast integral %[[TOTAL_LEN]] : !s32i -> !u64i113// CIR: %[[STACK_PTR:.*]] = cir.stacksave114// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]115// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN_SIZE_T]] : !u64i, ["arr"]116// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]117// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]118 119// LLVM: define{{.*}} void @f2(i32 %[[LEN_ARG:.*]])120// LLVM: %[[LEN_ADDR:.*]] = alloca i32121// LLVM: %[[SAVED_STACK:.*]] = alloca ptr122// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]123// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]124// LLVM: %[[TOTAL_LEN:.*]] = add nsw i32 %[[LEN]], 4125// LLVM: %[[TOTAL_LEN_SIZE_T:.*]] = sext i32 %[[TOTAL_LEN]] to i64126// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()127// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]128// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN_SIZE_T]]129// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]130// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])131 132// Note: VLA_EXPR0 below is emitted to capture debug info.133 134// OGCG: define{{.*}} void @f2(i32 {{.*}} %[[LEN_ARG:.*]])135// OGCG: %[[LEN_ADDR:.*]] = alloca i32136// OGCG: %[[SAVED_STACK:.*]] = alloca ptr137// OGCG: %[[VLA_EXPR0:.*]] = alloca i64138// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]139// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]140// OGCG: %[[TOTAL_LEN:.*]] = add nsw i32 %[[LEN]], 4141// OGCG: %[[TOTAL_LEN_SIZE_T:.*]] = zext i32 %[[TOTAL_LEN]] to i64142// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()143// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]144// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN_SIZE_T]]145// OGCG: store i64 %[[TOTAL_LEN_SIZE_T]], ptr %[[VLA_EXPR0]]146// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]147// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])148 149void f3(unsigned len) {150 char s1[len];151 unsigned i = 0u;152 while (++i < len) {153 char s2[i];154 }155}156 157// CIR: cir.func{{.*}} @f3(%[[LEN_ARG:.*]]: !u32i {{.*}})158// CIR: %[[LEN_ADDR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["len", init]159// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]160// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]161// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]162// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !u32i -> !u64i163// CIR: %[[STACK_PTR:.*]] = cir.stacksave164// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]165// CIR: %[[S1:.*]] = cir.alloca !s8i, !cir.ptr<!s8i>, %[[LEN_SIZE_T]] : !u64i, ["s1"]166// CIR: %[[I:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["i", init]167// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !u32i168// CIR: cir.store{{.*}} %[[ZERO]], %[[I]]169// CIR: cir.scope {170// CIR: cir.while {171// CIR: %[[CUR_I:.*]] = cir.load{{.*}} %[[I]]172// CIR: %[[NEXT:.*]] = cir.unary(inc, %[[CUR_I]])173// CIR: cir.store{{.*}} %[[NEXT]], %[[I]]174// CIR: %[[LEN2:.*]] = cir.load{{.*}} %[[LEN_ADDR]]175// CIR: %[[CMP:.*]] = cir.cmp(lt, %[[NEXT]], %[[LEN2]])176// CIR: cir.condition(%[[CMP]])177// CIR: } do {178// CIR: cir.scope {179// CIR: %[[SAVED_STACK2:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]180// CIR: %[[I_LEN:.*]] = cir.load{{.*}} %[[I]]181// CIR: %[[I_LEN_SIZE_T2:.*]] = cir.cast integral %[[I_LEN]] : !u32i -> !u64i182// CIR: %[[STACK_PTR2:.*]] = cir.stacksave183// CIR: cir.store{{.*}} %[[STACK_PTR2]], %[[SAVED_STACK2]]184// CIR: %[[S2:.*]] = cir.alloca !s8i, !cir.ptr<!s8i>, %[[I_LEN_SIZE_T2]] : !u64i, ["s2"]185// CIR: %[[SAVED_RESTORE_PTR2:.*]] = cir.load{{.*}} %[[SAVED_STACK2]]186// CIR: cir.stackrestore %[[SAVED_RESTORE_PTR2]]187// CIR: }188// CIR: cir.yield189// CIR: }190// CIR: }191// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]192// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]193 194// LLVM: define{{.*}} void @f3(i32 %[[LEN_ARG:.*]])195// LLVM: %[[SAVED_STACK2:.*]] = alloca ptr196// LLVM: %[[LEN_ADDR:.*]] = alloca i32197// LLVM: %[[SAVED_STACK:.*]] = alloca ptr198// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]199// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]200// LLVM: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64201// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()202// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]203// LLVM: %[[S1:.*]] = alloca i8, i64 %[[LEN_SIZE_T]]204// LLVM: %[[I:.*]] = alloca i32205// LLVM: store i32 0, ptr %[[I]]206// LLVM: br label %[[WHILE_START:.*]]207// LLVM: [[WHILE_START]]:208// LLVM: br label %[[WHILE_COND:.*]]209// LLVM: [[WHILE_COND]]:210// LLVM: %[[CUR_I:.*]] = load i32, ptr %[[I]]211// LLVM: %[[NEXT:.*]] = add i32 %[[CUR_I]], 1212// LLVM: store i32 %[[NEXT]], ptr %[[I]]213// LLVM: %[[LEN2:.*]] = load i32, ptr %[[LEN_ADDR]]214// LLVM: %[[CMP:.*]] = icmp ult i32 %[[NEXT]], %[[LEN2]]215// LLVM: br i1 %[[CMP]], label %[[WHILE_BODY:.*]], label %[[WHILE_END:.*]]216// LLVM: [[WHILE_BODY]]:217// LLVM: br label %[[WHILE_BODY2:.*]]218// LLVM: [[WHILE_BODY2]]:219// LLVM: %[[I_LEN:.*]] = load i32, ptr %[[I]]220// LLVM: %[[I_LEN_SIZE_T2:.*]] = zext i32 %[[I_LEN]] to i64221// LLVM: %[[STACK_PTR2:.*]] = call ptr @llvm.stacksave.p0()222// LLVM: store ptr %[[STACK_PTR2]], ptr %[[SAVED_STACK2]]223// LLVM: %[[S2:.*]] = alloca i8, i64 %[[I_LEN_SIZE_T2]]224// LLVM: %[[STACK_RESTORE_PTR2:.*]] = load ptr, ptr %[[SAVED_STACK2]]225// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR2]])226// LLVM: br label %[[WHILE_BODY_END:.*]]227// LLVM: [[WHILE_BODY_END]]:228// LLVM: br label %[[WHILE_COND]]229// LLVM: [[WHILE_END]]:230// LLVM: br label %[[F3_END:.*]]231// LLVM: [[F3_END]]:232// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]233// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])234 235// Note: VLA_EXPR0 and VLA_EXPR1 below are emitted to capture debug info.236 237// OGCG: define{{.*}} void @f3(i32 {{.*}} %[[LEN_ARG:.*]])238// OGCG: %[[LEN_ADDR:.*]] = alloca i32239// OGCG: %[[SAVED_STACK:.*]] = alloca ptr240// OGCG: %[[VLA_EXPR0:.*]] = alloca i64241// OGCG: %[[I:.*]] = alloca i32242// OGCG: %[[SAVED_STACK1:.*]] = alloca ptr243// OGCG: %[[VLA_EXPR1:.*]] = alloca i64244// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]245// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]246// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64247// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()248// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]249// OGCG: %[[S1:.*]] = alloca i8, i64 %[[LEN_SIZE_T]]250// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]]251// OGCG: br label %[[WHILE_COND:.*]]252// OGCG: [[WHILE_COND]]:253// OGCG: %[[CUR_I:.*]] = load i32, ptr %[[I]]254// OGCG: %[[NEXT:.*]] = add i32 %[[CUR_I]], 1255// OGCG: store i32 %[[NEXT]], ptr %[[I]]256// OGCG: %[[LEN2:.*]] = load i32, ptr %[[LEN_ADDR]]257// OGCG: %[[CMP:.*]] = icmp ult i32 %[[NEXT]], %[[LEN2]]258// OGCG: br i1 %[[CMP]], label %[[WHILE_BODY:.*]], label %[[WHILE_END:.*]]259// OGCG: [[WHILE_BODY]]:260// OGCG: %[[I_LEN:.*]] = load i32, ptr %[[I]]261// OGCG: %[[I_LEN_SIZE_T:.*]] = zext i32 %[[I_LEN]] to i64262// OGCG: %[[STACK_PTR1:.*]] = call ptr @llvm.stacksave.p0()263// OGCG: store ptr %[[STACK_PTR1]], ptr %[[SAVED_STACK1]]264// OGCG: %[[S2:.*]] = alloca i8, i64 %[[I_LEN_SIZE_T]]265// OGCG: store i64 %[[I_LEN_SIZE_T]], ptr %[[VLA_EXPR1]]266// OGCG: %[[STACK_RESTORE_PTR1:.*]] = load ptr, ptr %[[SAVED_STACK1]]267// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR1]])268// OGCG: br label %[[WHILE_COND]]269// OGCG: [[WHILE_END]]:270// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]271// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])272 273 274// The following test case is disabled because it runs into a bug (unrelated275// to VLA) in the handling of cleanups in loops with break statements.276//277// void f4(unsigned len) {278// char s1[len];279// while (1) {280// char s2[len];281// if (1)282// break;283// }284// }285 286int f5(unsigned long len) {287 int arr[len];288 return arr[2];289}290 291// CIR: cir.func{{.*}} @f5(%[[LEN_ARG:.*]]: !u64i {{.*}}) -> !s32i292// CIR: %[[LEN_ADDR:.*]] = cir.alloca !u64i, !cir.ptr<!u64i>, ["len", init]293// CIR: %[[RET_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]294// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]295// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]296// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]297// CIR: %[[STACK_PTR:.*]] = cir.stacksave298// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]299// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[LEN]] : !u64i, ["arr"]300// CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i301// CIR: %[[ARR_2:.*]] = cir.ptr_stride %[[ARR]], %[[TWO]]302// CIR: %[[ARR_VAL:.*]] = cir.load{{.*}} %[[ARR_2]] : !cir.ptr<!s32i>, !s32i303// CIR: cir.store{{.*}} %[[ARR_VAL]], %[[RET_ADDR]] : !s32i, !cir.ptr<!s32i>304// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]305// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]306// CIR: %[[RET_VAL:.*]] = cir.load{{.*}} %[[RET_ADDR]]307// CIR: cir.return %[[RET_VAL]] : !s32i308 309// LLVM: define{{.*}} i32 @f5(i64 %[[LEN_ARG:.*]])310// LLVM: %[[LEN_ADDR:.*]] = alloca i64311// LLVM: %[[RET_ADDR:.*]] = alloca i32312// LLVM: %[[SAVED_STACK:.*]] = alloca ptr313// LLVM: store i64 %[[LEN_ARG]], ptr %[[LEN_ADDR]]314// LLVM: %[[LEN:.*]] = load i64, ptr %[[LEN_ADDR]]315// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()316// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]317// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[LEN]]318// LLVM: %[[ARR_2:.*]] = getelementptr i32, ptr %[[ARR]], i64 2319// LLVM: %[[ARR_VAL:.*]] = load i32, ptr %[[ARR_2]]320// LLVM: store i32 %[[ARR_VAL]], ptr %[[RET_ADDR]]321// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]322// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])323// LLVM: %[[RET_VAL:.*]] = load i32, ptr %[[RET_ADDR]]324// LLVM: ret i32 %[[RET_VAL]]325 326// Note: VLA_EXPR0 below is emitted to capture debug info.327 328// OGCG: define{{.*}} i32 @f5(i64 {{.*}} %[[LEN_ARG:.*]])329// OGCG: %[[LEN_ADDR:.*]] = alloca i64330// OGCG: %[[SAVED_STACK:.*]] = alloca ptr331// OGCG: %[[VLA_EXPR0:.*]] = alloca i64332// OGCG: store i64 %[[LEN_ARG]], ptr %[[LEN_ADDR]]333// OGCG: %[[LEN:.*]] = load i64, ptr %[[LEN_ADDR]]334// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()335// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]336// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[LEN]]337// OGCG: store i64 %[[LEN]], ptr %[[VLA_EXPR0]]338// OGCG: %[[ARR_2:.*]] = getelementptr inbounds i32, ptr %[[ARR]], i64 2339// OGCG: %[[ARR_VAL:.*]] = load i32, ptr %[[ARR_2]]340// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]341// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])342// OGCG: ret i32 %[[ARR_VAL]]343