[compiler-rt] [llvm] [test][msan] Precommit tests for vararg improvements (PR #72612)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 16 22:08:43 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Vitaly Buka (vitalybuka)
<details>
<summary>Changes</summary>
---
Patch is 227.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72612.diff
3 Files Affected:
- (added) compiler-rt/test/msan/vararg_shadow.cpp (+256)
- (added) llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg_shadow.ll (+1890)
- (added) llvm/test/Instrumentation/MemorySanitizer/X86/vararg_shadow.ll (+1314)
``````````diff
diff --git a/compiler-rt/test/msan/vararg_shadow.cpp b/compiler-rt/test/msan/vararg_shadow.cpp
new file mode 100644
index 000000000000000..00c5002a9be8e06
--- /dev/null
+++ b/compiler-rt/test/msan/vararg_shadow.cpp
@@ -0,0 +1,256 @@
+// Check that shadow of retrived value from va_list matches the shadow of passed value.
+
+// Without -fno-sanitize-memory-param-retval we can't even pass poisoned values.
+// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -fsanitize-memory-track-origins=0 -O3 %s -o %t
+
+// Nothing works yet.
+// XFAIL: *
+
+#include <sanitizer/msan_interface.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DEBUG_TEST 0
+
+#if DEBUG_TEST
+__attribute__((noinline, no_sanitize("memory"))) void
+printb(const void *p, size_t n, int line, int align) {
+ fprintf(stderr, "\n%p at line %d: \n", p, line);
+ for (int i = 0; i < n;) {
+ fprintf(stderr, "%p: ", (void *)(((uint8_t *)p) + i));
+ for (int j = 0; j < align; ++i, ++j)
+ fprintf(stderr, "%02x ", ((uint8_t *)p)[i]);
+ fprintf(stderr, "\n");
+ }
+}
+
+struct my_va_list {
+# ifdef __ARM_ARCH_ISA_A64
+ void *stack;
+ void *gr_top;
+ void *vr_top;
+ int gr_offs;
+ int vr_offs;
+# else
+ unsigned int gp_offset;
+ unsigned int fp_offset;
+ void *overflow_arg_area;
+ void *reg_save_area;
+# endif
+};
+
+__attribute__((noinline, no_sanitize("memory"))) void printva(const void *p,
+ int line) {
+ my_va_list *pp = (my_va_list *)p;
+# ifdef __ARM_ARCH_ISA_A64
+ fprintf(stderr,
+ "\nva %p at line %d: stack : %p\n gr_top: %p\n vr_top: %p\n gr_offs: "
+ "%d\n "
+ "vr_offs: %d\n",
+ p, line, pp->stack, pp->gr_top, pp->vr_top, pp->gr_offs, pp->vr_offs);
+
+ printb((char *)pp->gr_top + pp->gr_offs, -pp->gr_offs, __LINE__, 8);
+ printb((char *)pp->vr_top + pp->vr_offs, -pp->vr_offs, __LINE__, 16);
+ printb((char *)pp->stack, 256, __LINE__, 8);
+# else
+ fprintf(stderr,
+ "\nva %p at line %d:\n gp_offset: %u\n fp_offset: %u\n "
+ "overflow_arg_area: %p\n reg_save_area: %p\n\n",
+ p, line, pp->gp_offset, pp->fp_offset, pp->overflow_arg_area,
+ pp->reg_save_area);
+
+ printb((char *)pp->reg_save_area + pp->gp_offset,
+ pp->fp_offset - pp->gp_offset, __LINE__, 8);
+ printb((char *)pp->reg_save_area + pp->fp_offset, 128, __LINE__, 16);
+ printb((char *)pp->overflow_arg_area, 256, __LINE__, 8);
+# endif
+}
+
+__attribute__((noinline, no_sanitize("memory"))) void printtls(int line) {
+ uint8_t tmp[kMsanParamTlsSize];
+ for (int i = 0; i < kMsanParamTlsSize; ++i)
+ tmp[i] = __msan_va_arg_tls[i];
+ fprintf(stderr, "\nTLS at line %d: ", line);
+ for (int i = 0; i < kMsanParamTlsSize;) {
+ fprintf(stderr, "\n");
+ for (int j = 0; j < 16; ++i, ++j)
+ fprintf(stderr, "%02x ", tmp[i]);
+ }
+
+ fprintf(stderr, "\n");
+}
+#endif
+
+const int kMsanParamTlsSize = 800;
+extern "C" __thread uint8_t __msan_va_arg_tls[];
+
+struct IntInt {
+ int a;
+ int b;
+};
+
+struct Int64Int64 {
+ int64_t a;
+ int64_t b;
+};
+
+struct DoubleDouble {
+ double a;
+ double b;
+};
+
+struct Double4 {
+ double a[4];
+};
+
+struct DoubleFloat {
+ double a;
+ float b;
+};
+
+struct LongDouble2 {
+ long double a[2];
+};
+
+struct LongDouble4 {
+ long double a[4];
+};
+
+template <class T>
+__attribute__((noinline)) void print_shadow(va_list &args, int n,
+ const char *function) {
+ for (int i = 0; i < n; i++) {
+ // 1-based to make it different from clean shadow.
+ fprintf(stderr, "\nArgShadow fn:%s n:%d i:%02x ", function, n, i + 1);
+ T arg_int = va_arg(args, T);
+ if (__msan_test_shadow(&arg_int, sizeof(arg_int)))
+ fprintf(stderr, "fale[clean] %02x", i + 1);
+ else
+ __msan_dump_shadow(&arg_int, sizeof(arg_int));
+#if DEBUG_TEST
+ printb(&arg_int, sizeof(arg_int), __LINE__, 16);
+#endif
+ }
+}
+
+template <class T> __attribute__((noinline)) void test1(int n, ...) {
+#if DEBUG_TEST
+ printtls(__LINE__);
+#endif
+ va_list args;
+ va_start(args, n);
+#if DEBUG_TEST
+ printva(&args, __LINE__);
+#endif
+ print_shadow<T>(args, n, __FUNCTION__);
+ va_end(args);
+}
+
+template <class T> __attribute__((noinline)) void test2(T t, int n, ...) {
+#if DEBUG_TEST
+ printtls(__LINE__);
+#endif
+ va_list args;
+ va_start(args, n);
+#if DEBUG_TEST
+ printva(&args, __LINE__);
+#endif
+ print_shadow<T>(args, n, __FUNCTION__);
+ va_end(args);
+}
+
+template <class T> __attribute__((noinline)) void test() {
+ // Array of values we will pass into variadic functions.
+ static T args[32] = {};
+
+ // Poison values making the fist byte of the item shadow match the index.
+ // E.g. item 3 should be poisoned as '03 ff ff ff'.
+ memset(args, 0xff, sizeof(args));
+ __msan_poison(args, sizeof(args));
+ for (int i = 0; i < 32; ++i) {
+ char *first = (char *)(&args[i]);
+ *first = char(*(int *)(first)&i);
+ }
+#if DEBUG_TEST
+ __msan_print_shadow(args, sizeof(args));
+#endif
+
+ // Now we will check that index, printed like 'i:03' will match
+ // '0x123abc[0x123abc] 03 ff ff ff'
+ memset(__msan_va_arg_tls, 0xee, kMsanParamTlsSize);
+ test1<T>(1, args[1]);
+ // CHECK-COUNT-1: ArgShadow fn:test1 n:1 i:[[ARGI:[[:xdigit:]]{2}]] {{[^]]+}}] [[ARGI]]
+
+ memset(__msan_va_arg_tls, 0xee, kMsanParamTlsSize);
+ test1<T>(4, args[1], args[2], args[3], args[4]);
+ // CHECK-COUNT-4: ArgShadow fn:test1 n:4 i:[[ARGI:[[:xdigit:]]{2}]] {{[^]]+}}] [[ARGI]]
+
+ memset(__msan_va_arg_tls, 0xee, kMsanParamTlsSize);
+ test1<T>(20, args[1], args[2], args[3], args[4], args[5], args[6], args[7],
+ args[8], args[9], args[10], args[11], args[12], args[13], args[14],
+ args[15], args[16], args[17], args[18], args[19], args[20]);
+ // CHECK-COUNT-20: ArgShadow fn:test1 n:20 i:[[ARGI:[[:xdigit:]]{2}]] {{[^]]+}}] [[ARGI]]
+
+ memset(__msan_va_arg_tls, 0xee, kMsanParamTlsSize);
+ test2<T>(args[31], 1, args[1]);
+ // CHECK-COUNT-1: ArgShadow fn:test2 n:1 i:[[ARGI:[[:xdigit:]]{2}]] {{[^]]+}}] [[ARGI]]
+
+ memset(__msan_va_arg_tls, 0xee, kMsanParamTlsSize);
+ test2<T>(args[31], 4, args[1], args[2], args[3], args[4]);
+ // CHECK-COUNT-4: ArgShadow fn:test2 n:4 i:[[ARGI:[[:xdigit:]]{2}]] {{[^]]+}}] [[ARGI]]
+
+ memset(__msan_va_arg_tls, 0xee, kMsanParamTlsSize);
+ test2<T>(args[31], 20, args[1], args[2], args[3], args[4], args[5], args[6],
+ args[7], args[8], args[9], args[10], args[11], args[12], args[13],
+ args[14], args[15], args[16], args[17], args[18], args[19],
+ args[20]);
+ // CHECK-COUNT-20: ArgShadow fn:test2 n:20 i:[[ARGI:[[:xdigit:]]{2}]] {{[^]]+}}] [[ARGI]]
+}
+
+int main(int argc, char *argv[]) {
+#define TEST(T...) \
+ if (argc == 2 && strcmp(argv[1], #T) == 0) { \
+ test<T>(); \
+ return 0; \
+ }
+
+ TEST(char);
+ // RUN: %run %t char 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(int);
+ // RUN: %run %t int 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(float);
+ // RUN: %run %t float 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(double);
+ // RUN: %run %t double 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(long double);
+ // RUN: %run %t "long double" 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(IntInt);
+ // RUN: %run %t IntInt 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(Int64Int64);
+ // RUN: %run %t Int64Int64 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(DoubleDouble);
+ // RUN: %run %t DoubleDouble 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(Double4);
+ // RUN: %run %t Double4 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(DoubleFloat);
+ // RUN: %run %t DoubleFloat 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(LongDouble2);
+ // RUN: %run %t LongDouble2 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ TEST(LongDouble4);
+ // RUN: %run %t LongDouble4 2>&1 | FileCheck %s --implicit-check-not="ArgShadow" --check-prefixes=CHECK
+
+ return 1;
+}
diff --git a/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg_shadow.ll b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg_shadow.ll
new file mode 100644
index 000000000000000..66f4d61f444f34e
--- /dev/null
+++ b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg_shadow.ll
@@ -0,0 +1,1890 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-grtev4-linux-gnu"
+
+%struct.IntInt = type { i32, i32 }
+%struct.Int64Int64 = type { i64, i64 }
+%struct.DoubleDouble = type { double, double }
+%struct.Double4 = type { [4 x double] }
+%struct.DoubleFloat = type { double, float }
+%struct.LongDouble2 = type { [2 x fp128] }
+%struct.LongDouble4 = type { [4 x fp128] }
+%"struct.std::__va_list" = type { ptr, ptr, ptr, i32, i32 }
+
+define linkonce_odr dso_local void @_Z4testIcEvT_(i8 noundef %arg) sanitize_memory {
+; CHECK-LABEL: define linkonce_odr dso_local void @_Z4testIcEvT_(
+; CHECK-SAME: i8 noundef [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @llvm.donothing()
+; CHECK-NEXT: [[ARG_ADDR:%.*]] = alloca i8, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], 193514046488576
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP3]], i8 -1, i64 1, i1 false)
+; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 193514046488576
+; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
+; CHECK-NEXT: store i8 [[TMP0]], ptr [[TMP6]], align 4
+; CHECK-NEXT: store i8 [[ARG]], ptr [[ARG_ADDR]], align 4
+; CHECK-NEXT: store i64 0, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @_Z3usePv(ptr noundef nonnull [[ARG_ADDR]])
+; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[ARG_ADDR]], align 4
+; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP8]], 193514046488576
+; CHECK-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to ptr
+; CHECK-NEXT: [[_MSLD:%.*]] = load i8, ptr [[TMP10]], align 4
+; CHECK-NEXT: [[_MSPROP:%.*]] = zext i8 [[_MSLD]] to i32
+; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP7]] to i32
+; CHECK-NEXT: store i8 [[_MSLD]], ptr @__msan_param_tls, align 8
+; CHECK-NEXT: store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 8) to ptr), align 8
+; CHECK-NEXT: store i32 [[_MSPROP]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
+; CHECK-NEXT: store i32 [[_MSPROP]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 16) to ptr), align 8
+; CHECK-NEXT: store i64 0, ptr @__msan_va_arg_overflow_size_tls, align 8
+; CHECK-NEXT: call void (i8, i32, ...) @_Z5test2IcEvT_iz(i8 noundef [[TMP7]], i32 noundef 1, i32 noundef [[CONV]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %arg.addr = alloca i8, align 4
+ store i8 %arg, ptr %arg.addr, align 4
+ call void @_Z3usePv(ptr noundef nonnull %arg.addr)
+ %0 = load i8, ptr %arg.addr, align 4
+ %conv = zext i8 %0 to i32
+ call void (i8, i32, ...) @_Z5test2IcEvT_iz(i8 noundef %0, i32 noundef 1, i32 noundef %conv)
+ ret void
+}
+
+define linkonce_odr dso_local void @_Z4testIiEvT_(i32 noundef %arg) sanitize_memory {
+; CHECK-LABEL: define linkonce_odr dso_local void @_Z4testIiEvT_(
+; CHECK-SAME: i32 noundef [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @llvm.donothing()
+; CHECK-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], 193514046488576
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP3]], i8 -1, i64 4, i1 false)
+; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 193514046488576
+; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
+; CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP6]], align 4
+; CHECK-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4
+; CHECK-NEXT: store i64 0, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @_Z3usePv(ptr noundef nonnull [[ARG_ADDR]])
+; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARG_ADDR]], align 4
+; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP8]], 193514046488576
+; CHECK-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to ptr
+; CHECK-NEXT: [[_MSLD:%.*]] = load i32, ptr [[TMP10]], align 4
+; CHECK-NEXT: store i32 [[_MSLD]], ptr @__msan_param_tls, align 8
+; CHECK-NEXT: store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 8) to ptr), align 8
+; CHECK-NEXT: store i32 [[_MSLD]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
+; CHECK-NEXT: store i32 [[_MSLD]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 16) to ptr), align 8
+; CHECK-NEXT: store i64 0, ptr @__msan_va_arg_overflow_size_tls, align 8
+; CHECK-NEXT: call void (i32, i32, ...) @_Z5test2IiEvT_iz(i32 noundef [[TMP7]], i32 noundef 1, i32 noundef [[TMP7]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %arg.addr = alloca i32, align 4
+ store i32 %arg, ptr %arg.addr, align 4
+ call void @_Z3usePv(ptr noundef nonnull %arg.addr)
+ %0 = load i32, ptr %arg.addr, align 4
+ call void (i32, i32, ...) @_Z5test2IiEvT_iz(i32 noundef %0, i32 noundef 1, i32 noundef %0)
+ ret void
+}
+
+define linkonce_odr dso_local void @_Z4testIfEvT_(float noundef %arg) sanitize_memory {
+; CHECK-LABEL: define linkonce_odr dso_local void @_Z4testIfEvT_(
+; CHECK-SAME: float noundef [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @llvm.donothing()
+; CHECK-NEXT: [[ARG_ADDR:%.*]] = alloca float, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], 193514046488576
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP3]], i8 -1, i64 4, i1 false)
+; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 193514046488576
+; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
+; CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP6]], align 4
+; CHECK-NEXT: store float [[ARG]], ptr [[ARG_ADDR]], align 4
+; CHECK-NEXT: store i64 0, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @_Z3usePv(ptr noundef nonnull [[ARG_ADDR]])
+; CHECK-NEXT: [[TMP7:%.*]] = load float, ptr [[ARG_ADDR]], align 4
+; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP8]], 193514046488576
+; CHECK-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to ptr
+; CHECK-NEXT: [[_MSLD:%.*]] = load i32, ptr [[TMP10]], align 4
+; CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[_MSLD]] to i64
+; CHECK-NEXT: [[CONV:%.*]] = fpext float [[TMP7]] to double
+; CHECK-NEXT: store i32 [[_MSLD]], ptr @__msan_param_tls, align 8
+; CHECK-NEXT: store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 8) to ptr), align 8
+; CHECK-NEXT: store i64 [[TMP11]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
+; CHECK-NEXT: store i64 [[TMP11]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 80) to ptr), align 8
+; CHECK-NEXT: store i64 0, ptr @__msan_va_arg_overflow_size_tls, align 8
+; CHECK-NEXT: call void (float, i32, ...) @_Z5test2IfEvT_iz(float noundef [[TMP7]], i32 noundef 1, double noundef [[CONV]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %arg.addr = alloca float, align 4
+ store float %arg, ptr %arg.addr, align 4
+ call void @_Z3usePv(ptr noundef nonnull %arg.addr)
+ %0 = load float, ptr %arg.addr, align 4
+ %conv = fpext float %0 to double
+ call void (float, i32, ...) @_Z5test2IfEvT_iz(float noundef %0, i32 noundef 1, double noundef %conv)
+ ret void
+}
+
+define linkonce_odr dso_local void @_Z4testIdEvT_(double noundef %arg) sanitize_memory {
+; CHECK-LABEL: define linkonce_odr dso_local void @_Z4testIdEvT_(
+; CHECK-SAME: double noundef [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @llvm.donothing()
+; CHECK-NEXT: [[ARG_ADDR:%.*]] = alloca double, align 8
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], 193514046488576
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP3]], i8 -1, i64 8, i1 false)
+; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 193514046488576
+; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
+; CHECK-NEXT: store i64 [[TMP0]], ptr [[TMP6]], align 8
+; CHECK-NEXT: store double [[ARG]], ptr [[ARG_ADDR]], align 8
+; CHECK-NEXT: store i64 0, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @_Z3usePv(ptr noundef nonnull [[ARG_ADDR]])
+; CHECK-NEXT: [[TMP7:%.*]] = load double, ptr [[ARG_ADDR]], align 8
+; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP8]], 193514046488576
+; CHECK-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to ptr
+; CHECK-NEXT: [[_MSLD:%.*]] = load i64, ptr [[TMP10]], align 8
+; CHECK-NEXT: store i64 [[_MSLD]], ptr @__msan_param_tls, align 8
+; CHECK-NEXT: store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 8) to ptr), align 8
+; CHECK-NEXT: store i64 [[_MSLD]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
+; CHECK-NEXT: store i64 [[_MSLD]], ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 80) to ptr), align 8
+; CHECK-NEXT: store i64 0, ptr @__msan_va_arg_overflow_size_tls, align 8
+; CHECK-NEXT: call void (double, i32, ...) @_Z5test2IdEvT_iz(double noundef [[TMP7]], i32 noundef 1, double noundef [[TMP7]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %arg.addr = alloca double, align 8
+ store double %arg, ptr %arg.addr, align 8
+ call void @_Z3usePv(ptr noundef nonnull %arg.addr)
+ %0 = load double, ptr %arg.addr, align 8
+ call void (double, i32, ...) @_Z5test2IdEvT_iz(double noundef %0, i32 noundef 1, double noundef %0)
+ ret void
+}
+
+define linkonce_odr dso_local void @_Z4testIeEvT_(fp128 noundef %arg) sanitize_memory {
+; CHECK-LABEL: define linkonce_odr dso_local void @_Z4testIeEvT_(
+; CHECK-SAME: fp128 noundef [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @__msan_param_tls, align 8
+; CHECK-NEXT: call void @llvm.donothing()
+; CHECK-NEXT: [[ARG_ADDR:%.*]] = alloca fp128, align 16
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[ARG_ADDR]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], 193514046488576
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/72612
More information about the llvm-commits
mailing list