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

va_arg fails with __int128 #20283

Open
llvmbot opened this issue Jun 1, 2014 · 6 comments
Open

va_arg fails with __int128 #20283

llvmbot opened this issue Jun 1, 2014 · 6 comments
Labels
ABI Application Binary Interface bugzilla Issues migrated from bugzilla

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 1, 2014

Bugzilla Link 19909
Version trunk
OS All
Attachments Demonstrate __int128 va_arg failure
Reporter LLVM Bugzilla Contributor
CC @tstellar

Extended Description

The attached example fails on Clang/LLVM trunk (or 3.4 or Apple 3.4) and passes when compiled with gcc 4.8.2. The code simple tries to pass multiple __int128 after two ints and a pointer. I debugged it a bit and it seems that the "overflow_arg_area" pointer in va_list is wrong by 8 bytes, which might indicate some alignment problem.

I also checked how __int128 is passed to the function. It seems that Clang is capable of splitting the __int128 where lower part is passed in a register and upper part on the stack. GCC does not split __int128 if it does not have 2 registers available. This might explain the wrong 8 bytes offset for the "overflow_arg_area" as va_start does not adjust for the split register.

@tstellar
Copy link
Collaborator

mentioned in issue llvm/llvm-bugzilla-archive#42439

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
@tgross35
Copy link

I think this is related to #41784

@shafik
Copy link
Collaborator

shafik commented Aug 17, 2023

code: https://godbolt.org/z/bxrdrMKne

#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

int si;
void *sp;

double foo(va_list ap) {
  int x = va_arg(ap, int);
  double y = *va_arg(ap, double *);

  __int128 psi = va_arg(ap, __int128);
  assert(psi == (__int128)&si);
  __int128 psv = va_arg(ap, __int128);
  assert(psv == (__int128)&si);
  __int128 psiB = va_arg(ap, __int128);
  assert(psiB == (__int128)&si);
  __int128 psiI = va_arg(ap, __int128);
  assert(psiI == (__int128)&si);
  __int128 psi0 = va_arg(ap, __int128);
  assert(psi0 == (__int128)&si);
  __int128 psi1 = va_arg(ap, __int128);
  assert(psi1 == (__int128)&si);
  void **ppsv = va_arg(ap, void **);
  assert(*ppsv == &si);
  void **ppsv2 = va_arg(ap, void **);
  assert(*ppsv2== &si);
  return x + y;
}

double bar(int last, ...) {
  va_list ap;
  double d;

  va_start(ap, last);
  d = foo(ap);
  va_end(ap);

  return d;
}
int main(void) {
  sp = &si;
  __int128 psv = (__int128)&si;
  __int128 psi = (__int128)&si;
  __int128 psiB = psv;
  __int128 psiI = psv;
  __int128 psi0 = psv;
  __int128 psi1 = psv;
  void **ppsv = &sp;
  double a = 7.0;
  si = 10;
  double b = bar(0, 1, &a, psi, psv, psiB, psiI, psi0, psi1, ppsv, ppsv);

  if (b != 8.0) {
    /* While floating-point comparisions are not safe in general, small integers are OK */
    printf("FAILED (result = %g but expect 8.0)\n", b);
  } else {
    printf("SUCCESS\n");
  }


  return 0;
}

clang fails with the following output:

output.s: /app/example.cpp:16: double foo(__va_list_tag *): Assertion `psv == (__int128)&si' failed.
Program terminated with signal: SIGSEGV

@shafik
Copy link
Collaborator

shafik commented Aug 17, 2023

CC @AaronBallman

@tgross35
Copy link

tgross35 commented Aug 17, 2023

I believe that the patch in https://reviews.llvm.org/D86310 will fix this once it resolves the register spilling

@tgross35
Copy link

If the fix for this is easy after https://reviews.llvm.org/D86310 landed, it may be a good candidate for 18.2 to keep all i128 ABI changes within the 18.x series.

cc @nikic since you were involved with the other i128 fixes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ABI Application Binary Interface bugzilla Issues migrated from bugzilla
Projects
None yet
Development

No branches or pull requests

4 participants