176 lines · plain
1; RUN: opt < %s -S -mcpu=z13 -msan-kernel=1 -float-abi=soft -passes=msan 2>&1 | FileCheck %s2 3target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"4target triple = "s390x-unknown-linux-gnu"5 6%struct.__va_list = type { i64, i64, ptr, ptr }7declare void @llvm.lifetime.start.p0(ptr)8declare void @llvm.va_start(ptr)9declare void @llvm.va_end(ptr)10declare void @llvm.lifetime.end.p0(ptr)11 12define i64 @foo(i64 %guard, ...) #1 {13 %vl = alloca %struct.__va_list14 call void @llvm.lifetime.start.p0(ptr %vl)15 call void @llvm.va_start(ptr %vl)16 call void @llvm.va_end(ptr %vl)17 call void @llvm.lifetime.end.p0(ptr %vl)18 ret i64 019}20 21; CHECK-LABEL: define {{[^@]+}}@foo(22 23; Callers store variadic arguments' shadow and origins into va_arg_shadow and24; va_arg_origin. Their layout is: the register save area (160 bytes) followed25; by the overflow arg area. It does not depend on "packed-stack".26; Check that callees correctly backup shadow into a local variable.27 28; CHECK: [[TMP:%.*]] = alloca { ptr, ptr }29; CHECK: [[OverflowSize:%.*]] = load i64, ptr %va_arg_overflow_size30; CHECK: [[MetaSize:%.*]] = add i64 160, [[OverflowSize]]31; CHECK: [[ShadowBackup:%.*]] = alloca {{.*}} [[MetaSize]]32; CHECK: [[MetaCopySize:%.*]] = call i64 @llvm.umin.i64(i64 [[MetaSize]], i64 800)33; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[ShadowBackup]], ptr align 8 %va_arg_shadow, i64 [[MetaCopySize]], i1 false)34; CHECK: [[OverflowBackup:%.*]] = alloca {{.*}} [[MetaSize]]35; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[OverflowBackup]], ptr align 8 %va_arg_origin, i64 [[MetaCopySize]], i1 false)36 37; Check that va_start() correctly copies the shadow backup into the shadow of38; the va_list. Register save area and overflow arg area are copied separately.39; Only 56 bytes of the register save area is copied, because of40; "use-soft-float".41 42; CHECK: call void @llvm.va_start.p0(ptr %vl)43; CHECK: [[VlAddr:%.*]] = ptrtoint ptr %vl to i6444; CHECK: [[RegSaveAreaAddrAddr:%.*]] = add i64 [[VlAddr]], 2445; CHECK: [[RegSaveAreaAddr:%.*]] = inttoptr i64 [[RegSaveAreaAddrAddr]] to ptr46; CHECK: [[RegSaveArea:%.*]] = load ptr, ptr [[RegSaveAreaAddr]]47; CHECK: call void @__msan_metadata_ptr_for_store_1(ptr [[TMP]], ptr [[RegSaveArea]])48; CHECK: [[RegSaveAreaMeta:%.*]] = load { ptr, ptr }, ptr [[TMP]]49; CHECK: [[RegSaveAreaShadow:%.*]] = extractvalue { ptr, ptr } [[RegSaveAreaMeta]], 050; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RegSaveAreaShadow]], ptr align 8 [[ShadowBackup]], i64 56, i1 false)51; CHECK: [[VlAddr:%.*]] = ptrtoint ptr %vl to i6452; CHECK: [[OverflowAddrAddr:%.*]] = add i64 [[VlAddr]], 1653; CHECK: [[OverflowAddr:%.*]] = inttoptr i64 [[OverflowAddrAddr]] to ptr54; CHECK: [[Overflow:%.*]] = load ptr, ptr [[OverflowAddr]]55; CHECK: call void @__msan_metadata_ptr_for_store_1(ptr [[TMP]], ptr [[Overflow]])56; CHECK: [[OverflowMeta:%.*]] = load { ptr, ptr }, ptr [[TMP]]57; CHECK: [[OverflowShadow:%.*]] = extractvalue { ptr, ptr } [[OverflowMeta]], 058; CHECK: [[OverflowShadowBackup:%.*]] = getelementptr i8, ptr [[ShadowBackup]], i32 16059; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[OverflowShadow]], ptr align 8 [[OverflowShadowBackup]], i64 [[OverflowSize]], i1 false)60 61declare i32 @random_i32()62declare i64 @random_i64()63declare float @random_float()64declare double @random_double()65 66define i64 @bar() #1 {67 %arg2 = call i32 () @random_i32()68 %arg3 = call float () @random_float()69 %arg4 = call i32 () @random_i32()70 %arg5 = call double () @random_double()71 %arg6 = call i64 () @random_i64()72 %arg9 = call i32 () @random_i32()73 %arg11 = call float () @random_float()74 %arg12 = call i32 () @random_i32()75 %arg13 = call double () @random_double()76 %arg14 = call i64 () @random_i64()77 %1 = call i64 (i64, ...) @foo(i64 1, i32 zeroext %arg2, float %arg3,78 i32 signext %arg4, double %arg5, i64 %arg6,79 i64 7, double 8.0, i32 zeroext %arg9,80 double 10.0, float %arg11, i32 signext %arg12,81 double %arg13, i64 %arg14)82 ret i64 %183}84 85attributes #1 = { sanitize_memory "target-features"="+soft-float" "use-soft-float"="true" }86 87; In kernel the floating point values are passed in GPRs:88; - r2@16 == i64 1 - skipped, because it's fixed89; - r3@24 == i32 zext %arg2 - shadow is zero-extended90; - r4@(32 + 4) == float %arg3 - right-justified, shadow is 32-bit91; - r5@40 == i32 sext %arg4 - shadow is sign-extended92; - r6@48 == double %arg5 - straightforward93; - overflow@160 == i64 %arg6 - straightforward94; - overflow@168 == 7 - filler95; - overflow@176 == 8.0 - filler96; - overflow@184 == i32 zext %arg9 - shadow is zero-extended97; - overflow@192 == 10.0 - filler98; - overflow@(200 + 4) == float %arg11 - right-justified, shadow is 32-bit99; - overflow@208 == i32 sext %arg12 - shadow is sign-extended100; - overflow@216 == double %arg13 - straightforward101; - overflow@224 == i64 %arg14 - straightforward102; Overflow arg area size is 72.103 104; CHECK-LABEL: @bar105 106; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64107; CHECK: [[S:%.*]] = add i64 [[B]], 24108; CHECK: [[V:%.*]] = zext {{.*}}109; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr110; CHECK: store {{.*}} [[V]], {{.*}} [[M]]111 112; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64113; CHECK: [[S:%.*]] = add i64 [[B]], 36114; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr115; CHECK: store {{.*}} [[M]]116 117; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64118; CHECK: [[S:%.*]] = add i64 [[B]], 40119; CHECK: [[V:%.*]] = sext {{.*}}120; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr121; CHECK: store {{.*}} [[V]], {{.*}} [[M]]122 123; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64124; CHECK: [[S:%.*]] = add i64 [[B]], 48125; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr126; CHECK: store {{.*}} [[M]]127 128; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64129; CHECK: [[S:%.*]] = add i64 [[B]], 160130; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr131; CHECK: store {{.*}} [[M]]132 133; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64134; CHECK: [[S:%.*]] = add i64 [[B]], 168135; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr136; CHECK: store {{.*}} [[M]]137 138; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64139; CHECK: [[S:%.*]] = add i64 [[B]], 176140; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr141; CHECK: store {{.*}} [[M]]142 143; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64144; CHECK: [[S:%.*]] = add i64 [[B]], 184145; CHECK: [[V:%.*]] = zext {{.*}}146; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr147; CHECK: store {{.*}} [[V]], {{.*}} [[M]]148 149; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64150; CHECK: [[S:%.*]] = add i64 [[B]], 192151; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr152; CHECK: store {{.*}} [[M]]153 154; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64155; CHECK: [[S:%.*]] = add i64 [[B]], 204156; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr157; CHECK: store {{.*}} [[M]]158 159; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64160; CHECK: [[S:%.*]] = add i64 [[B]], 208161; CHECK: [[V:%.*]] = sext {{.*}}162; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr163; CHECK: store {{.*}} [[V]], {{.*}} [[M]]164 165; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64166; CHECK: [[S:%.*]] = add i64 [[B]], 216167; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr168; CHECK: store {{.*}} [[M]]169 170; CHECK: [[B:%.*]] = ptrtoint ptr %va_arg_shadow to i64171; CHECK: [[S:%.*]] = add i64 [[B]], 224172; CHECK: [[M:%_msarg_va_s.*]] = inttoptr i64 [[S]] to ptr173; CHECK: store {{.*}} [[M]]174 175; CHECK: store {{.*}} 72, {{.*}} %va_arg_overflow_size176