[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