[clang] [clang][CodeGen] Use byval for SystemZ indirect arguments (PR #66404)

Ilya Leoshkevich via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 14 17:08:27 PDT 2023


iii-i wrote:

There is special byval handling in MSan:

```
  void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
...
    for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
...
      bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
```

If a target does not make use of byval, I would argue that this part of MSan is broken there.
Unfortunately this applies to SystemZ at the moment: `param_tls_limit.cpp` is marked as XFAIL because of this (the rationale that is written there, which says that the test is not applicable, is not correct).

A quick experiment shows that x86_64 uses byval:

```
$ uname -m
x86_64

$ clang --version
clang version 16.0.6 (Fedora 16.0.6-2.fc38)

$ cat 1.c
struct foo { char x[800]; };
void bar(struct foo) {};

$ clang -mllvm -print-after-all -c 1.c
[...]
define dso_local void @bar(ptr noundef byval(%struct.foo) align 8 %0) #0 {
[...]
```

As for the reasons why this all is the case, I think this is because of how arguments' shadow TLS is defined: it contains shadows of all argument values, where arguments are understood in terms of C, and not in terms of the ABI. This definition is then used in the runtime. See, for example, the handling of long doubles in `dfsan_custom.cpp`:

```
static int format_buffer(char *str, size_t size, const char *fmt,
                         dfsan_label *va_labels, dfsan_label *ret_label,
                         dfsan_origin *va_origins, dfsan_origin *ret_origin,
                         va_list ap) {
[...]
        case 'G':
          if (*(formatter.fmt_cur - 1) == 'L') {
            retval = formatter.format(va_arg(ap, long double));
          } else {
            retval = formatter.format(va_arg(ap, double));
          }
          if (va_origins == nullptr)
            dfsan_set_label(*va_labels++, formatter.str_cur(),
                            formatter.num_written_bytes(retval));
          else
            dfsan_set_label_origin(*va_labels++, *va_origins++,
                                   formatter.str_cur(),
                                   formatter.num_written_bytes(retval));
          end_fmt = true;
          break;
```

Here is wants the shadow of the long double itself, even if the target ABI requires passing it through a pointer.

https://github.com/llvm/llvm-project/pull/66404


More information about the cfe-commits mailing list