brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · 91b21ea Raw
213 lines · plain
1; RUN: opt < %s -S -mcpu=z13 -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 }7 8define i64 @foo(i64 %guard, ...) {9  %vl = alloca %struct.__va_list, align 810  call void @llvm.lifetime.start.p0(ptr %vl)11  call void @llvm.va_start(ptr %vl)12  call void @llvm.va_end(ptr %vl)13  call void @llvm.lifetime.end.p0(ptr %vl)14  ret i64 015}16 17; First check if the variadic shadow values are saved in stack with correct18; size (which is 160 - size of the register save area).19 20; CHECK-LABEL: @foo21; CHECK: [[A:%.*]] = load {{.*}} @__msan_va_arg_overflow_size_tls22; CHECK: [[B:%.*]] = add i64 160, [[A]]23; CHECK: alloca {{.*}} [[B]]24 25; We expect two memcpy operations: one for the register save area, and one for26; the overflow arg area.27 28; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 {{%.*}}, i64 160, i1 false)29; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 {{%.*}}, i64 [[A]], i1 false)30 31declare void @llvm.lifetime.start.p0(ptr nocapture) #132declare void @llvm.va_start(ptr) #233declare void @llvm.va_end(ptr) #234declare void @llvm.lifetime.end.p0(ptr nocapture) #135 36declare i32 @random_i32()37declare i64 @random_i64()38declare float @random_float()39declare double @random_double()40 41define i64 @bar() {42  %arg2 = call i32 () @random_i32()43  %arg3 = call float () @random_float()44  %arg4 = call i32 () @random_i32()45  %arg5 = call double () @random_double()46  %arg6 = call i64 () @random_i64()47  %arg9 = call i32 () @random_i32()48  %arg11 = call float () @random_float()49  %arg12 = call i32 () @random_i32()50  %arg13 = call double () @random_double()51  %arg14 = call i64 () @random_i64()52  %1 = call i64 (i64, ...) @foo(i64 1, i32 zeroext %arg2, float %arg3,53                                i32 signext %arg4, double %arg5, i64 %arg6,54                                i64 7, double 8.0, i32 zeroext %arg9,55                                double 10.0, float %arg11, i32 signext %arg12,56                                double %arg13, i64 %arg14)57  ret i64 %158}59 60; Save the incoming shadow values from the varargs in the __msan_va_arg_tls61; array at the offsets equal to those defined by the ABI for the corresponding62; registers in the register save area, and for the corresponding overflow args63; in the overflow arg area:64; - r2@16              == i64 1            - skipped, because it's fixed65; - r3@24              == i32 zext %arg2   - shadow is zero-extended66; - f0@128             == float %arg3      - left-justified, shadow is 32-bit67; - r4@32              == i32 sext %arg4   - shadow is sign-extended68; - f2@136             == double %arg5     - straightforward69; - r5@40              == i64 %arg6        - straightforward70; - r6@48              == 7                - filler71; - f4@144             == 8.0              - filler72; - overflow@160       == i32 zext %arg9   - shadow is zero-extended73; - f6@152             == 10.0             - filler74; - overflow@(168 + 4) == float %arg11     - right-justified, shadow is 32-bit75; - overflow@176       == i32 sext %arg12  - shadow is sign-extended76; - overflow@184       == double %arg13    - straightforward77; - overflow@192       == i64 %arg14       - straightforward78; Overflow arg area size is 40.79 80; CHECK-LABEL: @bar81 82; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 2483; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 12884; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 3285; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 13686; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 4087; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 4888; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 14489; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 16090; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 15291; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 17292; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 17693; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 18494; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 19295; CHECK: store {{.*}} 40, {{.*}} @__msan_va_arg_overflow_size_tls96 97; Test that MSan doesn't generate code overflowing __msan_va_arg_tls when too many arguments are98; passed to a variadic function.99 100define dso_local i64 @many_args() {101entry:102  %ret = call i64 (i64, ...) @sum(i64 120,103    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,104    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,105    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,106    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,107    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,108    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,109    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,110    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,111    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,112    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,113    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,114    i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1115  )116  ret i64 %ret117}118 119; If the size of __msan_va_arg_tls changes the second argument of `add` must also be changed.120; CHECK-LABEL: @many_args121; CHECK: i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 792)122; CHECK-NOT: i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 800)123 124declare i64 @sum(i64 %n, ...)125 126; Test offset calculation for vector arguments.127; Regardless of whether or not fixed args overflow, we should copy a shadow128; for a single vector vararg to offset 160.129 130declare void @vr_no_overflow(<4 x float> %v24, <4 x float> %v26,131                             <4 x float> %v28, <4 x float> %v30,132                             <4 x float> %v25, <4 x float> %v27,133                             <4 x float> %v29, ...)134 135declare <4 x float> @vr_value()136 137define void @vr_no_overflow_caller() {138  %1 = call <4 x float> () @vr_value()139  call void (<4 x float>, <4 x float>, <4 x float>,140             <4 x float>, <4 x float>, <4 x float>,141             <4 x float>, ...) @vr_no_overflow(142    <4 x float> %1, <4 x float> %1, <4 x float> %1, <4 x float> %1,143    <4 x float> %1, <4 x float> %1, <4 x float> %1, <4 x float> %1)144  ret void145}146 147; CHECK-LABEL: @vr_no_overflow_caller148; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 160149; CHECK-NOT: store {{.*}} @__msan_va_arg_tls {{.*}}150; CHECK: store {{.*}} 16, {{.*}} @__msan_va_arg_overflow_size_tls151 152declare void @vr_overflow(<4 x float> %v24, <4 x float> %v26,153                          <4 x float> %v28, <4 x float> %v30,154                          <4 x float> %v25, <4 x float> %v27,155                          <4 x float> %v29, <4 x float> %v31,156                          <4 x float> %overflow, ...)157 158define void @vr_overflow_caller() {159  %1 = call <4 x float> @vr_value()160  call void (<4 x float>, <4 x float>, <4 x float>,161             <4 x float>, <4 x float>, <4 x float>,162             <4 x float>, <4 x float>, <4 x float>,163             ...) @vr_overflow(164    <4 x float> %1, <4 x float> %1, <4 x float> %1, <4 x float> %1,165    <4 x float> %1, <4 x float> %1, <4 x float> %1, <4 x float> %1,166    <4 x float> %1, <4 x float> %1)167  ret void168}169 170; CHECK-LABEL: @vr_overflow_caller171; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 160172; CHECK-NOT: store {{.*}} @__msan_va_arg_tls {{.*}}173; CHECK: store {{.*}} 16, {{.*}} @__msan_va_arg_overflow_size_tls174 175; Test that i128 and fp128 are passed by reference.176 177declare i128 @random_i128()178declare fp128 @random_fp128()179 180define i64 @bar_128() {181  %iarg = call i128 @random_i128()182  %fparg = call fp128 @random_fp128()183  %1 = call i64 (i64, ...) @foo(i64 1, i128 %iarg, fp128 %fparg)184  ret i64 %1185}186 187; CHECK-LABEL: @bar_128188; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 24189; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 32190; CHECK: store {{.*}} 0, {{.*}} @__msan_va_arg_overflow_size_tls191 192; CHECK: declare void @__msan_maybe_warning_1(i8 zeroext, i32 zeroext)193; CHECK: declare void @__msan_maybe_store_origin_1(i8 zeroext, ptr, i32 zeroext)194; CHECK: declare void @__msan_maybe_warning_2(i16 zeroext, i32 zeroext)195; CHECK: declare void @__msan_maybe_store_origin_2(i16 zeroext, ptr, i32 zeroext)196; CHECK: declare void @__msan_maybe_warning_4(i32 zeroext, i32 zeroext)197; CHECK: declare void @__msan_maybe_store_origin_4(i32 zeroext, ptr, i32 zeroext)198; CHECK: declare void @__msan_maybe_warning_8(i64 zeroext, i32 zeroext)199; CHECK: declare void @__msan_maybe_store_origin_8(i64 zeroext, ptr, i32 zeroext)200 201; Test vararg function pointers.202;203; void (*ptr)(int, ...);204; void call_ptr(void) { ptr(0); }205 206@ptr = dso_local global ptr null, align 8207 208define dso_local void @call_ptr() {209  %1 = load ptr, ptr @ptr, align 8210  call void (i32, ...) %1(i32 noundef signext 0)211  ret void212}213