Skip to content
Snippets Groups Projects
Commit c6ffb6cd authored by Strahinja Petrovic's avatar Strahinja Petrovic
Browse files

This patch fixes problem with passing structures and unions

smaller than register as argument in variadic functions on
big endian architectures.
Differential Revision: http://reviews.llvm.org/D21611


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273665 91177308-0d34-0410-b5e6-96231b3b80d8
parent 96fd8da1
No related branches found
No related tags found
No related merge requests found
......@@ -272,7 +272,8 @@ static Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF,
// If the argument is smaller than a slot, and this is a big-endian
// target, the argument will be right-adjusted in its slot.
if (DirectSize < SlotSize && CGF.CGM.getDataLayout().isBigEndian()) {
if (DirectSize < SlotSize && CGF.CGM.getDataLayout().isBigEndian() &&
!DirectTy->isStructTy()) {
Addr = CGF.Builder.CreateConstInBoundsByteGEP(Addr, SlotSize - DirectSize);
}
......
// RUN: %clang -O2 -target mips-linux-gnu -EB -S -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS
// RUN: %clang -O2 -target mips64-linux-gnu -EB -S -emit-llvm %s -o - | FileCheck %s -check-prefix=MIPS64
// RUN: %clang -O2 -target armeb-linux-gnueabihf -march=armv7a -EB -S -emit-llvm %s -o - | FileCheck %s -check-prefix=ARM
#include <stdarg.h>
#include <stdlib.h>
struct tiny {
char c;
};
union data {
char c;
};
void fstr(int n, ...) {
struct tiny x;
va_list ap;
va_start (ap,n);
x = va_arg (ap, struct tiny);
if (x.c != 10)
abort();
va_end (ap);
// MIPS-NOT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %argp.cur, i32 3
// MIPS64-NOT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %argp.cur, i64 7
// ARM-NOT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %argp.cur, i32 3
}
void funi(int n, ...) {
union data x;
va_list ap;
va_start (ap,n);
x = va_arg (ap, union data);
if (x.c != 10)
abort();
va_end (ap);
// MIPS-NOT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %argp.cur, i32 3
// MIPS64-NOT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %argp.cur, i64 7
// ARM-NOT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %argp.cur, i32 3
}
void foo() {
struct tiny x[3];
union data y;
x[0].c = 10;
fstr(1, x[0]);
funi(1, y);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment