fhahn created this revision.
Herald added subscribers: javed.absar, mehdi_amini, aemerson.

The thumb-mode target feature is used to force Thumb or ARM code
generation on a per-function basis. Explicitly adding +thumb-mode to
functions for thumbxx triples enables mixed ARM/Thumb code generation in
places where compilation units with thumbxx and armxx triples are merged
together (e.g. the IR linker or LTO).

      

For armxx triples, -thumb-mode is added.


https://reviews.llvm.org/D33448

Files:
  lib/CodeGen/TargetInfo.cpp
  test/CodeGen/arm-long-calls.c
  test/CodeGen/arm-no-movt.c
  test/CodeGen/arm-target-features.c
  test/CodeGen/arm-thumb-mode-target-feature.c

Index: test/CodeGen/arm-thumb-mode-target-feature.c
===================================================================
--- /dev/null
+++ test/CodeGen/arm-thumb-mode-target-feature.c
@@ -0,0 +1,24 @@
+// REQUIRES: arm-registered-target
+
+// RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -emit-llvm -o - %s | FileCheck --check-prefix THUMB %s
+// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -emit-llvm -o - %s | FileCheck --check-prefix ARM %s
+
+void t1() {}
+
+ __attribute__((target("no-thumb-mode")))
+void t2() {}
+
+ __attribute__((target("thumb-mode")))
+void t3() {}
+
+// THUMB: void @t1() [[ThumbAttr:#[0-7]]]
+// THUMB: void @t2() [[NoThumbAttr:#[0-7]]]
+// THUMB: void @t3() [[ThumbAttr:#[0-7]]]
+// THUMB: attributes [[ThumbAttr]] = { {{.*}} "target-features"="+thumb-mode"
+// THUMB: attributes [[NoThumbAttr]] = { {{.*}} "target-features"="-thumb-mode"
+
+// ARM: void @t1() [[NoThumbAtr:#[0-7]]]
+// ARM: void @t2() [[NoThumbAttr:#[0-7]]]
+// ARM: void @t3() [[ThumbAttr:#[0-7]]]
+// ARM: attributes [[NoThumbAttr]] = { {{.*}} "target-features"="-thumb-mode"
+// ARM: attributes [[ThumbAttr]] = { {{.*}} "target-features"="+thumb-mode"
Index: test/CodeGen/arm-target-features.c
===================================================================
--- test/CodeGen/arm-target-features.c
+++ test/CodeGen/arm-target-features.c
@@ -1,65 +1,67 @@
 // REQUIRES: arm-registered-target
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu cortex-a8 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3
-// CHECK-VFP3: "target-features"="+dsp,+neon,+vfp3"
+// CHECK-VFP3: "target-features"="+dsp,+neon,+vfp3,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-a9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-FP16
-// CHECK-VFP3-FP16: "target-features"="+dsp,+fp16,+neon,+vfp3"
+// CHECK-VFP3-FP16: "target-features"="+dsp,+fp16,+neon,+vfp3,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu cortex-a5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4
-// CHECK-VFP4: "target-features"="+dsp,+neon,+vfp4"
+// CHECK-VFP4: "target-features"="+dsp,+neon,+vfp4,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu cortex-a7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-a12 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV
-// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a15 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV
-// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a17 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV
 // RUN: %clang_cc1 -triple thumbv7s-linux-gnueabi -target-cpu swift -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu krait -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV
-// CHECK-VFP4-DIV: "target-features"="+dsp,+hwdiv,+hwdiv-arm,+neon,+vfp4"
+// CHECK-VFP4-DIV: "target-features"="+dsp,+hwdiv,+hwdiv-arm,+neon,+vfp4,+thumb-mode"
 
+// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a15 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV-ARM
+// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a17 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV-ARM
+// CHECK-VFP4-DIV-ARM: "target-features"="+dsp,+hwdiv,+hwdiv-arm,+neon,+vfp4,-thumb-mode"
 
 // RUN: %clang_cc1 -triple thumbv7s-apple-ios7.0 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a32 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a35 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
-// RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a72 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a73 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
-// CHECK-BASIC-V8: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon"
+// CHECK-BASIC-V8: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,+thumb-mode"
 
+// RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8-ARM
+// CHECK-BASIC-V8-ARM: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,-thumb-mode"
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-DIV
-// CHECK-VFP3-D16-DIV: "target-features"="+d16,+dsp,+hwdiv,+hwdiv-arm,+vfp3"
+// CHECK-VFP3-D16-DIV: "target-features"="+d16,+dsp,+hwdiv,+hwdiv-arm,+vfp3,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple armv7-linux-gnueabi -target-cpu cortex-r4f -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-THUMB-DIV
-// CHECK-VFP3-D16-THUMB-DIV: "target-features"="+d16,+dsp,+hwdiv,+vfp3"
+// CHECK-VFP3-D16-THUMB-DIV: "target-features"="+d16,+dsp,+hwdiv,+vfp3,-thumb-mode"
 
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-FP16-DIV
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r8 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-FP16-DIV
-// CHECK-VFP3-D16-FP16-DIV: "target-features"="+d16,+dsp,+fp16,+hwdiv,+hwdiv-arm,+vfp3"
+// CHECK-VFP3-D16-FP16-DIV: "target-features"="+d16,+dsp,+fp16,+hwdiv,+hwdiv-arm,+vfp3,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-D16-SP-THUMB-DIV
-// CHECK-VFP4-D16-SP-THUMB-DIV: "target-features"="+d16,+dsp,+fp-only-sp,+hwdiv,+vfp4"
+// CHECK-VFP4-D16-SP-THUMB-DIV: "target-features"="+d16,+dsp,+fp-only-sp,+hwdiv,+vfp4,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP5-D16-THUMB-DIV
-// CHECK-VFP5-D16-THUMB-DIV: "target-features"="+d16,+dsp,+fp-armv8,+hwdiv"
+// CHECK-VFP5-D16-THUMB-DIV: "target-features"="+d16,+dsp,+fp-armv8,+hwdiv,+thumb-mode"
 
 
 // RUN: %clang_cc1 -triple armv7-linux-gnueabi -target-cpu cortex-r4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-DIV
-// CHECK-THUMB-DIV: "target-features"="+dsp,+hwdiv"
+// CHECK-THUMB-DIV: "target-features"="+dsp,+hwdiv,-thumb-mode"
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-DIV-M3
-// CHECK-THUMB-DIV-M3: "target-features"="+hwdiv"
+// CHECK-THUMB-DIV-M3: "target-features"="+hwdiv,+thumb-mode"
 
 
 void foo() {}
Index: test/CodeGen/arm-no-movt.c
===================================================================
--- test/CodeGen/arm-no-movt.c
+++ test/CodeGen/arm-no-movt.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple thumbv7-apple-ios5  -target-feature +no-movt -emit-llvm -o - %s | FileCheck -check-prefix=NO-MOVT %s
 // RUN: %clang_cc1 -triple thumbv7-apple-ios5 -emit-llvm -o - %s | FileCheck -check-prefix=MOVT %s
 
-// NO-MOVT: attributes #0 = { {{.*}} "target-features"="+no-movt"
-// MOVT-NOT: attributes #0 = { {{.*}} "target-features"="+no-movt"
+// NO-MOVT: attributes #0 = { {{.*}} "target-features"="+no-movt,+thumb-mode"
+// MOVT-NOT: attributes #0 = { {{.*}} "target-features"="+no-movt,+thumb-mode"
 
 int foo1(int a) { return a; }
Index: test/CodeGen/arm-long-calls.c
===================================================================
--- test/CodeGen/arm-long-calls.c
+++ test/CodeGen/arm-long-calls.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple thumbv7-apple-ios5  -target-feature +long-calls -emit-llvm -o - %s | FileCheck -check-prefix=LONGCALL %s
 // RUN: %clang_cc1 -triple thumbv7-apple-ios5 -emit-llvm -o - %s | FileCheck -check-prefix=NOLONGCALL %s
 
-// LONGCALL: attributes #0 = { {{.*}} "target-features"="+long-calls"
-// NOLONGCALL-NOT: attributes #0 = { {{.*}} "target-features"="+long-calls"
+// LONGCALL: attributes #0 = { {{.*}} "target-features"="+long-calls,+thumb-mode"
+// NOLONGCALL-NOT: attributes #0 = { {{.*}} "target-features"="+long-calls,+thumb-mode"
 
 int foo1(int a) { return a; }
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -5422,6 +5422,28 @@
     if (!FD)
       return;
 
+    llvm::Function *Fn = cast<llvm::Function>(GV);
+
+    if (CGM.getTriple().getArch() == llvm::Triple::thumb ||
+        CGM.getTriple().getArch() == llvm::Triple::arm) {
+      llvm::Attribute targetFeatures;
+      if (Fn->hasFnAttribute("target-features")) {
+        targetFeatures = Fn->getFnAttribute("target-features");
+      }
+
+      std::string newFeatures = targetFeatures.getValueAsString();
+      // Only add thumb-mode if it is not part of the existing target-features.
+      if (newFeatures.find("thumb-mode") == std::string::npos) {
+        if (newFeatures.size() > 0)
+          newFeatures += ",";
+        if (CGM.getTriple().getArch() == llvm::Triple::arm)
+          newFeatures += "-thumb-mode";
+        else
+          newFeatures += "+thumb-mode";
+        Fn->addFnAttr("target-features", newFeatures);
+      }
+    }
+
     const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
     if (!Attr)
       return;
@@ -5436,8 +5458,6 @@
     case ARMInterruptAttr::UNDEF:   Kind = "UNDEF"; break;
     }
 
-    llvm::Function *Fn = cast<llvm::Function>(GV);
-
     Fn->addFnAttr("interrupt", Kind);
 
     ARMABIInfo::ABIKind ABI = cast<ARMABIInfo>(getABIInfo()).getABIKind();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to