[clang] [llvm] [SPARC] Align i128 to 16 bytes in SPARC datalayouts (PR #106951)

via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 21 17:23:18 PDT 2024


https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/106951

>From 3eb96009b0b483553c2255893d26e59b8c4f6574 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Mon, 2 Sep 2024 12:01:04 +0700
Subject: [PATCH 1/3] [SPARC] Align i128 to 16 bytes in SPARC datalayouts

Align i128s to 16 bytes, following the example at https://reviews.llvm.org/D86310.

clang already does this, but do it in backend code too for the benefit of other
frontends (see e.g https://github.com/llvm/llvm-project/issues/102783).
---
 clang/lib/Basic/Targets/Sparc.h              |  6 ++---
 clang/test/CodeGen/target-data.c             |  4 +--
 llvm/lib/Target/Sparc/SparcTargetMachine.cpp |  4 +++
 llvm/test/CodeGen/SPARC/data-align.ll        | 27 ++++++++++++++++++++
 4 files changed, 36 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPARC/data-align.ll

diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h
index 3357bee33e1ac7..ee0d3e2b4329eb 100644
--- a/clang/lib/Basic/Targets/Sparc.h
+++ b/clang/lib/Basic/Targets/Sparc.h
@@ -151,7 +151,7 @@ class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
 public:
   SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : SparcTargetInfo(Triple, Opts) {
-    resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64");
+    resetDataLayout("E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64");
     // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.
     switch (getTriple().getOS()) {
     default:
@@ -188,7 +188,7 @@ class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
 public:
   SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : SparcV8TargetInfo(Triple, Opts) {
-    resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
+    resetDataLayout("e-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64");
   }
 };
 
@@ -198,7 +198,7 @@ class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
   SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : SparcTargetInfo(Triple, Opts) {
     // FIXME: Support Sparc quad-precision long double?
-    resetDataLayout("E-m:e-i64:64-n32:64-S128");
+    resetDataLayout("E-m:e-i64:64-i128:128-n32:64-S128");
     // This is an LP64 platform.
     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
 
diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c
index 41cbd5a0219d5e..8548aa00cfe877 100644
--- a/clang/test/CodeGen/target-data.c
+++ b/clang/test/CodeGen/target-data.c
@@ -28,11 +28,11 @@
 
 // RUN: %clang_cc1 -triple sparc-sun-solaris -emit-llvm -o - %s | \
 // RUN:     FileCheck %s --check-prefix=SPARC-V8
-// SPARC-V8: target datalayout = "E-m:e-p:32:32-i64:64-f128:64-n32-S64"
+// SPARC-V8: target datalayout = "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64"
 
 // RUN: %clang_cc1 -triple sparcv9-sun-solaris -emit-llvm -o - %s | \
 // RUN: FileCheck %s --check-prefix=SPARC-V9
-// SPARC-V9: target datalayout = "E-m:e-i64:64-n32:64-S128"
+// SPARC-V9: target datalayout = "E-m:e-i64:64-i128:128-n32:64-S128"
 
 // RUN: %clang_cc1 -triple mipsel-linux-gnu -o - -emit-llvm %s |     \
 // RUN: FileCheck %s -check-prefix=MIPS-32EL
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index fec2d3a35ae6d2..50a96368bbdca9 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -48,6 +48,10 @@ static std::string computeDataLayout(const Triple &T, bool is64Bit) {
   // Alignments for 64 bit integers.
   Ret += "-i64:64";
 
+  // Alignments for 128 bit integers.
+  // This is not specified in the ABI document but is the de facto standard.
+  Ret += "-i128:128";
+
   // On SparcV9 128 floats are aligned to 128 bits, on others only to 64.
   // On SparcV9 registers can hold 64 or 32 bits, on others only 32.
   if (is64Bit)
diff --git a/llvm/test/CodeGen/SPARC/data-align.ll b/llvm/test/CodeGen/SPARC/data-align.ll
new file mode 100644
index 00000000000000..d4a39524da44f6
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/data-align.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -march=sparc | FileCheck %s
+; RUN: llc < %s -march=sparcel | FileCheck %s
+; RUN: llc < %s -march=sparcv9 | FileCheck %s
+
+; CHECK:      .Li8:
+; CHECK-DAG: .size .Li8, 1
+ at i8 = private constant i8 42
+
+; CHECK:      .p2align 1
+; CHECK-NEXT: .Li16:
+; CHECK-DAG:  .size .Li16, 2
+ at i16 = private constant i16 42
+
+; CHECK:      .p2align 2
+; CHECK-NEXT: .Li32:
+; CHECK-DAG:  .size .Li32, 4
+ at i32 = private constant i32 42
+
+; CHECK:      .p2align 3
+; CHECK-NEXT: .Li64:
+; CHECK-DAG:  .size .Li64, 8
+ at i64 = private constant i64 42
+
+; CHECK:      .p2align 4
+; CHECK-NEXT: .Li128:
+; CHECK-DAG:  .size .Li128, 16
+ at i128 = private constant i128 42

>From 4b40325439810ff7786be100577207693b372f7b Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Wed, 4 Sep 2024 20:50:57 +0700
Subject: [PATCH 2/3] Handle new layout in UpgradeDataLayoutString

---
 llvm/lib/IR/AutoUpgrade.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 50fc2e728fcc01..f4145e9be35a64 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5461,6 +5461,13 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
     return Res;
   }
 
+  if (T.isSPARC()) {
+    // Add "-i128:128"
+    if (!DL.empty() && !DL.contains("-i128:128"))
+      Res.append("-i128:128");
+    return Res;
+  }
+
   if (!T.isX86())
     return Res;
 

>From b3219590664c3c629a7ff938cbff584af384498e Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Sun, 22 Sep 2024 07:22:10 +0700
Subject: [PATCH 3/3] Change addition method in UpgradeDataLayoutString & add
 tests

---
 llvm/lib/IR/AutoUpgrade.cpp                      | 9 +++++++--
 llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp | 7 +++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index f4145e9be35a64..f4e3ef728a74ca 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5463,8 +5463,13 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
 
   if (T.isSPARC()) {
     // Add "-i128:128"
-    if (!DL.empty() && !DL.contains("-i128:128"))
-      Res.append("-i128:128");
+    std::string I128 = "-i128:128";
+    if (StringRef Ref = Res; !Ref.contains(I128)) {
+      SmallVector<StringRef, 4> Groups;
+      Regex R("^([Ee](-[mpi][^-]*)*)((-[^mpi][^-]*)*)$");
+      if (R.match(Res, &Groups))
+        Res = (Groups[1] + I128 + Groups[3]).str();
+    }
     return Res;
   }
 
diff --git a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
index ca50187e5e5ee0..1cd4a47c75739b 100644
--- a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
+++ b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
@@ -68,6 +68,13 @@ TEST(DataLayoutUpgradeTest, ValidDataLayoutUpgrade) {
                                     "loongarch64"),
             "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
 
+  // Check that SPARC targets add -i128:128.
+  EXPECT_EQ(
+      UpgradeDataLayoutString("E-m:e-p:32:32-i64:64-f128:64-n32-S64", "sparc"),
+      "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64");
+  EXPECT_EQ(UpgradeDataLayoutString("E-m:e-i64:64-n32:64-S128", "sparcv9"),
+            "E-m:e-i64:64-i128:128-n32:64-S128");
+
   // Check that SPIR && SPIRV targets add -G1 if it's not present.
   EXPECT_EQ(UpgradeDataLayoutString("e-p:32:32", "spir"), "e-p:32:32-G1");
   EXPECT_EQ(UpgradeDataLayoutString("e-p:32:32", "spir64"), "e-p:32:32-G1");



More information about the cfe-commits mailing list