-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][aarch64] Add support for the MSVC qualifiers __ptr32, __ptr64, __sptr, __uptr for AArch64 #111879
Conversation
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-clang Author: Daniel Paoliello (dpaoliello) ChangesMSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all. This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them. Partially fixes #62536 This is a resurrected version of <https://reviews.llvm.org/D158857> (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout. Full diff: https://github.com/llvm/llvm-project/pull/111879.diff 9 Files Affected:
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 61889861c9c803..efa49b0aaa65f5 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,11 @@ 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32");
}
void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
@@ -1560,7 +1562,7 @@ 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32");
}
WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
@@ -1583,8 +1585,8 @@ 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-p:64:64-i32:32-p270:32:32-p271:32:32-p272:64:64-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..b03bf9eca79ae4 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -21,6 +21,32 @@
namespace clang {
namespace targets {
+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
+ 270, // ptr32_sptr
+ 271, // ptr32_uptr
+ 272, // 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[];
@@ -32,6 +58,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
SveMode = (1 << 2),
};
+ enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
+
unsigned FPU = FPUMode;
bool HasCRC = false;
bool HasAES = false;
@@ -207,6 +235,19 @@ 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..98ba189d530bb8 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-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..09e1618ffbd68b 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-p:64:64-i32:32-p270:32:32-p271:32:32-p272:64:64-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..10984ab4dc634a 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-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 e469c2ae52eb72..cdc6ffe5f710f0 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5547,11 +5547,24 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
return Res;
}
+ auto AddPtr32Ptr64AddrSpaces = [&Res]() {
+ // If the datalayout matches the expected format, add pointer size address
+ // spaces to the datalayout.
+ constexpr std::string_view AddrSpaces = "-p270:32:32-p271:32:32-p272:64:64";
+ if (StringRef Ref = Res; !Ref.contains(AddrSpaces)) {
+ SmallVector<StringRef, 4> Groups;
+ Regex R("(e-m:[a-z](-p:32:32)?)(-[if]64:.*$)");
+ 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;
}
@@ -5570,15 +5583,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<StringRef, 4> 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 9f96f6c5e83ec4..77f9b6efc4737a 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -290,15 +290,15 @@ 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-p:64:64-i32:32-p270:32:32-p271:32:32-p272:64:64-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";
+ "-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-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..eaa02e4c9a91a5 100644
--- a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
+++ b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
@@ -31,7 +31,7 @@ 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");
// 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 +94,14 @@ 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");
|
@llvm/pr-subscribers-backend-aarch64 Author: Daniel Paoliello (dpaoliello) ChangesMSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all. This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them. Partially fixes #62536 This is a resurrected version of <https://reviews.llvm.org/D158857> (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout. Full diff: https://github.com/llvm/llvm-project/pull/111879.diff 9 Files Affected:
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 61889861c9c803..efa49b0aaa65f5 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,11 @@ 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32");
}
void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
@@ -1560,7 +1562,7 @@ 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32");
}
WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
@@ -1583,8 +1585,8 @@ 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-p:64:64-i32:32-p270:32:32-p271:32:32-p272:64:64-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..b03bf9eca79ae4 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -21,6 +21,32 @@
namespace clang {
namespace targets {
+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
+ 270, // ptr32_sptr
+ 271, // ptr32_uptr
+ 272, // 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[];
@@ -32,6 +58,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
SveMode = (1 << 2),
};
+ enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
+
unsigned FPU = FPUMode;
bool HasCRC = false;
bool HasAES = false;
@@ -207,6 +235,19 @@ 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..98ba189d530bb8 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-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..09e1618ffbd68b 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-p:64:64-i32:32-p270:32:32-p271:32:32-p272:64:64-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..10984ab4dc634a 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-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-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 e469c2ae52eb72..cdc6ffe5f710f0 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5547,11 +5547,24 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
return Res;
}
+ auto AddPtr32Ptr64AddrSpaces = [&Res]() {
+ // If the datalayout matches the expected format, add pointer size address
+ // spaces to the datalayout.
+ constexpr std::string_view AddrSpaces = "-p270:32:32-p271:32:32-p272:64:64";
+ if (StringRef Ref = Res; !Ref.contains(AddrSpaces)) {
+ SmallVector<StringRef, 4> Groups;
+ Regex R("(e-m:[a-z](-p:32:32)?)(-[if]64:.*$)");
+ 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;
}
@@ -5570,15 +5583,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<StringRef, 4> 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 9f96f6c5e83ec4..77f9b6efc4737a 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -290,15 +290,15 @@ 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-p:64:64-i32:32-p270:32:32-p271:32:32-p272:64:64-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";
+ "-i8:8:32-i16:16:32-p270:32:32-p271:32:32-p272:64:64-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..eaa02e4c9a91a5 100644
--- a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
+++ b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp
@@ -31,7 +31,7 @@ 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");
// 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 +94,14 @@ 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");
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
3daa496
to
281a05c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me.
cc @amykhuang
if (R.match(Res, &Groups)) | ||
Res = (Groups[1] + AddrSpaces + Groups[3]).str(); | ||
} | ||
AddPtr32Ptr64AddrSpaces(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I vaguely recall that the autoupgrade was somewhat painful for x86 usage, but I don't have anything specific, and we're just doing exactly the same stuff. @efriedma-quic are there any lessons learned there that we should keep in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there isn't any existing code using the new address-spaces, autoupgrading like this should work smoothly, I think? Need to make sure the autoupgraded string matches the new string, but otherwise should be fine. (I remember last time we made major changes for x86, the 128-bit integer alignment change, it was sort of tricky, but the issue mostly wasn't the layout string itself.)
Having a dedicated address-space for __ptr64 is a little strange, but I guess if that's what we did on x86, there isn't really a reason to deviate.
clang/lib/Basic/Targets/AArch64.h
Outdated
@@ -32,6 +58,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { | |||
SveMode = (1 << 2), | |||
}; | |||
|
|||
enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of nitty, but if you move this up to global scope and give it an AArch64-prefixed name you can use static_cast<unsigned>(AArch64::ptr32_sptr)
in place for 270 etc above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely prefer that - this whole thing has way too many magic numbers for my liking...
281a05c
to
ec2b533
Compare
…__sptr, __uptr for aarch64
ec2b533
to
0f2017d
Compare
if (R.match(Res, &Groups)) | ||
Res = (Groups[1] + AddrSpaces + Groups[3]).str(); | ||
} | ||
AddPtr32Ptr64AddrSpaces(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there isn't any existing code using the new address-spaces, autoupgrading like this should work smoothly, I think? Need to make sure the autoupgraded string matches the new string, but otherwise should be fine. (I remember last time we made major changes for x86, the 128-bit integer alignment change, it was sort of tricky, but the issue mostly wasn't the layout string itself.)
Having a dedicated address-space for __ptr64 is a little strange, but I guess if that's what we did on x86, there isn't really a reason to deviate.
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also need some tests in the backend? I guess most things likely work because we already did most of the work for the aarch64_32 ABI, but I'd like to see some tests that the basics work (load/store/arguments/return values).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backend hasn't been implemented yet - I'll have a follow up PR with the changes and tests.
There are tests for this - I also hit an issue with an unrelated test due to data layout upgrading not working correctly, so I added this to the auto-upgrade tests as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details
LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details
LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details
llvm: Match aarch64 data layout to new LLVM layout LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details
…, __sptr, __uptr for AArch64 (llvm#111879) MSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all. This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them. Partially fixes llvm#62536 This is a resurrected version of <https://reviews.llvm.org/D158857> (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout.
Rollup merge of rust-lang#131760 - maurer:data-layout-aarch64, r=nikic llvm: Match aarch64 data layout to new LLVM layout LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details
…, __sptr, __uptr for AArch64 (llvm#111879) MSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all. This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them. Partially fixes llvm#62536 This is a resurrected version of <https://reviews.llvm.org/D158857> (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout.
LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details
…, __sptr, __uptr for AArch64 (llvm#111879) MSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all. This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them. Partially fixes llvm#62536 This is a resurrected version of <https://reviews.llvm.org/D158857> (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout.
…, __sptr, __uptr for AArch64 (llvm#111879) MSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all. This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them. Partially fixes llvm#62536 This is a resurrected version of <https://reviews.llvm.org/D158857> (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout.
MSVC has a set of qualifiers to allow using 32-bit signed/unsigned pointers when building 64-bit targets. This is useful for WoW code (i.e., the part of Windows that handles running 32-bit application on a 64-bit OS). Currently this is supported on x64 using the 270, 271 and 272 address spaces, but does not work for AArch64 at all.
This change adds the same 270, 271 and 272 address spaces to AArch64 and adjusts the data layout string accordingly. Clang will generate the correct address space casts, but these will currently be ignored until the AArch64 backend is updated to handle them.
Partially fixes #62536
This is a resurrected version of https://reviews.llvm.org/D158857 (originally created by @a_vorobev) - I've cleaned it up a little, fixed the rest of the tests and added to auto-upgrade for the data layout.