john.brawn created this revision.
john.brawn added reviewers: efriedma, vhscampos, chill.
Herald added subscribers: dexonsmith, steven_wu, hiraditya, kristof.beyls.
Herald added a project: clang.
john.brawn requested review of this revision.

LLVM assumes that when it creates a call to a C library function it can use the 
C calling convention. On ARM the effective calling convention is determined 
from the target triple, however using -mfloat-abi=hard on ARM means that calls 
to (and definitions of) C library functions use the arm_aapcs_vfpcc calling 
convention which can result in a mismatch.

Fix this by incorporating -mfloat-abi into the target triple, similar to how 
-mbig-endian and -march/-mcpu are. This only works for EABI targets and not 
Android or iOS, but there the float abi is fixed.

Fixes PR45524.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89573

Files:
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Arch/ARM.cpp
  clang/test/Driver/arm-float-abi-lto.c
  clang/test/Driver/arm-triple.c
  clang/test/Driver/windows-thumbv7em.cpp

Index: clang/test/Driver/windows-thumbv7em.cpp
===================================================================
--- clang/test/Driver/windows-thumbv7em.cpp
+++ clang/test/Driver/windows-thumbv7em.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang -target thumb-none-windows-eabi-coff -mcpu=cortex-m7 -### -c %s 2>&1 \
 // RUN: | FileCheck %s --check-prefix CHECK-V7
-// CHECK-V7-NOT: error: the target architecture 'thumbv7em' is not supported by the target 'thumbv7em-none-windows-eabi'
+// CHECK-V7-NOT: error: the target architecture 'thumbv7em' is not supported by the target 'thumbv7em-none-windows-eabihf'
 
 // RUN: %clang -target thumb-none-windows-eabi-coff -mcpu=cortex-m1 -### -c %s 2>&1 \
 // RUN: | FileCheck %s --check-prefix CHECK-V6
-// CHECK-V6: error: the target architecture 'thumbv6m' is not supported by the target 'thumbv6m-none-windows-eabi'
+// CHECK-V6: error: the target architecture 'thumbv6m' is not supported by the target 'thumbv6m-none-windows-eabihf'
 
Index: clang/test/Driver/arm-triple.c
===================================================================
--- /dev/null
+++ clang/test/Driver/arm-triple.c
@@ -0,0 +1,48 @@
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabi \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DEFAULT
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=armeb-none-eabi -mlittle-endian \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DEFAULT
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabihf -march=armv4t -mfloat-abi=softfp \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DEFAULT
+// CHECK-DEFAULT: armv4t-none-unknown-eabi
+
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=armeb-none-eabi \
+// RUN:   | FileCheck %s --check-prefix=CHECK-EB
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabi -mbig-endian \
+// RUN:   | FileCheck %s --check-prefix=CHECK-EB
+// CHECK-EB: armebv4t-none-unknown-eabi
+
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabihf -march=armv4t \
+// RUN:   | FileCheck %s --check-prefix=CHECK-HF
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabi -mfloat-abi=hard \
+// RUN:   | FileCheck %s --check-prefix=CHECK-HF
+// CHECK-HF: armv4t-none-unknown-eabihf
+
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=armeb-none-eabihf -march=armv4t \
+// RUN:   | FileCheck %s --check-prefix=CHECK-EB-HF
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=armeb-none-eabi -mfloat-abi=hard \
+// RUN:   | FileCheck %s --check-prefix=CHECK-EB-HF
+// RUN: %clang -print-effective-triple -march=armv4t \
+// RUN:   --target=arm-none-eabihf -mbig-endian \
+// RUN:   | FileCheck %s --check-prefix=CHECK-EB-HF
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabi -mbig-endian -mfloat-abi=hard \
+// RUN:   | FileCheck %s --check-prefix=CHECK-EB-HF
+// CHECK-EB-HF: armebv4t-none-unknown-eabihf
+
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabi -march=armv8m.main -mbig-endian -mfloat-abi=hard \
+// RUN:   | FileCheck %s --check-prefix=CHECK-V8M-EB-HF
+// RUN: %clang -print-effective-triple \
+// RUN:   --target=arm-none-eabi -mcpu=cortex-m33 -mbig-endian -mfloat-abi=hard \
+// RUN:   | FileCheck %s --check-prefix=CHECK-V8M-EB-HF
+// CHECK-V8M-EB-HF: thumbebv8m.main-none-unknown-eabihf
Index: clang/test/Driver/arm-float-abi-lto.c
===================================================================
--- /dev/null
+++ clang/test/Driver/arm-float-abi-lto.c
@@ -0,0 +1,63 @@
+// REQUIRES: arm-registered-target
+
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -S -o - -emit-llvm -DCALL_LIB -DDEFINE_LIB | FileCheck %s
+
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=full -c -o %t.call_full.bc -DCALL_LIB
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=full -c -o %t.define_full.bc -DDEFINE_LIB
+// RUN: llvm-lto2 run -o %t.lto_full -save-temps %t.call_full.bc %t.define_full.bc \
+// RUN:  -r %t.call_full.bc,fn,px \
+// RUN:  -r %t.call_full.bc,fwrite,l \
+// RUN:  -r %t.call_full.bc,putchar,l \
+// RUN:  -r %t.call_full.bc,stdout,px \
+// RUN:  -r %t.define_full.bc,fwrite,px \
+// RUN:  -r %t.define_full.bc,putchar,px \
+// RUN:  -r %t.define_full.bc,otherfn,px
+// RUN: llvm-dis %t.lto_full.0.4.opt.bc -o - | FileCheck %s
+
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=thin -c -o %t.call_thin.bc -DCALL_LIB
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=thin -c -o %t.define_thin.bc -DDEFINE_LIB
+// RUN: llvm-lto2 run -o %t.lto_thin -save-temps %t.call_thin.bc %t.define_thin.bc \
+// RUN:  -r %t.call_thin.bc,fn,px \
+// RUN:  -r %t.call_thin.bc,fwrite,l \
+// RUN:  -r %t.call_thin.bc,putchar,l \
+// RUN:  -r %t.call_thin.bc,stdout,px \
+// RUN:  -r %t.define_thin.bc,fwrite,px \
+// RUN:  -r %t.define_thin.bc,putchar,px \
+// RUN:  -r %t.define_thin.bc,otherfn,px
+// RUN: llvm-dis %t.lto_thin.1.4.opt.bc -o - | FileCheck %s
+
+// We expect that the fprintf is optimised to fwrite, and the printf is
+// optimised to putchar. Check that we don't have a mismatch in calling
+// conventions causing the call to be replaced by a trap.
+// CHECK-LABEL: define{{.*}}void @fn()
+// CHECK-NOT: call void @llvm.trap()
+
+typedef struct FILE FILE;
+typedef unsigned int size_t;
+extern FILE *stdout;
+extern int fprintf(FILE *, const char *, ...);
+extern int printf(const char *, ...);
+extern void otherfn(const void *);
+
+#ifdef CALL_LIB
+
+void fn() {
+  fprintf(stdout, "hello world");
+  printf("a");
+}
+
+#endif
+
+#ifdef DEFINE_LIB
+
+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
+  otherfn(ptr);
+  return 0;
+}
+
+int putchar(int c) {
+  otherfn(&c);
+  return 0;
+}
+
+#endif
Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -134,6 +134,7 @@
   // The backend is hardwired to assume AAPCS for M-class processors, ensure
   // the frontend matches that.
   return T.getEnvironment() == llvm::Triple::EABI ||
+         T.getEnvironment() == llvm::Triple::EABIHF ||
          T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
 }
 
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -787,6 +787,26 @@
     }
     Triple.setArchName(ArchName + Suffix.str());
 
+    bool isHardFloat =
+        (arm::getARMFloatABI(getDriver(), Triple, Args) == arm::FloatABI::Hard);
+    switch (Triple.getEnvironment()) {
+    case Triple::GNUEABI:
+    case Triple::GNUEABIHF:
+      Triple.setEnvironment(isHardFloat ? Triple::GNUEABIHF : Triple::GNUEABI);
+      break;
+    case Triple::EABI:
+    case Triple::EABIHF:
+      Triple.setEnvironment(isHardFloat ? Triple::EABIHF : Triple::EABI);
+      break;
+    case Triple::MuslEABI:
+    case Triple::MuslEABIHF:
+      Triple.setEnvironment(isHardFloat ? Triple::MuslEABIHF
+                                        : Triple::MuslEABI);
+      break;
+    default:
+      break;
+    }
+
     return Triple.getTriple();
   }
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to