Author: spetrovic Date: Fri Jun 24 07:12:41 2016 New Revision: 273665 URL: http://llvm.org/viewvc/llvm-project?rev=273665&view=rev Log: 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
Added: cfe/trunk/test/CodeGen/struct-union-BE.c Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=273665&r1=273664&r2=273665&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Fri Jun 24 07:12:41 2016 @@ -272,7 +272,8 @@ static Address emitVoidPtrDirectVAArg(Co // 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); } Added: cfe/trunk/test/CodeGen/struct-union-BE.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/struct-union-BE.c?rev=273665&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/struct-union-BE.c (added) +++ cfe/trunk/test/CodeGen/struct-union-BE.c Fri Jun 24 07:12:41 2016 @@ -0,0 +1,48 @@ +// 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); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits