Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test][msan] Precommit tests for vararg improvements #72612

Merged
merged 1 commit into from
Nov 17, 2023

Conversation

vitalybuka
Copy link
Collaborator

No description provided.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 17, 2023

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Vitaly Buka (vitalybuka)

Changes

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 --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]

Copy link

github-actions bot commented Nov 17, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@kstoimenov kstoimenov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need separate ll files for ARM and X86? Is there a way to combine those?

@vitalybuka
Copy link
Collaborator Author

Why do we need separate ll files for ARM and X86? Is there a way to combine those?

VarArg is ABI specific
IR is different even before sanitizer instrumentation.

compiler-rt/test/msan/vararg_shadow.cpp Outdated Show resolved Hide resolved
compiler-rt/test/msan/vararg_shadow.cpp Outdated Show resolved Hide resolved
compiler-rt/test/msan/vararg_shadow.cpp Outdated Show resolved Hide resolved
compiler-rt/test/msan/vararg_shadow.cpp Outdated Show resolved Hide resolved
@vitalybuka vitalybuka merged commit 37db332 into llvm:main Nov 17, 2023
2 of 3 checks passed
@vitalybuka vitalybuka deleted the vararg branch November 17, 2023 20:37
sr-tream pushed a commit to sr-tream/llvm-project that referenced this pull request Nov 20, 2023
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants