Review for: [ARM] Separate EABI and GNUEABI lowering
Vinicius Tinti via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 3 20:17:08 PDT 2015
Hi,
I have made a patch to separate the GNUEABI lowering from EABI concerning RTLIB.
Before, both were handle as the same target.
This patch aims to fix the following:
struct my_s {
unsigned long a[18];
};
void foo(unsigned long *t) {
*(struct my_s *)t = *((struct my_s *)(1UL));
}
This code will generate a 'memcpy' call which will, on LLVM, be converted to
'__aeabi_memcpy' and then '__aeabi_memcpy4'. The issue is that GCC will not do
so. GCC keeps 'memcpy' as 'memcpy'.
I will not argue that one is correct. Instead I just want to point out that as
the target is called 'arm-linux-gnueabi' and it should IMHO behave as expected
by GNU tools. Linux and Android need workarounds that can be solved with this
patch:
* Bionic from Android wraps '__aeabi_memcpy4' to 'memcpy' [1].
* LLVMLinux wraps it too (NOTE: patch not in mainline) [2].
Please give your thoughts and suggestions.
http://reviews.llvm.org/D12413
[1] https://android.googlesource.com/platform/bionic/+/master/libc/arch-arm/bionic/__aeabi.c
[2] http://git.linuxfoundation.org/?p=llvmlinux.git;a=blob_plain;f=arch/arm/patches/eabi-arm.patch;hb=8ee017d41f46b40af20d7b7a9cc28618c9c7181c
Regards,
Vinicius
-------------- next part --------------
Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp
+++ lib/Target/ARM/ARMISelLowering.cpp
@@ -249,8 +249,11 @@
setLibcallName(RTLIB::SRL_I128, nullptr);
setLibcallName(RTLIB::SRA_I128, nullptr);
- if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO() &&
- !Subtarget->isTargetWindows()) {
+ // FIXME: __aeabi_d2h currently is not implemented in GNUAEABI and should
+ // not be emited. However it is probably missing.
+ // Common RTLIB to AEABI and GNUAEABI
+ if (Subtarget->isAAPCS_ABI() &&
+ (Subtarget->isTargetAEABI() || Subtarget->isTargetGNUAEABI())) {
static const struct {
const RTLIB::Libcall Op;
const char * const Name;
@@ -338,7 +341,24 @@
{ RTLIB::UDIV_I16, "__aeabi_uidiv", CallingConv::ARM_AAPCS, ISD::SETCC_INVALID },
{ RTLIB::UDIV_I32, "__aeabi_uidiv", CallingConv::ARM_AAPCS, ISD::SETCC_INVALID },
{ RTLIB::UDIV_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS, ISD::SETCC_INVALID },
+ };
+ for (const auto &LC : LibraryCalls) {
+ setLibcallName(LC.Op, LC.Name);
+ setLibcallCallingConv(LC.Op, LC.CC);
+ if (LC.Cond != ISD::SETCC_INVALID)
+ setCmpLibcallCC(LC.Op, LC.Cond);
+ }
+ }
+
+ // RTLIB to AEABI only
+ if (Subtarget->isAAPCS_ABI() && Subtarget->isTargetAEABI()) {
+ static const struct {
+ const RTLIB::Libcall Op;
+ const char * const Name;
+ const CallingConv::ID CC;
+ const ISD::CondCode Cond;
+ } LibraryCalls[] = {
// Memory operations
// RTABI chapter 4.3.4
{ RTLIB::MEMCPY, "__aeabi_memcpy", CallingConv::ARM_AAPCS, ISD::SETCC_INVALID },
Index: lib/Target/ARM/ARMSubtarget.h
===================================================================
--- lib/Target/ARM/ARMSubtarget.h
+++ lib/Target/ARM/ARMSubtarget.h
@@ -375,6 +375,12 @@
TargetTriple.getEnvironment() == Triple::EABIHF) &&
!isTargetDarwin() && !isTargetWindows();
}
+ bool isTargetGNUAEABI() const {
+ return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
+ TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
+ TargetTriple.getEnvironment() == Triple::Android) &&
+ !isTargetDarwin() && !isTargetWindows();
+ }
// ARM Targets that support EHABI exception handling standard
// Darwin uses SjLj. Other targets might need more checks.
Index: test/CodeGen/ARM/fp16-promote.ll
===================================================================
--- test/CodeGen/ARM/fp16-promote.ll
+++ test/CodeGen/ARM/fp16-promote.ll
@@ -269,10 +269,10 @@
; CHECK-FP16-LABEL: test_fptosi_i64:
; CHECK-FP16: vcvtb.f32.f16
-; CHECK-FP16: bl __aeabi_f2lz
+; CHECK-FP16: bl __fixsfdi
; CHECK-LIBCALL-LABEL: test_fptosi_i64:
; CHECK-LIBCALL: bl __gnu_h2f_ieee
-; CHECK-LIBCALL: bl __aeabi_f2lz
+; CHECK-LIBCALL: bl __fixsfdi
define i64 @test_fptosi_i64(half* %p) #0 {
%a = load half, half* %p, align 2
%r = fptosi half %a to i64
@@ -293,10 +293,10 @@
; CHECK-FP16-LABEL: test_fptoui_i64:
; CHECK-FP16: vcvtb.f32.f16
-; CHECK-FP16: bl __aeabi_f2ulz
+; CHECK-FP16: bl __fixunssfdi
; CHECK-LIBCALL-LABEL: test_fptoui_i64:
; CHECK-LIBCALL: bl __gnu_h2f_ieee
-; CHECK-LIBCALL: bl __aeabi_f2ulz
+; CHECK-LIBCALL: bl __fixunssfdi
define i64 @test_fptoui_i64(half* %p) #0 {
%a = load half, half* %p, align 2
%r = fptoui half %a to i64
@@ -328,10 +328,10 @@
}
; CHECK-FP16-LABEL: test_sitofp_i64:
-; CHECK-FP16: bl __aeabi_l2f
+; CHECK-FP16: bl __floatdisf
; CHECK-FP16: vcvtb.f16.f32
; CHECK-LIBCALL-LABEL: test_sitofp_i64:
-; CHECK-LIBCALL: bl __aeabi_l2f
+; CHECK-LIBCALL: bl __floatdisf
; CHECK-LIBCALL: bl __gnu_f2h_ieee
define void @test_sitofp_i64(i64 %a, half* %p) #0 {
%r = sitofp i64 %a to half
@@ -340,10 +340,10 @@
}
; CHECK-FP16-LABEL: test_uitofp_i64:
-; CHECK-FP16: bl __aeabi_ul2f
+; CHECK-FP16: bl __floatundisf
; CHECK-FP16: vcvtb.f16.f32
; CHECK-LIBCALL-LABEL: test_uitofp_i64:
-; CHECK-LIBCALL: bl __aeabi_ul2f
+; CHECK-LIBCALL: bl __floatundisf
; CHECK-LIBCALL: bl __gnu_f2h_ieee
define void @test_uitofp_i64(i64 %a, half* %p) #0 {
%r = uitofp i64 %a to half
@@ -362,9 +362,9 @@
}
; CHECK-FP16-LABEL: test_fptrunc_double:
-; CHECK-FP16: bl __aeabi_d2h
+; CHECK-FP16: bl __truncdfhf2
; CHECK-LIBCALL-LABEL: test_fptrunc_double:
-; CHECK-LIBCALL: bl __aeabi_d2h
+; CHECK-LIBCALL: bl __truncdfhf2
define void @test_fptrunc_double(double %d, half* %p) #0 {
%a = fptrunc double %d to half
store half %a, half* %p
Index: test/CodeGen/ARM/memfunc.ll
===================================================================
--- test/CodeGen/ARM/memfunc.ll
+++ test/CodeGen/ARM/memfunc.ll
@@ -2,6 +2,9 @@
; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
+; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
+; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
+; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
define void @f1(i8* %dest, i8* %src) {
entry:
@@ -10,11 +13,13 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
; EABI memset swaps arguments
@@ -24,6 +29,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 0, i1 false)
; EABI uses memclr if value set to 0
@@ -32,48 +39,57 @@
; CHECK-DARWIN: movs r1, #0
; CHECK-DARWIN: memset
; CHECK-EABI: __aeabi_memclr
+ ; CHECK-GNUEABI: memset
call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 0, i1 false)
-
+
; EABI uses aligned function variants if possible
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove4
+ ; CHECK-GNUEABI: memmove
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy4
+ ; CHECK-GNUEABI: memcpy
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
; CHECK-IOS: memset
; CHECK-DARWIN: memset
; CHECK-EABI: __aeabi_memset4
+ ; CHECK-GNUEABI: memset
call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 4, i1 false)
; CHECK-IOS: memset
; CHECK-DARWIN: memset
; CHECK-EABI: __aeabi_memclr4
+ ; CHECK-GNUEABI: memset
call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 4, i1 false)
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove8
+ ; CHECK-GNUEABI: memmove
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy8
+ ; CHECK-GNUEABI: memcpy
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
; CHECK-IOS: memset
; CHECK-DARWIN: memset
; CHECK-EABI: __aeabi_memset8
+ ; CHECK-GNUEABI: memset
call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 8, i1 false)
; CHECK-IOS: memset
; CHECK-DARWIN: memset
; CHECK-EABI: __aeabi_memclr8
+ ; CHECK-GNUEABI: memset
call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 8, i1 false)
unreachable
@@ -91,6 +107,8 @@
; CHECK-DARWIN: memmove
; CHECK-EABI: add r1, sp, #28
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: add r1, sp, #28
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [9 x i8], align 1
%0 = bitcast [9 x i8]* %arr0 to i8*
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -99,6 +117,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [9 x i8], align 1
%1 = bitcast [9 x i8]* %arr1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -112,6 +131,9 @@
; CHECK-EABI: add r0, sp, #4
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: add r0, sp, #4
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [9 x i8], align 1
%2 = bitcast [9 x i8]* %arr2 to i8*
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -128,6 +150,7 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [7 x i8], align 1
%0 = bitcast [7 x i8]* %arr0 to i8*
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -136,6 +159,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [7 x i8], align 1
%1 = bitcast [7 x i8]* %arr1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -147,6 +171,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [7 x i8], align 1
%2 = bitcast [7 x i8]* %arr2 to i8*
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -163,6 +189,7 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [9 x i8], align 1
%0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -171,6 +198,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [9 x i8], align 1
%1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -182,6 +210,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [9 x i8], align 1
%2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -198,6 +228,7 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [13 x i8], align 1
%0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -206,6 +237,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [13 x i8], align 1
%1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -217,6 +249,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [13 x i8], align 1
%2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -233,6 +267,7 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [13 x i8], align 1
%0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -241,6 +276,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [13 x i8], align 1
%1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -252,6 +288,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [13 x i8], align 1
%2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -268,6 +306,7 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [13 x i8], align 1
%0 = getelementptr [13 x i8], [13 x i8]* %arr0, i32 0, i32 4
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -276,6 +315,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [13 x i8], align 1
%1 = getelementptr [13 x i8], [13 x i8]* %arr1, i32 0, i32 4
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -287,6 +327,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [13 x i8], align 1
%2 = getelementptr [13 x i8], [13 x i8]* %arr2, i32 0, i32 4
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -303,6 +345,7 @@
; CHECK-IOS: memmove
; CHECK-DARWIN: memmove
; CHECK-EABI: __aeabi_memmove
+ ; CHECK-GNUEABI: memmove
%arr0 = alloca [13 x i8], align 1
%0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 16
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
@@ -311,6 +354,7 @@
; CHECK-IOS: memcpy
; CHECK-DARWIN: memcpy
; CHECK-EABI: __aeabi_memcpy
+ ; CHECK-GNUEABI: memcpy
%arr1 = alloca [13 x i8], align 1
%1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 16
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
@@ -322,6 +366,8 @@
; CHECK-DARWIN: memset
; CHECK-EABI: mov r2, #1
; CHECK-EABI: __aeabi_memset
+ ; CHECK-GNUEABI: mov r1, #1
+ ; CHECK-GNUEABI: memset
%arr2 = alloca [13 x i8], align 1
%2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 16
call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
@@ -357,6 +403,7 @@
; CHECK-IOS: .align 3
; CHECK-DARWIN: .align 2
; CHECK-EABI: .align 2
+; CHECK-GNUEABI: .align 2
; CHECK: arr2:
; CHECK: {{\.section.+foo,bar}}
; CHECK-NOT: .align
More information about the llvm-commits
mailing list