-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SystemZ][z/OS] __ptr32 support for z/OS #101696
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
Conversation
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Abhina Sree (abhina-sree) ChangesEnabling __ptr32 keyword to support in Clang for z/OS. It is represented by addrspace(1) in LLVM IR. Unlike existing implementation, __ptr32 is not mangled into symbol names for z/OS. Patch is 34.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/101696.diff 16 Files Affected:
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 0035092ce0d863..c276c98d57db7b 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -91,6 +91,7 @@ LANGOPT(C2y , 1, 0, "C2y")
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
LANGOPT(Kernel , 1, 0, "Kernel mode")
LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
+LANGOPT(ZOSExt , 1, 0, "z/OS extensions")
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 7e638dc1ddcdba..9cb8a34ac15575 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -292,6 +292,7 @@ PUNCTUATOR(caretcaret, "^^")
// CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
// KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point
// extension.
+// KEYZOS - This is a keyword in C/C++ on z/OS
//
KEYWORD(auto , KEYALL)
KEYWORD(break , KEYALL)
@@ -722,7 +723,7 @@ KEYWORD(__funcref , KEYALL)
// Microsoft extensions which should be disabled in strict conformance mode
KEYWORD(__ptr64 , KEYMS)
-KEYWORD(__ptr32 , KEYMS)
+KEYWORD(__ptr32 , KEYMS | KEYZOS)
KEYWORD(__sptr , KEYMS)
KEYWORD(__uptr , KEYMS)
KEYWORD(__w64 , KEYMS)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index f690467bb82cd3..00b8f7c5635e2c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3065,6 +3065,10 @@ dll version.}]>;
def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">,
Group<f_Group>, Flags<[]>,
Visibility<[ClangOption, CLOption]>;
+def fzos_extensions : Flag<["-"], "fzos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Accept some non-standard constructs supported by the z/OS compiler">;
+def fno_zos_extensions : Flag<["-"], "fno-zos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Do not accept non-standard constructs supported by the z/OS compiler">;
defm delayed_template_parsing : BoolFOption<"delayed-template-parsing",
LangOpts<"DelayedTemplateParsing">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ead5da4e90f2f0..65f30cd2b012b7 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2727,6 +2727,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
// <type> ::= U <OpenCL-addrspace>
// <type> ::= U <CUDA-addrspace>
+ llvm::Triple Triple = getASTContext().getTargetInfo().getTriple();
+
SmallString<64> ASString;
LangAS AS = Quals.getAddressSpace();
@@ -2795,7 +2797,11 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
ASString = "ptr32_sptr";
break;
case LangAS::ptr32_uptr:
- ASString = "ptr32_uptr";
+ // For z/OS, there are no special mangling rules applied to the ptr32
+ // qualifier. Ex: void foo(int * __ptr32 p) -> _Z3f2Pi. The mangling for
+ // "p" is treated the same as a regular integer pointer.
+ if (!Triple.isOSzOS())
+ ASString = "ptr32_uptr";
break;
case LangAS::ptr64:
ASString = "ptr64";
diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp
index 4f7ccaf4021d63..1ef07d41839c7a 100644
--- a/clang/lib/Basic/IdentifierTable.cpp
+++ b/clang/lib/Basic/IdentifierTable.cpp
@@ -107,12 +107,14 @@ namespace {
KEYMSCOMPAT = 0x400000,
KEYSYCL = 0x800000,
KEYCUDA = 0x1000000,
- KEYHLSL = 0x2000000,
- KEYFIXEDPOINT = 0x4000000,
+ KEYZOS = 0x2000000,
+ KEYNOZOS = 0x4000000,
+ KEYHLSL = 0x8000000,
+ KEYFIXEDPOINT = 0x10000000,
KEYMAX = KEYFIXEDPOINT, // The maximum key
KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20,
- KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 &
- ~KEYNOOPENCL // KEYNOMS18 and KEYNOOPENCL are used to exclude.
+ KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 & ~KEYNOOPENCL &
+ ~KEYNOZOS // KEYNOMS18, KEYNOOPENCL, KEYNOZOS are excluded.
};
/// How a keyword is treated in the selected standard. This enum is ordered
@@ -199,6 +201,8 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown;
case KEYCUDA:
return LangOpts.CUDA ? KS_Enabled : KS_Unknown;
+ case KEYZOS:
+ return LangOpts.ZOSExt ? KS_Enabled : KS_Unknown;
case KEYHLSL:
return LangOpts.HLSL ? KS_Enabled : KS_Unknown;
case KEYNOCXX:
@@ -211,6 +215,9 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
case KEYNOMS18:
// The disable behavior for this is handled in getKeywordStatus.
return KS_Unknown;
+ case KEYNOZOS:
+ // The disable behavior for this is handled in getKeywordStatus.
+ return KS_Unknown;
case KEYFIXEDPOINT:
return LangOpts.FixedPoint ? KS_Enabled : KS_Disabled;
default:
@@ -230,7 +237,8 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
!LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
return KS_Disabled;
-
+ if (LangOpts.ZOSExt && (Flags & KEYNOZOS))
+ return KS_Disabled;
KeywordStatus CurStatus = KS_Unknown;
while (Flags != 0) {
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index 3bc6f2c1d30832..7390f25d6efb1d 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -21,6 +21,30 @@
namespace clang {
namespace targets {
+static const unsigned ZOSAddressMap[] = {
+ 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
+ 0, // ptr32_sptr
+ 1, // ptr32_uptr
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ 0 // wasm_funcref
+};
+
class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
static const char *const GCCRegNames[];
@@ -30,6 +54,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
bool HasVector;
bool SoftFloat;
bool UnalignedSymbols;
+ enum AddrSpace { ptr32 = 1 };
public:
SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -49,6 +74,9 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
MinGlobalAlign = 16;
HasUnalignedAccess = true;
if (Triple.isOSzOS()) {
+ if (Triple.isArch64Bit()) {
+ AddrSpaceMap = &ZOSAddressMap;
+ }
TLSSupported = false;
// All vector types are default aligned on an 8-byte boundary, even if the
// vector facility is not available. That is different from Linux.
@@ -56,7 +84,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
// Compared to Linux/ELF, the data layout differs only in some details:
// - name mangling is GOFF.
// - 32 bit pointers, either as default or special address space
- resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
+ resetDataLayout("E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
"a:8:16-n32:64");
} else {
TLSSupported = true;
@@ -224,6 +252,16 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(256, 256);
}
+ uint64_t getPointerWidthV(LangAS AddrSpace) const override {
+ return (getTriple().isOSzOS() && getTriple().isArch64Bit() &&
+ getTargetAddressSpace(AddrSpace) == ptr32)
+ ? 32
+ : PointerWidth;
+ }
+
+ uint64_t getPointerAlignV(LangAS AddrSpace) const override {
+ return getPointerWidthV(AddrSpace);
+ }
};
} // namespace targets
} // namespace clang
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index f6b6c44a4cab6a..790a65942d6761 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3642,6 +3642,14 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Consumer, OPT_ftrigraphs);
}
+ if (T.isOSzOS()) {
+ if (!Opts.ZOSExt)
+ GenerateArg(Consumer, OPT_fno_zos_extensions);
+ } else {
+ if (Opts.ZOSExt)
+ GenerateArg(Consumer, OPT_fzos_extensions);
+ }
+
if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
GenerateArg(Consumer, OPT_fblocks);
@@ -4043,6 +4051,9 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.Trigraphs =
Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
+ Opts.ZOSExt =
+ Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());
+
Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
&& Opts.OpenCLVersion == 200);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 6fa39cdccef2b9..6ea87cc3425dc7 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7051,6 +7051,7 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
// Add address space to type based on its attributes.
LangAS ASIdx = LangAS::Default;
+ llvm::Triple Triple = S.Context.getTargetInfo().getTriple();
uint64_t PtrWidth =
S.Context.getTargetInfo().getPointerWidth(LangAS::Default);
if (PtrWidth == 32) {
@@ -7059,7 +7060,7 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
else if (Attrs[attr::UPtr])
ASIdx = LangAS::ptr32_uptr;
} else if (PtrWidth == 64 && Attrs[attr::Ptr32]) {
- if (Attrs[attr::UPtr])
+ if (Triple.isOSzOS() || Attrs[attr::UPtr])
ASIdx = LangAS::ptr32_uptr;
else
ASIdx = LangAS::ptr32_sptr;
diff --git a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-definitions.c b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-definitions.c
new file mode 100644
index 00000000000000..8fac3ccc78e5a5
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-definitions.c
@@ -0,0 +1,54 @@
+
+// RUN: %clang_cc1 -triple s390x-ibm-zos -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-ZOS
+// RUN: %clang_cc1 -triple s390x-ibm-linux -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-LINUX
+// RUN: %clang_cc1 -triple s390x-linux-gnu -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-LINUX
+
+void ptr32_declarations() {
+ // PTR32-ZOS-LABEL: @ptr32_declarations()
+ // PTR32-LINUX-LABEL: @ptr32_declarations()
+
+ // PTR32-ZOS: %p1 = alloca ptr addrspace(1), align 4
+ // PTR32-LINUX-NOT: %p1 = alloca i8 addrspace(1)*, align 4
+ // PTR32-LINUX: %p1 = alloca ptr, align 8
+ char * __ptr32 p1;
+
+ // PTR32-ZOS: %p2 = alloca ptr, align 8
+ // PTR32-LINUX-NOT: %p2 = alloca ptr addrspace(1), align 8
+ // PTR32-LINUX: %p2 = alloca ptr, align 8
+ char * __ptr32 *p2;
+
+ // PTR32-ZOS: %p3 = alloca ptr addrspace(1), align 4
+ // PTR32-LINUX-NOT: %p3 = alloca i8* addrspace(1)*, align 4
+ // PTR32-LINUX: %p3 = alloca ptr, align 8
+ char ** __ptr32 p3;
+
+ // PTR32-ZOS: %p4 = alloca ptr, align 8
+ // PTR32-LINUX-NOT: %p4 = alloca ptr addrspace(1), align 8
+ // PTR32-LINUX: %p4 = alloca ptr, align 8
+ char ** __ptr32 *p4;
+
+ // PTR32-ZOS: %p5 = alloca ptr, align 8
+ // PTR32-LINUX-NOT: %p5 = alloca ptr addrspace(1), align 8
+ // PTR32-LINUX: %p5 = alloca ptr, align 8
+ char *** __ptr32 *p5;
+
+ // PTR32-ZOS: %p6 = alloca ptr, align 8
+ // PTR32-LINUX: %p6 = alloca ptr, align 8
+ char **p6;
+
+ // PTR32-ZOS: %p7 = alloca ptr addrspace(1), align 4
+ // PTR32-LINUX-NOT: %p7 = alloca i8 addrspace(1)* addrspace(1)*, align 4
+ // PTR32-LINUX: %p7 = alloca ptr, align 8
+ char * __ptr32 * __ptr32 p7;
+
+ // PTR32-ZOS: %p8 = alloca ptr addrspace(1), align 4
+ // PTR32-LINUX-NOT: %p8 = alloca i8* addrspace(1)* addrspace(1)*, align 4
+ // PTR32-LINUX: %p8 = alloca ptr, align 8
+ char ** __ptr32 * __ptr32 p8;
+
+ // PTR32-ZOS: %p9 = alloca ptr, align 8
+ // PTR32-LINUX-NOT: %p9 = alloca i8* addrspace(1)* addrspace(1)**, align 8
+ // PTR32-LINUX: %p9 = alloca ptr, align 8
+ char ** __ptr32 * __ptr32 *p9;
+
+}
diff --git a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c
new file mode 100644
index 00000000000000..1018c113ceea01
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -triple s390x-ibm-zos -fzos-extensions -emit-llvm -O2 < %s | FileCheck %s --check-prefix=X64
+#include <stddef.h>
+void *__malloc31(size_t);
+
+int test_1() {
+ // X64-LABEL: define {{.*}} i32 @test_1()
+ // X64: ret i32 135
+ int *__ptr32 a;
+ int *b;
+ int i;
+ int sum1, sum2, sum3;
+
+ a = (int *__ptr32)__malloc31(sizeof(int) * 10);
+
+ b = a;
+ sum1 = 0;
+ for (i = 0; i < 10; ++i) {
+ a[i] = i;
+ sum1 += i;
+ }
+
+ sum2 = 0;
+ for (i = 0; i < 10; ++i) {
+ sum2 += a[i];
+ }
+ sum3 = 0;
+ for (i = 0; i < 10; ++i) {
+ sum3 += b[i];
+ }
+
+ return (sum1 + sum2 + sum3);
+}
+
+int test_2() {
+ // X64-LABEL: define {{.*}} i32 @test_2()
+ // X64: ret i32 4
+ int *a = (int *)__malloc31(sizeof(int));
+ int *__ptr32 b;
+
+ *a = 99;
+ b = a;
+ *b = 44;
+
+ // Test should return 4
+ return (*b - 40);
+}
+
+int test_3() {
+ // X64-LABEL: define {{.*}} i32 @test_3()
+ // X64: ret i32 4
+ int *a = (int *)__malloc31(sizeof(int));
+ int *__ptr32 b;
+
+ *a = 99;
+ b = a;
+
+ // Test should return 4
+ return (*b - 95);
+}
+
+int test_4() {
+ // X64-LABEL: define {{.*}} i32 @test_4()
+ // X64: ret i32 1
+ int *a = (int *)__malloc31(sizeof(int));
+ float *d = (float *)__malloc31(sizeof(float));
+
+ int *__ptr32 b;
+ int *c;
+
+ float *__ptr32 e;
+ float *f;
+
+ *a = 0;
+ *d = 0.0;
+
+ b = a;
+ c = a;
+ e = d;
+ f = d;
+
+ // Test should return 1
+ return (b == c && e == f);
+}
+
diff --git a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-sizeof.c b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-sizeof.c
new file mode 100644
index 00000000000000..6b434a926f706b
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-sizeof.c
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -emit-llvm -triple s390x-ibm-zos -fzos-extensions -fdump-record-layouts < %s | FileCheck %s --check-prefix=PTR32-ZOS
+// RUN: %clang_cc1 -emit-llvm -triple s390x-ibm-linux -fzos-extensions -fdump-record-layouts < %s | FileCheck %s --check-prefix=PTR32-LINUX
+// RUN: %clang_cc1 -emit-llvm -triple s390x-linux-gnu -fzos-extensions -fdump-record-layouts < %s | FileCheck %s --check-prefix=PTR32-LINUX
+
+// PTR32-ZOS: 0 | struct s1
+// PTR32-ZOS-NEXT: 0 | long a
+// PTR32-ZOS-NEXT: 8 | int b
+// PTR32-ZOS-NEXT: 12 | int * __ptr32 c
+// PTR32-ZOS-NEXT: 16 | int d
+// PTR32-ZOS-NEXT: | [sizeof=24, align=8]
+
+// PTR32-LINUX: 0 | struct s1
+// PTR32-LINUX-NEXT: 0 | long a
+// PTR32-LINUX-NEXT: 8 | int b
+// PTR32-LINUX-NEXT: 16 | int * __ptr32 c
+// PTR32-LINUX-NEXT: 24 | int d
+// PTR32-LINUX-NEXT: | [sizeof=32, align=8]
+struct s1 {
+ long a;
+ int b;
+ int * __ptr32 c;
+ int d;
+} S1;
+
+// PTR32-ZOS: 0 | struct s2
+// PTR32-ZOS-NEXT: 0 | long a
+// PTR32-ZOS-NEXT: 8 | int b
+// PTR32-ZOS-NEXT: 16 | int * c
+// PTR32-ZOS-NEXT: 24 | int d
+// PTR32-ZOS-NEXT: | [sizeof=32, align=8]
+
+// PTR32-LINUX: 0 | struct s2
+// PTR32-LINUX-NEXT: 0 | long a
+// PTR32-LINUX-NEXT: 8 | int b
+// PTR32-LINUX-NEXT: 16 | int * c
+// PTR32-LINUX-NEXT: 24 | int d
+// PTR32-LINUX-NEXT: | [sizeof=32, align=8]
+struct s2 {
+ long a;
+ int b;
+ int *c;
+ int d;
+} S2;
+
+// PTR32-ZOS: 0 | struct s3
+// PTR32-ZOS-NEXT: 0 | int a
+// PTR32-ZOS-NEXT: 4 | int * __ptr32 b
+// PTR32-ZOS-NEXT: 8 | int * __ptr32 c
+// PTR32-ZOS-NEXT: 12 | int * d
+// PTR32-ZOS-NEXT: | [sizeof=20, align=1]
+
+struct __attribute__((packed)) s3 {
+ int a;
+ int *__ptr32 b;
+ int *__ptr32 c;
+ int *d;
+};
+struct s3 S3;
+
+// PTR32-ZOS: 0 | union u1
+// PTR32-ZOS-NEXT: 0 | int * __ptr32 a
+// PTR32-ZOS-NEXT: 0 | int * b
+// PTR32-ZOS-NEXT: | [sizeof=8, align=8]
+
+// PTR32-LINUX: 0 | union u1
+// PTR32-LINUX-NEXT: 0 | int * __ptr32 a
+// PTR32-LINUX-NEXT: 0 | int * b
+// PTR32-LINUX-NEXT: | [sizeof=8, align=8]
+union u1 {
+ int *__ptr32 a;
+ int *b;
+} U1;
+
+// PTR32-ZOS: 0 | union u2
+// PTR32-ZOS-NEXT: 0 | int * __ptr32 a
+// PTR32-ZOS-NEXT: 0 | int * b
+// PTR32-ZOS-NEXT: | [sizeof=8, align=1]
+
+union __attribute__((packed)) u2 {
+ int *__ptr32 a;
+ int *b;
+};
+union u2 U2;
+
+// PTR32-ZOS: 0 | union u3
+// PTR32-ZOS-NEXT: 0 | int * __ptr32 a
+// PTR32-ZOS-NEXT: 0 | short b
+// PTR32-ZOS-NEXT: | [sizeof=4, align=1]
+
+union __attribute__((packed)) u3 {
+ int *__ptr32 a;
+ short b;
+};
+union u3 U3;
diff --git a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c
new file mode 100644
index 00000000000000..24bd75284ebc4c
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c
@@ -0,0 +1,298 @@
+// RUN: %clang_cc1 -triple s390x-ibm-zos -fzos-extensions -emit-llvm -O2 < %s | FileCheck %s --check-prefix=X64
+
+#define PSA_PTR 0x00
+#define PSAAOLD 0x224
+
+struct Foo {
+ int * __ptr32 p32;
+ int *p64;
+ char *cp64;
+};
+
+void use_foo(struct Foo *f);
+
+void ptr32_to_ptr(struct Foo *f, int * __ptr32 i) {
+ // X64-LABEL: define void @ptr32_to_ptr(ptr noundef %f, ptr addrspace(1) noundef %i)
+ // X64: %{{.+}} = addrspacecast ptr addrspace(1) %i to ptr
+ f->p64= i;
+ use_foo(f);
+}
+
+void ptr_to_ptr32(struct Foo *f, int *i) {
+ // X64-LABEL: define void @ptr_to_ptr32(ptr noundef %f, ptr noundef %i)
+ // X64: %{{.+}} = addrspacecast ptr %i to ptr addrspace(1)
+ f->p32 = i;
+ use_foo(f);
+}
+
+void ptr32_to_ptr32(struct Foo *f, int * __ptr32 i) {
+ // X64-LABEL: define void @ptr32_to_ptr32(ptr noundef %f, ptr addrspace(1) noundef %i)
+ // X64-NOT: addrspacecast
+ f->p32 = i;
+ use_foo(f);
+}
+
+void ptr_to_ptr32_explicit_cast(struct Foo *f, int *i) {
+ // X64-LABEL: define void @ptr_to_ptr32_explicit_cast(ptr noundef %f, ptr noundef %i)
+ // X64: %{{.+}} = addrspacecast ptr %i to ptr addrspace(1)
+ f->p32 = (int * __ptr32)i;
+ use_foo(f);
+}
+
+void test_indexing(struct Foo *f) {
+ // X64-LABEL: define void @test_indexing(ptr noundef %f)
+ // X64: addrspacecast ptr addrspace(1) {{%[0-9]}} to ptr
+ f->cp64 = ((char * __ptr32 *)1028)[1];
+ use_foo(f);
+}
+
+void test_indexing_2(struct Foo *f) {
+ // X64-LABEL: define void @test_indexing_2(ptr noundef %f)
+ // X64: getelementptr inbounds i8, ptr addrspace(1) {{%[0-9]}}, i32 16
+ // X64: getelementptr inbounds i8, ptr {{%[0-9]}}, i64 24
+ f->cp64 = ((char *** __ptr32 *)1028)[1][2][3];
+ use_foo(f);
+}
+
+unsigned long* test_misc() {
+ // X64-LABEL: define ptr @test_misc()
+ // X64: %arrayidx = getelementptr inbounds i8, ptr addrspace(1) %0, i32 88
+ // X64-NEXT: %1 = load ptr, ptr addrspace(1) %arrayidx
+ // X64-NEXT: %arrayidx1 = getelementptr inbounds i8, ptr %1, i64 8
+ // X64-NEXT: %2 = load ptr, ptr %arrayidx1
+ // X64-NEXT: %arrayidx2 = getelementptr inbounds i8, ptr %2, i64 904
+ // X64-NEXT: %3 = load ptr, ptr %arrayidx2
+ // X64-NEXT: %arrayidx3 = getelementptr inbounds i8, ptr %3, i6...
[truncated]
|
3225fec
to
0246fe8
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
0246fe8
to
20a999c
Compare
20a999c
to
f6e1481
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.
LGTM
…to test for defaults
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 Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/73/builds/3370 Here is the relevant piece of the build log for the reference:
|
Enabling __ptr32 keyword to support in Clang for z/OS. It is represented by addrspace(1) in LLVM IR. Unlike existing implementation, __ptr32 is not mangled into symbol names for z/OS.