254 lines · plain
1; This check verifies that stack depth callback instrumentation works correctly.2; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-stack-depth -sanitizer-coverage-stack-depth-callback-min=1 -S | FileCheck %s --check-prefixes=COMMON,CB13; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-stack-depth -sanitizer-coverage-stack-depth-callback-min=8 -S | FileCheck %s --check-prefixes=COMMON,CB84; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-stack-depth -sanitizer-coverage-stack-depth-callback-min=16 -S | FileCheck %s --check-prefixes=COMMON,CB165; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-stack-depth -sanitizer-coverage-stack-depth-callback-min=32 -S | FileCheck %s --check-prefixes=COMMON,CB326; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-stack-depth -sanitizer-coverage-stack-depth-callback-min=64 -S | FileCheck %s --check-prefixes=COMMON,CB647; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=1 -sanitizer-coverage-stack-depth -sanitizer-coverage-stack-depth-callback-min=128 -S | FileCheck %s --check-prefixes=COMMON,CB1288 9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"10target triple = "x86_64-unknown-linux-gnu"11 12; No stack, just return: our leaf function13define i32 @foo() {14; COMMON-LABEL: define i32 @foo() {15; COMMON-NEXT: entry:16; CB1-NOT: call void @__sanitizer_cov_stack_depth()17; CB8-NOT: call void @__sanitizer_cov_stack_depth()18; CB16-NOT: call void @__sanitizer_cov_stack_depth()19; CB32-NOT: call void @__sanitizer_cov_stack_depth()20; CB64-NOT: call void @__sanitizer_cov_stack_depth()21; CB128-NOT: call void @__sanitizer_cov_stack_depth()22; COMMON-NEXT: ret i32 723;24entry:25 26 ret i32 727}28 29; No stack, just function call30define i32 @retcall() {31; COMMON-LABEL: define i32 @retcall() {32; COMMON-NEXT: entry:33; CB1-NOT: call void @__sanitizer_cov_stack_depth()34; CB8-NOT: call void @__sanitizer_cov_stack_depth()35; CB16-NOT: call void @__sanitizer_cov_stack_depth()36; CB32-NOT: call void @__sanitizer_cov_stack_depth()37; CB64-NOT: call void @__sanitizer_cov_stack_depth()38; CB128-NOT: call void @__sanitizer_cov_stack_depth()39; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()40; COMMON-NEXT: ret i32 [[CALL]]41entry:42 43 %call = call i32 @foo()44 ret i32 %call45}46 47; No stack, just function call, with argument48define i32 @witharg(i32 %input) {49; COMMON-LABEL: define i32 @witharg(i32 %input) {50; COMMON-NEXT: entry:51; CB1-NOT: call void @__sanitizer_cov_stack_depth()52; CB8-NOT: call void @__sanitizer_cov_stack_depth()53; CB16-NOT: call void @__sanitizer_cov_stack_depth()54; CB32-NOT: call void @__sanitizer_cov_stack_depth()55; CB64-NOT: call void @__sanitizer_cov_stack_depth()56; CB128-NOT: call void @__sanitizer_cov_stack_depth()57; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()58; COMMON-NEXT: ret i32 [[CALL]]59entry:60 61 %call = call i32 @foo()62 ret i32 %call63}64 65; 4 byte stack of scalars66define i32 @alloc4_0() {67; COMMON-LABEL: define i32 @alloc4_0() {68; COMMON-NEXT: entry:69; COMMON-NEXT: [[VAR:%.*]] = alloca i32, align 470; CB1-NEXT: call void @__sanitizer_cov_stack_depth()71; CB8-NOT: call void @__sanitizer_cov_stack_depth()72; CB16-NOT: call void @__sanitizer_cov_stack_depth()73; CB32-NOT: call void @__sanitizer_cov_stack_depth()74; CB64-NOT: call void @__sanitizer_cov_stack_depth()75; CB128-NOT: call void @__sanitizer_cov_stack_depth()76; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()77; COMMON-NEXT: ret i32 [[CALL]]78entry:79 %var1 = alloca i32, align 480 81 %call = call i32 @foo()82 ret i32 %call83}84 85; 16 byte stack of scalars86define i32 @alloc16_0() {87; COMMON-LABEL: define i32 @alloc16_0() {88; COMMON-NEXT: entry:89; COMMON-NEXT: [[VAR:%.*]] = alloca i32, align 490; COMMON-NEXT: [[VAR:%.*]] = alloca i32, align 491; COMMON-NEXT: [[VAR:%.*]] = alloca i32, align 492; COMMON-NEXT: [[VAR:%.*]] = alloca i32, align 493; CB1-NEXT: call void @__sanitizer_cov_stack_depth()94; CB8-NEXT: call void @__sanitizer_cov_stack_depth()95; CB16-NEXT: call void @__sanitizer_cov_stack_depth()96; CB32-NOT: call void @__sanitizer_cov_stack_depth()97; CB64-NOT: call void @__sanitizer_cov_stack_depth()98; CB128-NOT: call void @__sanitizer_cov_stack_depth()99; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()100; COMMON-NEXT: ret i32 [[CALL]]101entry:102 %var1 = alloca i32, align 4103 %var2 = alloca i32, align 4104 %var3 = alloca i32, align 4105 %var4 = alloca i32, align 4106 107 %call = call i32 @foo()108 ret i32 %call109}110 111; 32 byte stack of scalars112define i32 @alloc32_0() {113; COMMON-LABEL: define i32 @alloc32_0() {114; COMMON-NEXT: entry:115; COMMON-NEXT: [[VAR:%.*]] = alloca i64, align 8116; COMMON-NEXT: [[VAR:%.*]] = alloca i64, align 8117; COMMON-NEXT: [[VAR:%.*]] = alloca i64, align 8118; COMMON-NEXT: [[VAR:%.*]] = alloca i64, align 8119; CB1-NEXT: call void @__sanitizer_cov_stack_depth()120; CB8-NEXT: call void @__sanitizer_cov_stack_depth()121; CB16-NEXT: call void @__sanitizer_cov_stack_depth()122; CB32-NEXT: call void @__sanitizer_cov_stack_depth()123; CB64-NOT: call void @__sanitizer_cov_stack_depth()124; CB128-NOT: call void @__sanitizer_cov_stack_depth()125; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()126; COMMON-NEXT: ret i32 [[CALL]]127entry:128 %var1 = alloca i64, align 8129 %var2 = alloca i64, align 8130 %var3 = alloca i64, align 8131 %var4 = alloca i64, align 8132 133 %call = call i32 @foo()134 ret i32 %call135}136 137; 36 byte stack of 1 4 byte scalar and 1 32 byte array138define i32 @alloc4_32x1() {139; COMMON-LABEL: define i32 @alloc4_32x1() {140; COMMON-NEXT: entry:141; COMMON-NEXT: [[VAR:%.*]] = alloca i8, i32 32, align 4142; COMMON-NEXT: [[VAR:%.*]] = alloca i32, align 4143; CB1-NEXT: call void @__sanitizer_cov_stack_depth()144; CB8-NEXT: call void @__sanitizer_cov_stack_depth()145; CB16-NEXT: call void @__sanitizer_cov_stack_depth()146; CB32-NEXT: call void @__sanitizer_cov_stack_depth()147; CB64-NOT: call void @__sanitizer_cov_stack_depth()148; CB128-NOT: call void @__sanitizer_cov_stack_depth()149; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()150; COMMON-NEXT: ret i32 [[CALL]]151entry:152 %stack_array1 = alloca i8, i32 32, align 4153 %var1 = alloca i32, align 4154 155 %call = call i32 @foo()156 ret i32 %call157}158 159; 64 byte stack of 2 32 byte arrays160define i32 @alloc0_32x2() {161; COMMON-LABEL: define i32 @alloc0_32x2() {162; COMMON-NEXT: entry:163; COMMON-NEXT: [[VAR:%.*]] = alloca i8, i32 32, align 4164; COMMON-NEXT: [[VAR:%.*]] = alloca i8, i32 32, align 4165; CB1-NEXT: call void @__sanitizer_cov_stack_depth()166; CB8-NEXT: call void @__sanitizer_cov_stack_depth()167; CB16-NEXT: call void @__sanitizer_cov_stack_depth()168; CB32-NEXT: call void @__sanitizer_cov_stack_depth()169; CB64-NEXT: call void @__sanitizer_cov_stack_depth()170; CB128-NOT: call void @__sanitizer_cov_stack_depth()171; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()172; COMMON-NEXT: ret i32 [[CALL]]173entry:174 %stack_array1 = alloca i8, i32 32, align 4175 %stack_array2 = alloca i8, i32 32, align 4176 177 %call = call i32 @foo()178 ret i32 %call179}180 181; 64 byte stack of 1 64 byte array182define i32 @alloc0_64x1() {183; COMMON-LABEL: define i32 @alloc0_64x1() {184; COMMON-NEXT: entry:185; COMMON-NEXT: [[VAR:%.*]] = alloca i8, i32 64, align 4186; CB1-NEXT: call void @__sanitizer_cov_stack_depth()187; CB8-NEXT: call void @__sanitizer_cov_stack_depth()188; CB16-NEXT: call void @__sanitizer_cov_stack_depth()189; CB32-NEXT: call void @__sanitizer_cov_stack_depth()190; CB64-NEXT: call void @__sanitizer_cov_stack_depth()191; CB128-NOT: call void @__sanitizer_cov_stack_depth()192; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()193; COMMON-NEXT: ret i32 [[CALL]]194entry:195 %stack_array = alloca i8, i32 64, align 4196 197 %call = call i32 @foo()198 ret i32 %call199}200 201; dynamic stack sized by i32202define i32 @alloc0_32xDyn(i32 %input) {203; COMMON-LABEL: define i32 @alloc0_32xDyn(i32 %input) {204; COMMON-NEXT: entry:205; COMMON-NEXT: [[VAR:%.*]] = alloca i8, i32 %input, align 4206; CB1-NEXT: call void @__sanitizer_cov_stack_depth()207; CB8-NEXT: call void @__sanitizer_cov_stack_depth()208; CB16-NEXT: call void @__sanitizer_cov_stack_depth()209; CB32-NEXT: call void @__sanitizer_cov_stack_depth()210; CB64-NEXT: call void @__sanitizer_cov_stack_depth()211; CB128-NEXT: call void @__sanitizer_cov_stack_depth()212; COMMON-NEXT: [[CALL:%.*]] = call i32 @foo()213; COMMON-NEXT: ret i32 [[CALL]]214entry:215 %stack_array1 = alloca i8, i32 %input, align 4216 217 %call = call i32 @foo()218 ret i32 %call219}220 221; true dynamic stack sized by i32, from C:222; static int dyamic_alloca(int size)223; {224; int array[size];225; return foo();226; }227define dso_local i32 @dynamic_alloca(i32 noundef %0) #0 {228 %2 = alloca i32, align 4229 %3 = alloca ptr, align 8230 %4 = alloca i64, align 8231 store i32 %0, ptr %2, align 4232 %5 = load i32, ptr %2, align 4233 %6 = zext i32 %5 to i64234; COMMON-LABEL: %7 = call ptr @llvm.stacksave235; COMMON-NEXT: store ptr %7, ptr %3, align 8236; COMMON-NEXT: [[VAR:%.*]] = alloca i32, i64 %6, align 16237; CB1-NEXT: call void @__sanitizer_cov_stack_depth()238; CB8-NEXT: call void @__sanitizer_cov_stack_depth()239; CB16-NEXT: call void @__sanitizer_cov_stack_depth()240; CB32-NEXT: call void @__sanitizer_cov_stack_depth()241; CB64-NEXT: call void @__sanitizer_cov_stack_depth()242; CB128-NEXT: call void @__sanitizer_cov_stack_depth()243 %7 = call ptr @llvm.stacksave.p0()244 store ptr %7, ptr %3, align 8245 %8 = alloca i32, i64 %6, align 16246 store i64 %6, ptr %4, align 8247 %9 = call i32 @foo()248 %10 = load ptr, ptr %3, align 8249; COMMON-LABEL: call void @llvm.stackrestore250; COMMON-NEXT: ret i32 %9251 call void @llvm.stackrestore.p0(ptr %10)252 ret i32 %9253}254