ABISysV_arm64: compute return value for large vectors correctly

Summary:
Arm64 Procedure Call Standard specifies than only vectors up to 16 bytes
are stored in v0 (which makes sense, as that's the size of the
register). 32-byte vector types are passed as regular structs via x8
pointer. Treat them as such.

This fixes TestReturnValue for arm64-clang. I also split the test case
into two so I can avoid the if(gcc) line, and annotate each test
instead. (It seems the vector type tests fail with gcc only when
targetting x86 arches).

Reviewers: tberghammer, eugene

Subscribers: aemerson, omjavaid, rengolin, srhines, lldb-commits

Differential Revision: https://reviews.llvm.org/D32813

llvm-svn: 302220
This commit is contained in:
Pavel Labath 2017-05-05 10:50:02 +00:00
parent 807ca72e66
commit 3559f20f17
2 changed files with 55 additions and 29 deletions

View File

@ -171,17 +171,45 @@ class ReturnValueTestCase(TestBase):
#self.return_and_test_struct_value ("return_one_int_one_double_packed")
self.return_and_test_struct_value("return_one_int_one_long")
# icc and gcc don't support this extension.
if self.getCompiler().endswith('clang'):
self.return_and_test_struct_value("return_vector_size_float32_8")
self.return_and_test_struct_value("return_vector_size_float32_16")
self.return_and_test_struct_value("return_vector_size_float32_32")
self.return_and_test_struct_value(
"return_ext_vector_size_float32_2")
self.return_and_test_struct_value(
"return_ext_vector_size_float32_4")
self.return_and_test_struct_value(
"return_ext_vector_size_float32_8")
@expectedFailureAll(oslist=["freebsd"], archs=["i386"])
@expectedFailureAll(oslist=["macosx"], archs=["i386"], bugnumber="<rdar://problem/28719652>")
@expectedFailureAll(
oslist=["linux"],
compiler="clang",
compiler_version=[
"<=",
"3.6"],
archs=["i386"])
@expectedFailureAll(
bugnumber="llvm.org/pr25785",
hostoslist=["windows"],
compiler="gcc",
archs=["i386"],
triple='.*-android')
@expectedFailureAll(compiler=["gcc"], archs=["x86_64", "i386"])
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
def test_vector_values(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
error = lldb.SBError()
self.target = self.dbg.CreateTarget(exe)
self.assertTrue(self.target, VALID_TARGET)
main_bktp = self.target.BreakpointCreateByName("main", exe)
self.assertTrue(main_bktp, VALID_BREAKPOINT)
self.process = self.target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(
self.process, main_bktp)), 1)
self.return_and_test_struct_value("return_vector_size_float32_8")
self.return_and_test_struct_value("return_vector_size_float32_16")
self.return_and_test_struct_value("return_vector_size_float32_32")
self.return_and_test_struct_value("return_ext_vector_size_float32_2")
self.return_and_test_struct_value("return_ext_vector_size_float32_4")
self.return_and_test_struct_value("return_ext_vector_size_float32_8")
def return_and_test_struct_value(self, func_name):
"""Pass in the name of the function to return from - takes in value, returns value."""

View File

@ -2362,32 +2362,30 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
if (success)
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
} else if (type_flags & eTypeIsVector && byte_size <= 16) {
if (byte_size > 0) {
const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
if (v0_info) {
if (byte_size <= v0_info->byte_size) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
new DataBufferHeap(byte_size, 0));
const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(v0_info, reg_value)) {
Error error;
if (reg_value.GetAsMemoryData(v0_info, heap_data_ap->GetBytes(),
heap_data_ap->GetByteSize(),
byte_order, error)) {
DataExtractor data(DataBufferSP(heap_data_ap.release()),
byte_order,
exe_ctx.GetProcessRef().GetAddressByteSize());
return_valobj_sp = ValueObjectConstResult::Create(
&thread, return_compiler_type, ConstString(""), data);
}
std::unique_ptr<DataBufferHeap> heap_data_ap(
new DataBufferHeap(byte_size, 0));
const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(v0_info, reg_value)) {
Error error;
if (reg_value.GetAsMemoryData(v0_info, heap_data_ap->GetBytes(),
heap_data_ap->GetByteSize(), byte_order,
error)) {
DataExtractor data(DataBufferSP(heap_data_ap.release()), byte_order,
exe_ctx.GetProcessRef().GetAddressByteSize());
return_valobj_sp = ValueObjectConstResult::Create(
&thread, return_compiler_type, ConstString(""), data);
}
}
}
}
} else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
} else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
(type_flags & eTypeIsVector && byte_size > 16)) {
DataExtractor data;
uint32_t NGRN = 0; // Search ABI docs for NGRN