1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=bpf-ir-peephole -mtriple=bpf-pc-linux -S %s | FileCheck %s 3; Source: 4; #define AA 40 5; struct t { 6; char a[20]; 7; }; 8; void foo(ptr); 9; 10; int test1() { 11; const int a = 8; 12; char tmp[AA + sizeof(struct t) + a]; 13; foo(tmp); 14; return 0; 15; } 16; 17; int test2(int b) { 18; const int a = 8; 19; char tmp[a + b]; 20; foo(tmp); 21; return 0; 22; } 23; Compilation flag: 24; clang -target bpf -O2 -S -emit-llvm t.c -Xclang -disable-llvm-passes 25 26source_filename = "t.c" 27target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" 28target triple = "bpf" 29 30; Function Attrs: nounwind 31define dso_local i32 @test1() { 32; CHECK-LABEL: @test1( 33; CHECK-NEXT: entry: 34; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 35; CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca ptr, align 8 36; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A]]) 37; CHECK-NEXT: store i32 8, ptr [[A]], align 4 38; CHECK-NEXT: [[VLA:%.*]] = alloca i8, i64 68, align 1 39; CHECK-NEXT: call void @foo(ptr [[VLA]]) 40; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A]]) 41; CHECK-NEXT: ret i32 0 42; 43entry: 44 %a = alloca i32, align 4 45 %saved_stack = alloca ptr, align 8 46 call void @llvm.lifetime.start.p0(i64 4, ptr %a) 47 store i32 8, ptr %a, align 4 48 %0 = call ptr @llvm.stacksave() 49 store ptr %0, ptr %saved_stack, align 8 50 %vla = alloca i8, i64 68, align 1 51 call void @foo(ptr %vla) 52 %1 = load ptr, ptr %saved_stack, align 8 53 call void @llvm.stackrestore(ptr %1) 54 call void @llvm.lifetime.end.p0(i64 4, ptr %a) 55 ret i32 0 56} 57 58declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) 59 60declare ptr @llvm.stacksave() 61 62declare dso_local void @foo(ptr) 63 64declare void @llvm.stackrestore(ptr) 65 66declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) 67 68define dso_local i32 @test2(i32 %b) { 69; CHECK-LABEL: @test2( 70; CHECK-NEXT: entry: 71; CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 72; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 73; CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca ptr, align 8 74; CHECK-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 75; CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4 76; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A]]) 77; CHECK-NEXT: store i32 8, ptr [[A]], align 4 78; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4 79; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 8, [[TMP1]] 80; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[ADD]] to i64 81; CHECK-NEXT: [[VLA:%.*]] = alloca i8, i64 [[TMP2]], align 1 82; CHECK-NEXT: store i64 [[TMP2]], ptr [[__VLA_EXPR0]], align 8 83; CHECK-NEXT: call void @foo(ptr [[VLA]]) 84; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A]]) 85; CHECK-NEXT: ret i32 0 86; 87entry: 88 %b.addr = alloca i32, align 4 89 %a = alloca i32, align 4 90 %saved_stack = alloca ptr, align 8 91 %__vla_expr0 = alloca i64, align 8 92 store i32 %b, ptr %b.addr, align 4 93 call void @llvm.lifetime.start.p0(i64 4, ptr %a) 94 store i32 8, ptr %a, align 4 95 %0 = load i32, ptr %b.addr, align 4 96 %add = add nsw i32 8, %0 97 %1 = zext i32 %add to i64 98 %2 = call ptr @llvm.stacksave() 99 store ptr %2, ptr %saved_stack, align 8 100 %vla = alloca i8, i64 %1, align 1 101 store i64 %1, ptr %__vla_expr0, align 8 102 call void @foo(ptr %vla) 103 %3 = load ptr, ptr %saved_stack, align 8 104 call void @llvm.stackrestore(ptr %3) 105 call void @llvm.lifetime.end.p0(i64 4, ptr %a) 106 ret i32 0 107} 108