From 90c138be43d778fc1c7daf3ba43668d94a871dbc Mon Sep 17 00:00:00 2001 From: Christian Pirker Date: Thu, 3 Jul 2014 09:28:12 +0000 Subject: [PATCH] ARMEB: Fix function result return for composite types Reviewed at http://reviews.llvm.org/D4364 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212261 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetInfo.cpp | 4 ++++ test/CodeGen/arm-be-result-return.c | 37 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/CodeGen/arm-be-result-return.c diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 16dee574fd..ae3caf7863 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -4379,6 +4379,10 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, // are returned indirectly. uint64_t Size = getContext().getTypeSize(RetTy); if (Size <= 32) { + if (getDataLayout().isBigEndian()) + // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4) + return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext())); + // Return in the smallest viable integer type. if (Size <= 8) return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); diff --git a/test/CodeGen/arm-be-result-return.c b/test/CodeGen/arm-be-result-return.c new file mode 100644 index 0000000000..aadc4e1884 --- /dev/null +++ b/test/CodeGen/arm-be-result-return.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple armebv7-arm-none-eabi -emit-llvm -w -o - %s | FileCheck %s + +// this tests for AAPCS section 5.4: +// A Composite Type not larger than 4 bytes is returned in r0. +// The format is as if the result had been stored in memory at a +// word-aligned address and then loaded into r0 with an LDR instruction + +extern union Us { short s; } us; +union Us callee_us() { return us; } +// CHECK-LABEL: callee_us() +// CHECK: zext i16 +// CHECK: shl +// CHECK: ret i32 + +void caller_us() { + us = callee_us(); +// CHECK-LABEL: caller_us() +// CHECK: call i32 +// CHECK: lshr i32 +// CHECK: trunc i32 +} + +extern struct Ss { short s; } ss; +struct Ss callee_ss() { return ss; } +// CHECK-LABEL: callee_ss() +// CHECK: zext i16 +// CHECK: shl +// CHECK: ret i32 + +void caller_ss() { + ss = callee_ss(); +// CHECK-LABEL: caller_ss() +// CHECK: call i32 +// CHECK: lshr i32 +// CHECK: trunc i32 +} + -- 2.40.0