diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 61889861c9c803..b96fab978a3fcb 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -143,6 +143,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, IntMaxType = SignedLong; } + AddrSpaceMap = &ARM64AddrSpaceMap; + // All AArch64 implementations support ARMv8 FP, which makes half a legal type. HasLegalHalfType = true; HalfArgsAndReturns = true; @@ -1533,11 +1535,16 @@ AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, void AArch64leTargetInfo::setDataLayout() { if (getTriple().isOSBinFormatMachO()) { if(getTriple().isArch32Bit()) - resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32", "_"); + resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-" + "i128:128-n32:64-S128-Fn32", + "_"); else - resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128-Fn32", "_"); + resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-" + "n32:64-S128-Fn32", + "_"); } else - resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"); + resetDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-" + "i64:64-i128:128-n32:64-S128-Fn32"); } void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -1560,7 +1567,8 @@ void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, void AArch64beTargetInfo::setDataLayout() { assert(!getTriple().isOSBinFormatMachO()); - resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"); + resetDataLayout("E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-" + "i64:64-i128:128-n32:64-S128-Fn32"); } WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, @@ -1583,8 +1591,10 @@ WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, void WindowsARM64TargetInfo::setDataLayout() { resetDataLayout(Triple.isOSBinFormatMachO() - ? "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" - : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32", + ? "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:" + "128-n32:64-S128-Fn32" + : "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-" + "i64:64-i128:128-n32:64-S128-Fn32", Triple.isOSBinFormatMachO() ? "_" : ""); } diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 1226ce4d4355c2..16a02e102e045d 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -21,6 +21,34 @@ namespace clang { namespace targets { +enum AArch64AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 }; + +static const unsigned ARM64AddrSpaceMap[] = { + 0, // Default + 0, // opencl_global + 0, // opencl_local + 0, // opencl_constant + 0, // opencl_private + 0, // opencl_generic + 0, // opencl_global_device + 0, // opencl_global_host + 0, // cuda_device + 0, // cuda_constant + 0, // cuda_shared + 0, // sycl_global + 0, // sycl_global_device + 0, // sycl_global_host + 0, // sycl_local + 0, // sycl_private + static_cast(AArch64AddrSpace::ptr32_sptr), + static_cast(AArch64AddrSpace::ptr32_uptr), + static_cast(AArch64AddrSpace::ptr64), + 0, // hlsl_groupshared + // Wasm address space values for this target are dummy values, + // as it is only enabled for Wasm targets. + 20, // wasm_funcref +}; + class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { virtual void setDataLayout() = 0; static const TargetInfo::GCCRegAlias GCCRegAliases[]; @@ -207,6 +235,18 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const override; + + uint64_t getPointerWidthV(LangAS AddrSpace) const override { + if (AddrSpace == LangAS::ptr32_sptr || AddrSpace == LangAS::ptr32_uptr) + return 32; + if (AddrSpace == LangAS::ptr64) + return 64; + return PointerWidth; + } + + uint64_t getPointerAlignV(LangAS AddrSpace) const override { + return getPointerWidthV(AddrSpace); + } }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { diff --git a/clang/test/CodeGen/aarch64-type-sizes.c b/clang/test/CodeGen/aarch64-type-sizes.c index a40423c1f8deb2..f6129b3943d2b9 100644 --- a/clang/test/CodeGen/aarch64-type-sizes.c +++ b/clang/test/CodeGen/aarch64-type-sizes.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s // char by definition has size 1 -// CHECK: target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" +// CHECK: target datalayout = "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" int check_short(void) { return sizeof(short); diff --git a/clang/test/CodeGen/coff-aarch64-type-sizes.c b/clang/test/CodeGen/coff-aarch64-type-sizes.c index 9cb0ddbaef3f65..2e5b94c14e6acf 100644 --- a/clang/test/CodeGen/coff-aarch64-type-sizes.c +++ b/clang/test/CodeGen/coff-aarch64-type-sizes.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple aarch64-windows -emit-llvm -w -o - %s | FileCheck %s -// CHECK: target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" +// CHECK: target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" // CHECK: target triple = "aarch64-unknown-windows-msvc" int check_short(void) { diff --git a/clang/test/CodeGen/ms-mixed-ptr-sizes.c b/clang/test/CodeGen/ms-mixed-ptr-sizes.c index 0bc1925b13dbc6..f99c6196557e18 100644 --- a/clang/test/CodeGen/ms-mixed-ptr-sizes.c +++ b/clang/test/CodeGen/ms-mixed-ptr-sizes.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -emit-llvm -O2 < %s | FileCheck %s --check-prefixes=X64,ALL // RUN: %clang_cc1 -triple i386-pc-win32 -fms-extensions -emit-llvm -O2 < %s | FileCheck %s --check-prefixes=X86,ALL +// RUN: %clang_cc1 -triple aarch64-windows-msvc -fms-extensions -emit-llvm -O2 < %s | FileCheck %s --check-prefixes=AARCH64,ALL struct Foo { int * __ptr32 p32; @@ -9,32 +10,40 @@ void use_foo(struct Foo *f); void test_sign_ext(struct Foo *f, int * __ptr32 __sptr i) { // X64-LABEL: define dso_local void @test_sign_ext({{.*}}ptr addrspace(270) noundef %i) // X86-LABEL: define dso_local void @test_sign_ext(ptr noundef %f, ptr noundef %i) +// AARCH64-LABEL: define dso_local void @test_sign_ext({{.*}}ptr addrspace(270) noundef %i) local_unnamed_addr #0 // X64: %{{.+}} = addrspacecast ptr addrspace(270) %i to ptr // X86: %{{.+}} = addrspacecast ptr %i to ptr addrspace(272) +// AARCH64: %{{.+}} = addrspacecast ptr addrspace(270) %i to ptr f->p64 = i; use_foo(f); } void test_zero_ext(struct Foo *f, int * __ptr32 __uptr i) { // X64-LABEL: define dso_local void @test_zero_ext({{.*}}ptr addrspace(271) noundef %i) // X86-LABEL: define dso_local void @test_zero_ext({{.*}}ptr addrspace(271) noundef %i) +// AARCH64-LABEL: define dso_local void @test_zero_ext({{.*}}ptr addrspace(271) noundef %i) local_unnamed_addr #0 // X64: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr // X86: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr addrspace(272) +// AARCH64: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr f->p64 = i; use_foo(f); } void test_trunc(struct Foo *f, int * __ptr64 i) { // X64-LABEL: define dso_local void @test_trunc(ptr noundef %f, ptr noundef %i) // X86-LABEL: define dso_local void @test_trunc({{.*}}ptr addrspace(272) noundef %i) +// AARCH64-LABEL: define dso_local void @test_trunc(ptr noundef %f, ptr noundef %i) local_unnamed_addr #0 // X64: %{{.+}} = addrspacecast ptr %i to ptr addrspace(270) // X86: %{{.+}} = addrspacecast ptr addrspace(272) %i to ptr +// AARCH64: %{{.+}} = addrspacecast ptr %i to ptr addrspace(270) f->p32 = i; use_foo(f); } void test_noop(struct Foo *f, int * __ptr32 i) { // X64-LABEL: define dso_local void @test_noop({{.*}}ptr addrspace(270) noundef %i) // X86-LABEL: define dso_local void @test_noop({{.*}}ptr noundef %i) +// AARCH64-LABEL: define dso_local void @test_noop({{.*}}ptr addrspace(270) noundef %i) local_unnamed_addr #0 // X64-NOT: addrspacecast // X86-NOT: addrspacecast +// AARCH64-NOT: addrspacecast f->p32 = i; use_foo(f); } @@ -42,8 +51,10 @@ void test_noop(struct Foo *f, int * __ptr32 i) { void test_other(struct Foo *f, __attribute__((address_space(10))) int *i) { // X64-LABEL: define dso_local void @test_other({{.*}}ptr addrspace(10) noundef %i) // X86-LABEL: define dso_local void @test_other({{.*}}ptr addrspace(10) noundef %i) +// AARCH64-LABEL: define dso_local void @test_other({{.*}}ptr addrspace(10) noundef %i) local_unnamed_addr #0 // X64: %{{.+}} = addrspacecast ptr addrspace(10) %i to ptr addrspace(270) // X86: %{{.+}} = addrspacecast ptr addrspace(10) %i to ptr +// AARCH64: %{{.+}} = addrspacecast ptr addrspace(10) %i to ptr addrspace(270) f->p32 = (int * __ptr32)i; use_foo(f); } @@ -54,6 +65,8 @@ int test_compare1(int *__ptr32 __uptr i, int *__ptr64 j) { // X64: %cmp = icmp eq ptr addrspace(271) %i, %{{.+}} // X86: %{{.+}} = addrspacecast ptr addrspace(272) %j to ptr addrspace(271) // X86: %cmp = icmp eq ptr addrspace(271) %i, %{{.+}} + // AARCH64: %{{.+}} = addrspacecast ptr %j to ptr addrspace(271) + // AARCH64: %cmp = icmp eq ptr addrspace(271) %i, %{{.+}} return (i == j); } @@ -63,6 +76,8 @@ int test_compare2(int *__ptr32 __sptr i, int *__ptr64 j) { // X64: %cmp = icmp eq ptr addrspace(270) %i, %{{.+}} // X86: %{{.+}} = addrspacecast ptr addrspace(272) %j to ptr // X86: %cmp = icmp eq ptr %i, %{{.+}} + // AARCH64: %{{.+}} = addrspacecast ptr %j to ptr addrspace(270) + // AARCH64: %cmp = icmp eq ptr addrspace(270) %i, %{{.+}} return (i == j); } @@ -72,6 +87,8 @@ int test_compare3(int *__ptr32 __uptr i, int *__ptr64 j) { // X64: %cmp = icmp eq ptr %j, %{{.+}} // X86: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr addrspace(272) // X86: %cmp = icmp eq ptr addrspace(272) %j, %{{.+}} + // AARCH64: %{{.+}} = addrspacecast ptr addrspace(271) %i to ptr + // AARCH64: %cmp = icmp eq ptr %j, %{{.+}} return (j == i); } @@ -81,5 +98,7 @@ int test_compare4(int *__ptr32 __sptr i, int *__ptr64 j) { // X64: %cmp = icmp eq ptr %j, %{{.+}} // X86: %{{.+}} = addrspacecast ptr %i to ptr addrspace(272) // X86: %cmp = icmp eq ptr addrspace(272) %j, %{{.+}} + // AARCH64: %{{.+}} = addrspacecast ptr addrspace(270) %i to ptr + // AARCH64: %cmp = icmp eq ptr %j, %{{.+}} return (j == i); } diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index 8548aa00cfe877..26a1bf2a1a5740 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -185,15 +185,15 @@ // RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=AARCH64 -// AARCH64: target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" +// AARCH64: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" // RUN: %clang_cc1 -triple arm64_32-apple-ios7.0 -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=AARCH64-ILP32 -// AARCH64-ILP32: target datalayout = "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32" +// AARCH64-ILP32: target datalayout = "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" // RUN: %clang_cc1 -triple arm64-pc-win32-macho -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=AARCH64-WIN32-MACHO -// AARCH64-WIN32-MACHO: target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" +// AARCH64-WIN32-MACHO: target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" // RUN: %clang_cc1 -triple thumb-unknown-gnueabi -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=THUMB diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 215bfc8c6cfe3e..62931f4d90f2ef 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -5565,11 +5565,24 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { return Res; } + auto AddPtr32Ptr64AddrSpaces = [&DL, &Res]() { + // If the datalayout matches the expected format, add pointer size address + // spaces to the datalayout. + StringRef AddrSpaces{"-p270:32:32-p271:32:32-p272:64:64"}; + if (!DL.contains(AddrSpaces)) { + SmallVector Groups; + Regex R("^([Ee]-m:[a-z](-p:32:32)?)(-.*)$"); + if (R.match(Res, &Groups)) + Res = (Groups[1] + AddrSpaces + Groups[3]).str(); + } + }; + // AArch64 data layout upgrades. if (T.isAArch64()) { // Add "-Fn32" if (!DL.empty() && !DL.contains("-Fn32")) Res.append("-Fn32"); + AddPtr32Ptr64AddrSpaces(); return Res; } @@ -5588,15 +5601,7 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { if (!T.isX86()) return Res; - // If the datalayout matches the expected format, add pointer size address - // spaces to the datalayout. - std::string AddrSpaces = "-p270:32:32-p271:32:32-p272:64:64"; - if (StringRef Ref = Res; !Ref.contains(AddrSpaces)) { - SmallVector Groups; - Regex R("(e-m:[a-z](-p:32:32)?)(-[if]64:.*$)"); - if (R.match(Res, &Groups)) - Res = (Groups[1] + AddrSpaces + Groups[3]).str(); - } + AddPtr32Ptr64AddrSpaces(); // i128 values need to be 16-byte-aligned. LLVM already called into libgcc // for i128 operations prior to this being reflected in the data layout, and diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 7b0ae23358673e..21b86f5fe5d912 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -290,15 +290,19 @@ static std::string computeDataLayout(const Triple &TT, bool LittleEndian) { if (TT.isOSBinFormatMachO()) { if (TT.getArch() == Triple::aarch64_32) - return "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32"; - return "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"; + return "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-" + "n32:64-S128-Fn32"; + return "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-" + "Fn32"; } if (TT.isOSBinFormatCOFF()) - return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"; + return "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:" + "128-n32:64-S128-Fn32"; std::string Endian = LittleEndian ? "e" : "E"; std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : ""; return Endian + "-m:e" + Ptr32 + - "-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"; + "-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-" + "n32:64-S128-Fn32"; } static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) { diff --git a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp index 1cd4a47c75739b..e7fb4e0718648b 100644 --- a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp +++ b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp @@ -23,6 +23,8 @@ TEST(DataLayoutUpgradeTest, ValidDataLayoutUpgrade) { "e-m:o-i64:64-f80:128-n8:16:32:64-S128", "x86_64-apple-macosx"); std::string DL4 = UpgradeDataLayoutString("e-m:o-i64:64-i128:128-n32:64-S128", "aarch64--"); + std::string DL5 = UpgradeDataLayoutString( + "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "aarch64--"); EXPECT_EQ(DL1, "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128" "-f80:128-n8:16:32:64-S128"); @@ -31,7 +33,10 @@ TEST(DataLayoutUpgradeTest, ValidDataLayoutUpgrade) { "-f80:128-n8:16:32-S32"); EXPECT_EQ(DL3, "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:" "128-n8:16:32:64-S128"); - EXPECT_EQ(DL4, "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"); + EXPECT_EQ(DL4, "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:" + "64-S128-Fn32"); + EXPECT_EQ(DL5, "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:" + "64-i128:128-n32:64-S128-Fn32"); // Check that AMDGPU targets add -G1 if it's not present. EXPECT_EQ(UpgradeDataLayoutString("e-p:32:32", "r600"), "e-p:32:32-G1"); @@ -94,14 +99,16 @@ TEST(DataLayoutUpgradeTest, NoDataLayoutUpgrade) { std::string DL2 = UpgradeDataLayoutString("e-m:e-i64:64-n32:64", "powerpc64le-unknown-linux-gnu"); std::string DL3 = UpgradeDataLayoutString( - "e-m:o-i64:64-i128:128-n32:64-S128-Fn32", "aarch64--"); + "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32", + "aarch64--"); EXPECT_EQ( DL1, "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128" "-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64" "-f80:128:128-n8:16:32:64-S128"); EXPECT_EQ(DL2, "e-m:e-i64:64-n32:64"); - EXPECT_EQ(DL3, "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"); + EXPECT_EQ(DL3, "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:" + "64-S128-Fn32"); // Check that AMDGPU targets don't add -G1 if there is already a -G flag. EXPECT_EQ(UpgradeDataLayoutString("e-p:32:32-G2", "r600"), "e-p:32:32-G2");