From 3eb96009b0b483553c2255893d26e59b8c4f6574 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Mon, 2 Sep 2024 12:01:04 +0700 Subject: [PATCH 1/5] [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 +@i8 = private constant i8 42 + +; CHECK: .p2align 1 +; CHECK-NEXT: .Li16: +; CHECK-DAG: .size .Li16, 2 +@i16 = private constant i16 42 + +; CHECK: .p2align 2 +; CHECK-NEXT: .Li32: +; CHECK-DAG: .size .Li32, 4 +@i32 = private constant i32 42 + +; CHECK: .p2align 3 +; CHECK-NEXT: .Li64: +; CHECK-DAG: .size .Li64, 8 +@i64 = private constant i64 42 + +; CHECK: .p2align 4 +; CHECK-NEXT: .Li128: +; CHECK-DAG: .size .Li128, 16 +@i128 = private constant i128 42 From 4b40325439810ff7786be100577207693b372f7b Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 4 Sep 2024 20:50:57 +0700 Subject: [PATCH 2/5] 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 Date: Sun, 22 Sep 2024 07:22:10 +0700 Subject: [PATCH 3/5] 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 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"); From 8256a53224e03bfc8ba0440d4c53c4d3e21acccb Mon Sep 17 00:00:00 2001 From: Koakuma Date: Mon, 23 Sep 2024 18:47:25 +0700 Subject: [PATCH 4/5] Take out regex from UpgradeDataLayoutString matcher --- llvm/lib/IR/AutoUpgrade.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index f4e3ef728a74ca..0ae078fd65b245 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -5463,12 +5463,12 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { if (T.isSPARC()) { // Add "-i128:128" + std::string I64 = "-i64:64"; std::string I128 = "-i128:128"; if (StringRef Ref = Res; !Ref.contains(I128)) { - SmallVector Groups; - Regex R("^([Ee](-[mpi][^-]*)*)((-[^mpi][^-]*)*)$"); - if (R.match(Res, &Groups)) - Res = (Groups[1] + I128 + Groups[3]).str(); + size_t Pos = Res.find(I64); + assert(Pos != size_t(-1) && "no i64 data layout found!"); + Res.insert(Pos + I64.size(), I128); } return Res; } From d965148c6f948db35d5e75186f6b9460c8763c18 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Sun, 29 Sep 2024 21:49:06 +0700 Subject: [PATCH 5/5] Apply suggestions --- llvm/lib/IR/AutoUpgrade.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 0ae078fd65b245..a1314f4fce14de 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -5465,7 +5465,7 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { // Add "-i128:128" std::string I64 = "-i64:64"; std::string I128 = "-i128:128"; - if (StringRef Ref = Res; !Ref.contains(I128)) { + if (!StringRef(Res).contains(I128)) { size_t Pos = Res.find(I64); assert(Pos != size_t(-1) && "no i64 data layout found!"); Res.insert(Pos + I64.size(), I128);