mirror of
https://github.com/intel/llvm.git
synced 2026-01-29 04:16:38 +08:00
[SPARC] Align i128 to 16 bytes in SPARC datalayouts (#106951)
Align i128s to 16 bytes, following the example at https://reviews.llvm.org/D86310. clang already does this implicitly, but do it in backend code too for the benefit of other frontends (see e.g https://github.com/llvm/llvm-project/issues/102783 & https://github.com/rust-lang/rust/issues/128950).
This commit is contained in:
@@ -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 @@ public:
|
||||
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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5517,6 +5517,18 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
|
||||
return Res;
|
||||
}
|
||||
|
||||
if (T.isSPARC()) {
|
||||
// Add "-i128:128"
|
||||
std::string I64 = "-i64:64";
|
||||
std::string I128 = "-i128:128";
|
||||
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);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
if (!T.isX86())
|
||||
return Res;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
27
llvm/test/CodeGen/SPARC/data-align.ll
Normal file
27
llvm/test/CodeGen/SPARC/data-align.ll
Normal file
@@ -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
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user