[clang] [llvm] [SystemZ][z/OS] __ptr32 support for z/OS in Clang (PR #96063)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 19 04:46:40 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-systemz
@llvm/pr-subscribers-clang
Author: Fanbo Meng (fanbo-meng)
<details>
<summary>Changes</summary>
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.
---
Patch is 35.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/96063.diff
17 Files Affected:
- (modified) clang/include/clang/Basic/LangOptions.def (+1)
- (modified) clang/include/clang/Basic/TokenKinds.def (+2-1)
- (modified) clang/include/clang/Driver/Options.td (+4)
- (modified) clang/lib/AST/ItaniumMangle.cpp (+7-1)
- (modified) clang/lib/Basic/IdentifierTable.cpp (+12-4)
- (modified) clang/lib/Basic/Targets/SystemZ.h (+42-1)
- (modified) clang/lib/Frontend/CompilerInvocation.cpp (+11)
- (modified) clang/lib/Sema/SemaType.cpp (+8-3)
- (modified) clang/test/CodeGen/target-data.c (+1-1)
- (added) clang/test/CodeGen/zos-mixed-ptr-sizes-definitions.c (+53)
- (added) clang/test/CodeGen/zos-mixed-ptr-sizes-malloc.c (+84)
- (added) clang/test/CodeGen/zos-mixed-ptr-sizes-sizeof.c (+94)
- (added) clang/test/CodeGen/zos-mixed-ptr-sizes.c (+298)
- (added) clang/test/CodeGenCXX/zos-mangle-ptr-size-address-space.cpp (+17)
- (added) clang/test/Sema/ZOSExtensions.cpp (+119)
- (added) clang/test/Sema/attr-print-zos.c (+31)
- (modified) llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp (+8)
``````````diff
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 2dea3cd4d795b..9f303b2f549bf 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -90,6 +90,7 @@ LANGOPT(C23 , 1, 0, "C23")
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 9c4b17465e18a..9717ecd6d7d66 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -286,6 +286,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)
@@ -708,7 +709,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 d44faa55c456f..e0ae29f881d9e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3038,6 +3038,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 ed9e6eeb36c75..8c0bc9474dbc0 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2728,6 +2728,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();
@@ -2796,7 +2798,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 feea84544d62f..ac7409c9b587b 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 used to exclude.
};
/// 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,6 +237,7 @@ 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;
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index 3bc6f2c1d3083..5f4f93cbfa48e 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,19 @@ 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 {
+ unsigned TargetAddrSpace = getTargetAddressSpace(AddrSpace);
+ return (TargetAddrSpace == ptr32 && getTriple().isOSzOS() &&
+ getTriple().isArch64Bit())
+ ? 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 58694e5399d58..ef982214eba61 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3567,6 +3567,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);
@@ -3968,6 +3976,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 441fdcca0758f..346139042d114 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7089,6 +7089,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) {
@@ -7097,10 +7098,14 @@ 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()) {
ASIdx = LangAS::ptr32_uptr;
- else
- ASIdx = LangAS::ptr32_sptr;
+ } else {
+ if (Attrs[attr::UPtr])
+ ASIdx = LangAS::ptr32_uptr;
+ else
+ ASIdx = LangAS::ptr32_sptr;
+ }
}
QualType Pointee = Type->getPointeeType();
diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c
index 7f7005d21b99a..d487584521e78 100644
--- a/clang/test/CodeGen/target-data.c
+++ b/clang/test/CodeGen/target-data.c
@@ -235,7 +235,7 @@
// RUN: FileCheck %s -check-prefix=ZOS
// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z13 -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=ZOS
-// ZOS: target datalayout = "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+// ZOS: target datalayout = "E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
// RUN: %clang_cc1 -triple msp430-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=MSP430
diff --git a/clang/test/CodeGen/zos-mixed-ptr-sizes-definitions.c b/clang/test/CodeGen/zos-mixed-ptr-sizes-definitions.c
new file mode 100644
index 0000000000000..887ce1ddfe931
--- /dev/null
+++ b/clang/test/CodeGen/zos-mixed-ptr-sizes-definitions.c
@@ -0,0 +1,53 @@
+// 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/zos-mixed-ptr-sizes-malloc.c b/clang/test/CodeGen/zos-mixed-ptr-sizes-malloc.c
new file mode 100644
index 0000000000000..1018c113ceea0
--- /dev/null
+++ b/clang/test/CodeGen/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/zos-mixed-ptr-sizes-sizeof.c b/clang/test/CodeGen/zos-mixed-ptr-sizes-sizeof.c
new file mode 100644
index 0000000000000..6b434a926f706
--- /dev/null
+++ b/clang/test/CodeGen/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/zos-mixed-ptr-sizes.c b/clang/test/CodeGen/zos-mixed-ptr-sizes.c
new file mode 100644
index 0000000000000..24bd75284ebc4
--- /dev/null
+++ b/clang/test/CodeGen/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...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/96063
More information about the cfe-commits
mailing list