diff options
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 7 | ||||
-rw-r--r-- | clang/test/CodeGen/x86_64-arguments.c | 18 |
2 files changed, 22 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 7c850afbf8f..6d5e38daa89 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -1198,6 +1198,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Current = NoClass; uint64_t EltSize = getContext().getTypeSize(AT->getElementType()); uint64_t ArraySize = AT->getSize().getZExtValue(); + + // The only case a 256-bit wide vector could be used is when the array + // contains a single 256-bit element. Since Lo and Hi logic isn't extended + // to work for sizes wider than 128, early check and fallback to memory. + if (Size > 128 && EltSize != 256) + return; + for (uint64_t i=0, Offset=OffsetBase; i<ArraySize; ++i, Offset += EltSize) { Class FieldLo, FieldHi; classify(AT->getElementType(), Offset, FieldLo, FieldHi); diff --git a/clang/test/CodeGen/x86_64-arguments.c b/clang/test/CodeGen/x86_64-arguments.c index 3d4016db829..b0218351657 100644 --- a/clang/test/CodeGen/x86_64-arguments.c +++ b/clang/test/CodeGen/x86_64-arguments.c @@ -277,9 +277,9 @@ void f38(s256 x); void f37(__m256 x); void f39() { f38(x38); f37(x37); } -// Make sure that the struct below is passed in the same way -// regardless of avx being used -// +// The two next tests make sure that the struct below is passed +// in the same way regardless of avx being used + // CHECK: declare void @func40(%struct.t128* byval align 16) typedef float __m128 __attribute__ ((__vector_size__ (16))); typedef struct t128 { @@ -292,3 +292,15 @@ void func41(two128 s) { func40(s); } +// CHECK: declare void @func42(%struct.t128_2* byval align 16) +typedef struct xxx { + __m128 array[2]; +} Atwo128; +typedef struct t128_2 { + Atwo128 x; +} SA; + +extern void func42(SA s); +void func43(SA s) { + func42(s); +} |