From 92c6c90e9099b7e27073056b154b2d5e7d5449b1 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 3 May 2012 01:34:46 +0000 Subject: [PATCH] Merge x86-64-abi-sret-vs-2word-struct-param.cpp into the generic x86_64-arguments.cpp test file and be sure to test the coerced case as well. Thanks to Wei-Ren Chen for bringing this test to my attention. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156047 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../x86-64-abi-sret-vs-2word-struct-param.cpp | 29 ----------------- test/CodeGenCXX/x86_64-arguments.cpp | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 29 deletions(-) delete mode 100644 test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp diff --git a/test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp b/test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp deleted file mode 100644 index 1aa80f2d6e..0000000000 --- a/test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -// XTARGET: x86 -// PR4242 -// (PR 4242 bug is on 64-bit only, test passes on x86-32 as well) - -struct S { - void* data[3]; -}; - -struct T { - void* data[2]; -}; - -// CHECK: %struct.T* byval -extern "C" S fail(int, int, int, int, T t, void* p) { - S s; - s.data[0] = t.data[0]; - s.data[1] = t.data[1]; - s.data[2] = p; - return s; -} - -// CHECK: %struct.T* byval -extern "C" S* succeed(S* sret, int, int, int, int, T t, void* p) { - sret->data[0] = t.data[0]; - sret->data[1] = t.data[1]; - sret->data[2] = p; - return sret; -} diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp index e1d9dfc1fc..672180363f 100644 --- a/test/CodeGenCXX/x86_64-arguments.cpp +++ b/test/CodeGenCXX/x86_64-arguments.cpp @@ -56,6 +56,7 @@ namespace PR7742 { // Also rdar://8250764 // CHECK: define <2 x float> @_ZN6PR77423fooEPNS_2c2E(%"struct.PR7742::c2"* %P) c2 foo(c2 *P) { + return c2(); } } @@ -149,3 +150,34 @@ namespace test8 { foo(b); } } + +// PR4242 +namespace test9 { + // Large enough to be passed indirectly. + struct S { void *data[3]; }; + + struct T { void *data[2]; }; + + // CHECK: define void @_ZN5test93fooEPNS_1SEPNS_1TE([[S:%.*]]*, [[T:%.*]]*) + void foo(S*, T*) {} + + // CHECK: define void @_ZN5test91aEiiiiNS_1TEPv([[S]]* noalias sret {{%.*}}, i32, i32, i32, i32, [[T]]* byval align 8, i8*) + S a(int, int, int, int, T, void*) { + return S(); + } + + // CHECK: define [[S]]* @_ZN5test91bEPNS_1SEiiiiNS_1TEPv([[S]]* {{%.*}}, i32, i32, i32, i32, [[T:%.*]]* byval align 8, i8*) + S* b(S* sret, int, int, int, int, T, void*) { + return sret; + } + + // CHECK: define void @_ZN5test91cEiiiNS_1TEPv([[S]]* noalias sret {{%.*}}, i32, i32, i32, i8* {{%.*}}, i8* {{%.*}}, i8*) + S c(int, int, int, T, void*) { + return S(); + } + + // CHECK: define [[S]]* @_ZN5test91dEPNS_1SEiiiNS_1TEPv([[S]]* {{%.*}}, i32, i32, i32, i8* {{%.*}}, i8* {{%.*}}, i8*) + S* d(S* sret, int, int, int, T, void*) { + return sret; + } +} -- 2.40.0