forked from OSchip/llvm-project
The 0.98 revision of the x86-64 ABI clarified a lot of things, some
of which break strict compatibility with previous compilers. Implement one of them and then immediately opt out on Darwin. llvm-svn: 129899
This commit is contained in:
parent
e302c2c785
commit
e0fda7377e
|
@ -865,6 +865,15 @@ class X86_64ABIInfo : public ABIInfo {
|
|||
unsigned &neededInt,
|
||||
unsigned &neededSSE) const;
|
||||
|
||||
/// The 0.98 ABI revision clarified a lot of ambiguities,
|
||||
/// unfortunately in ways that were not always consistent with
|
||||
/// certain previous compilers. In particular, platforms which
|
||||
/// required strict binary compatibility with older versions of GCC
|
||||
/// may need to exempt themselves.
|
||||
bool honorsRevision0_98() const {
|
||||
return !getContext().Target.getTriple().isOSDarwin();
|
||||
}
|
||||
|
||||
public:
|
||||
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
||||
|
||||
|
@ -1253,15 +1262,24 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
|
|||
// (a) If one of the classes is MEMORY, the whole argument is
|
||||
// passed in memory.
|
||||
//
|
||||
// (b) If SSEUP is not preceded by SSE, it is converted to SSE.
|
||||
|
||||
// The first of these conditions is guaranteed by how we implement
|
||||
// the merge (just bail).
|
||||
// (b) If X87UP is not preceded by X87, the whole argument is
|
||||
// passed in memory.
|
||||
//
|
||||
// (c) If the size of the aggregate exceeds two eightbytes and the first
|
||||
// eight-byte isn’t SSE or any other eightbyte isn’t SSEUP, the whole
|
||||
// argument is passed in memory.
|
||||
//
|
||||
// (d) If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE.
|
||||
//
|
||||
// The second condition occurs in the case of unions; for example
|
||||
// union { _Complex double; unsigned; }.
|
||||
// Some of these are enforced by the merging logic. Others can arise
|
||||
// only with unions; for example:
|
||||
// union { _Complex double; unsigned; }
|
||||
//
|
||||
// Note that clauses (b) and (c) were added in 0.98.
|
||||
if (Hi == Memory)
|
||||
Lo = Memory;
|
||||
if (Hi == X87Up && Lo != X87 && honorsRevision0_98())
|
||||
Lo = Memory;
|
||||
if (Hi == SSEUp && Lo != SSE)
|
||||
Hi = SSE;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s| FileCheck %s
|
||||
|
||||
// rdar://9122143
|
||||
// CHECK: declare void @func(i64, double)
|
||||
typedef struct _str {
|
||||
union {
|
||||
long double a;
|
||||
long c;
|
||||
};
|
||||
} str;
|
||||
|
||||
void func(str s);
|
||||
str ss;
|
||||
void f9122143()
|
||||
{
|
||||
func(ss);
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s
|
||||
#include <stdarg.h>
|
||||
|
||||
// CHECK: %0 = type { i64, double }
|
||||
|
||||
// CHECK: define signext i8 @f0()
|
||||
char f0(void) {
|
||||
return 0;
|
||||
|
@ -44,8 +42,8 @@ void f7(e7 a0) {
|
|||
|
||||
// Test merging/passing of upper eightbyte with X87 class.
|
||||
//
|
||||
// CHECK: define %0 @f8_1()
|
||||
// CHECK: define void @f8_2(i64 %a0.coerce0, double %a0.coerce1)
|
||||
// CHECK: define void @f8_1(%struct.s19* sret %agg.result)
|
||||
// CHECK: define void @f8_2(%struct.s19* byval align 16 %a0)
|
||||
union u8 {
|
||||
long double a;
|
||||
int b;
|
||||
|
@ -245,3 +243,19 @@ v1i64 f34(v1i64 arg) { return arg; }
|
|||
typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
|
||||
v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
|
||||
|
||||
// rdar://9122143
|
||||
// CHECK: declare void @func(%struct._str* byval align 16)
|
||||
typedef struct _str {
|
||||
union {
|
||||
long double a;
|
||||
long c;
|
||||
};
|
||||
} str;
|
||||
|
||||
void func(str s);
|
||||
str ss;
|
||||
void f9122143()
|
||||
{
|
||||
func(ss);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue