forked from OSchip/llvm-project
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:
parent
807ca72e66
commit
3559f20f17
|
@ -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."""
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue