r372387 - [SystemZ] Add SystemZ as supporting target in help text for -mfentry.
Author: jonpa Date: Fri Sep 20 06:13:50 2019 New Revision: 372387 URL: http://llvm.org/viewvc/llvm-project?rev=372387&view=rev Log: [SystemZ] Add SystemZ as supporting target in help text for -mfentry. => "Insert calls to fentry at function entry (x86/SystemZ only)" Review: Ulrich Weigand Modified: cfe/trunk/docs/ClangCommandLineReference.rst cfe/trunk/include/clang/Driver/Options.td Modified: cfe/trunk/docs/ClangCommandLineReference.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangCommandLineReference.rst?rev=372387&r1=372386&r2=372387&view=diff == --- cfe/trunk/docs/ClangCommandLineReference.rst (original) +++ cfe/trunk/docs/ClangCommandLineReference.rst Fri Sep 20 06:13:50 2019 @@ -2194,7 +2194,7 @@ Set EABI type, e.g. 4, 5 or gnu (default .. option:: -mfentry -Insert calls to fentry at function entry (x86 only) +Insert calls to fentry at function entry (x86/SystemZ only) .. option:: -mfloat-abi= Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=372387&r1=372386&r2=372387&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Fri Sep 20 06:13:50 2019 @@ -2387,7 +2387,7 @@ def mpie_copy_relocations : Flag<["-"], Flags<[CC1Option]>, HelpText<"Use copy relocations support for PIE builds">; def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group; -def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86 only)">, +def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">, Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group; def mno_mips16 : Flag<["-"], "mno-mips16">, Group; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 515bfc6 - [SystemZ] Implement -fstack-clash-protection
Author: Jonas Paulsson Date: 2020-06-06T18:38:36+02:00 New Revision: 515bfc66eaced830c03b2ec187bef0d8c4dc6915 URL: https://github.com/llvm/llvm-project/commit/515bfc66eaced830c03b2ec187bef0d8c4dc6915 DIFF: https://github.com/llvm/llvm-project/commit/515bfc66eaced830c03b2ec187bef0d8c4dc6915.diff LOG: [SystemZ] Implement -fstack-clash-protection Probing of allocated stack space is now done when this option is passed. The purpose is to protect against the stack clash attack (see https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt). Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D78717 Added: clang/test/Driver/stack-clash-protection-02.c llvm/test/CodeGen/SystemZ/stack-clash-dynamic-alloca.ll llvm/test/CodeGen/SystemZ/stack-clash-protection.ll Modified: clang/docs/ReleaseNotes.rst clang/lib/Basic/Targets/SystemZ.h clang/lib/Driver/ToolChains/Clang.cpp clang/test/CodeGen/stack-clash-protection.c llvm/include/llvm/ADT/Triple.h llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp llvm/lib/Target/SystemZ/SystemZFrameLowering.h llvm/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/lib/Target/SystemZ/SystemZISelLowering.h llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp llvm/lib/Target/SystemZ/SystemZInstrInfo.h llvm/lib/Target/SystemZ/SystemZInstrInfo.td llvm/lib/Target/SystemZ/SystemZOperators.td Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 25ff809120de..15e6d35117b4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -94,8 +94,8 @@ New Compiler Flags -- - -fstack-clash-protection will provide a protection against the stack clash - attack for x86 architecture through automatic probing of each page of - allocated stack. + attack for x86 and s390x architectures through automatic probing of each page + of allocated stack. - -ffp-exception-behavior={ignore,maytrap,strict} allows the user to specify the floating-point exception behavior. The default setting is ``ignore``. diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 1c8822e2bc2d..134b0313b86a 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -64,6 +64,10 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { ArrayRef getGCCAddlRegNames() const override; + bool isSPRegName(StringRef RegName) const override { +return RegName.equals("r15"); + } + bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index b20048768e44..513f32caad8a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2997,7 +2997,7 @@ static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args, if (!EffectiveTriple.isOSLinux()) return; - if (!EffectiveTriple.isX86()) + if (!EffectiveTriple.isX86() && !EffectiveTriple.isSystemZ()) return; if (Args.hasFlag(options::OPT_fstack_clash_protection, diff --git a/clang/test/CodeGen/stack-clash-protection.c b/clang/test/CodeGen/stack-clash-protection.c index f970bf909cbe..eb48da8ff9e9 100644 --- a/clang/test/CodeGen/stack-clash-protection.c +++ b/clang/test/CodeGen/stack-clash-protection.c @@ -1,5 +1,6 @@ // Check the correct function attributes are generated // RUN: %clang_cc1 -triple x86_64-linux -O0 -S -emit-llvm -o- %s -fstack-clash-protection | FileCheck %s +// RUN: %clang_cc1 -triple s390x-linux-gnu -O0 -S -emit-llvm -o- %s -fstack-clash-protection | FileCheck %s // CHECK: define void @large_stack() #[[A:.*]] { void large_stack() { diff --git a/clang/test/Driver/stack-clash-protection-02.c b/clang/test/Driver/stack-clash-protection-02.c new file mode 100644 index ..25ff3b5d6940 --- /dev/null +++ b/clang/test/Driver/stack-clash-protection-02.c @@ -0,0 +1,13 @@ +// RUN: %clang -target s390x-linux-gnu -fstack-clash-protection -### %s 2>&1 | FileCheck %s -check-prefix=SystemZ +// SystemZ: "-fstack-clash-protection" +// RUN: %clang -target s390x-linux-gnu -fstack-clash-protection -S -emit-llvm -o %t.ll %s 2>&1 | FileCheck %s -check-prefix=SystemZ-warn +// SystemZ-warn: warning: Unable to protect inline asm that clobbers stack pointer against stack clash + +int foo(int c) { + int r; + __asm__("ag %%r15, %0" + : + : "rm"(c) + : "r15"); + return r; +} diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index fa437a57520a..8e46265c7f71 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -739,6 +739,11 @@ class Triple { return getArch() == Triple::riscv32 || getArch() == Triple::riscv64; } + /// T
[clang] de0e311 - [SystemZ] Improve handling of vector alignments.
Author: Jonas Paulsson Date: 2022-09-08T17:33:05+02:00 New Revision: de0e3117d40af95993b11d0622f9700415552d48 URL: https://github.com/llvm/llvm-project/commit/de0e3117d40af95993b11d0622f9700415552d48 DIFF: https://github.com/llvm/llvm-project/commit/de0e3117d40af95993b11d0622f9700415552d48.diff LOG: [SystemZ] Improve handling of vector alignments. Make the DataLayout string always hold a vector alignment of 8 bytes, regardless of the vector ABI. This makes the datalayout depend only on the target triple which is the general expectation (in assertions). On older architectures where vectors use the natural alignment (16 bytes), the front end will maintain the same behavior and produce an overalignment compared to the datalayout. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D131158 Added: clang/test/CodeGen/SystemZ/align-systemz-02.c Modified: clang/lib/Basic/Targets/SystemZ.h clang/test/CodeGen/target-data.c llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp llvm/test/CodeGen/SystemZ/function-attributes-01.ll llvm/test/CodeGen/SystemZ/vec-abi-align.ll Removed: diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 7def024d07a7..371eb2516378 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -51,13 +51,13 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { // All vector types are default aligned on an 8-byte boundary, even if the // vector facility is not available. That is diff erent from Linux. MaxVectorAlign = 64; - // Compared to Linux/ELF, the data layout diff ers only in some details: - // - name mangling is GOFF - // - 128 bit vector types are 64 bit aligned + // Compared to Linux/ELF, the data layout diff ers only in that name + // mangling is GOFF. resetDataLayout( "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"); } else - resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); + resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" + "-v128:64-a:8:16-n32:64"); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; HasStrictFP = true; } @@ -171,12 +171,14 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { } HasVector &= !SoftFloat; -// If we use the vector ABI, vector types are 64-bit aligned. -if (HasVector && !getTriple().isOSzOS()) { +// If we use the vector ABI, vector types are 64-bit aligned. The +// DataLayout string is always set to this alignment as it is not a +// requirement that it follows the alignment emitted by the front end. It +// is assumed generally that the Datalayout should reflect only the +// target triple and not any specific feature. +if (HasVector && !getTriple().isOSzOS()) MaxVectorAlign = 64; - resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" - "-v128:64-a:8:16-n32:64"); -} + return true; } diff --git a/clang/test/CodeGen/SystemZ/align-systemz-02.c b/clang/test/CodeGen/SystemZ/align-systemz-02.c new file mode 100644 index ..cc09a9093741 --- /dev/null +++ b/clang/test/CodeGen/SystemZ/align-systemz-02.c @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature +vector -emit-llvm \ +// RUN:| FileCheck %s -check-prefix=VECIR +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature +vector -emit-obj -S \ +// RUN:| FileCheck %s -check-prefix=VECASM +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature -vector -emit-llvm \ +// RUN:| FileCheck %s -check-prefix=SCALIR +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature -vector -emit-obj -S \ +// RUN:| FileCheck %s -check-prefix=SCALASM + +typedef __attribute__((vector_size(16))) signed int vec_sint; + +volatile vec_sint GlobVsi; + +struct S { + int A; + vec_sint Vsi; +} GlobS; + +void fun() { + GlobS.Vsi = GlobVsi; +} + +// VECIR: %struct.S = type { i32, <4 x i32> } +// VECIR: @GlobVsi = global <4 x i32> zeroinitializer, align 8 +// VECIR: @GlobS = global %struct.S zeroinitializer, align 8 +// VECIR: %0 = load volatile <4 x i32>, ptr @GlobVsi, align 8 +// VECIR: store <4 x i32> %0, ptr getelementptr inbounds (%struct.S, ptr @GlobS, i32 0, i32 1), align 8 + +// VECASM: lgrl %r1, GlobVsi@GOT +// VECASM-NEXT: vl %v0, 0(%r1), 3 +// VECASM-NEXT: lgrl %r1, GlobS@GOT +// VECASM-NEXT: vst %v0, 8(%r1), 3 +// +// VECASM: .globl GlobVsi +// VECASM: .p2align3 +// VECASM: GlobVsi: +// VECASM: .space 16 +// VECASM: .globl GlobS +// VECASM: .p2align3 +// VECASM: GlobS: +// VECASM: .space 24 + +// SCALIR: %struct.S = type { i32, [12 x i8], <4 x i32> } +// SCALIR: @GlobVsi = global <4 x i32> zeroinitializ
[clang] 906ea59 - [SystemZ] Fix new test case
Author: Jonas Paulsson Date: 2022-09-08T18:05:17+02:00 New Revision: 906ea59d00f0deb9777aa977fdcb589d4736244c URL: https://github.com/llvm/llvm-project/commit/906ea59d00f0deb9777aa977fdcb589d4736244c DIFF: https://github.com/llvm/llvm-project/commit/906ea59d00f0deb9777aa977fdcb589d4736244c.diff LOG: [SystemZ] Fix new test case Add 'REQUIRES: systemz-registered-target'. Added: Modified: clang/test/CodeGen/SystemZ/align-systemz-02.c Removed: diff --git a/clang/test/CodeGen/SystemZ/align-systemz-02.c b/clang/test/CodeGen/SystemZ/align-systemz-02.c index cc09a9093741..013faea61ada 100644 --- a/clang/test/CodeGen/SystemZ/align-systemz-02.c +++ b/clang/test/CodeGen/SystemZ/align-systemz-02.c @@ -6,6 +6,7 @@ // RUN:| FileCheck %s -check-prefix=SCALIR // RUN: %clang_cc1 -triple s390x-linux-gnu %s -o - -target-feature -vector -emit-obj -S \ // RUN:| FileCheck %s -check-prefix=SCALASM +// REQUIRES: systemz-registered-target typedef __attribute__((vector_size(16))) signed int vec_sint; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Ensure minimal alignment of global vars of incomplete type. (PR #72886)
JonPsson1 wrote: @efriedma-quic @rjmccall @uweigand (for review) https://github.com/llvm/llvm-project/pull/72886 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Ensure minimal alignment of global vars of incomplete type. (PR #72886)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/72886 The SystemZ ABI requires any global variable to be aligned to at least 2 bytes, and therefore an external global Value with an opaque type should get this alignment as well. >From e9380e98527790aee19857b221b7b63d43a0ee87 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Mon, 20 Nov 2023 12:29:33 +0100 Subject: [PATCH] [clang] Ensure minimial alignment of global vars of incomplete type. The SystemZ ABI requires any global variable to be aligned to at least 2 bytes, and therefore an external global Value with an opaque type should get this alignment as well. --- clang/lib/AST/ASTContext.cpp | 14 +++- clang/test/Driver/systemz-alignment.c | 32 +++ 2 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 clang/test/Driver/systemz-alignment.c diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1c893d008cb49f3..a7cee3b7ba2b0db 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1680,14 +1680,16 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); if (BaseT.getQualifiers().hasUnaligned()) Align = Target->getCharWidth(); - if (const auto *VD = dyn_cast(D)) { -if (VD->hasGlobalStorage() && !ForAlignof) { - uint64_t TypeSize = getTypeSize(T.getTypePtr()); - Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); -} - } } +// Ensure miminum alignment for global variables. +if (const auto *VD = dyn_cast(D)) + if (VD->hasGlobalStorage() && !ForAlignof) { +uint64_t TypeSize = +!BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; +Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); + } + // Fields can be subject to extra alignment constraints, like if // the field is packed, the struct is packed, or the struct has a // a max-field-alignment constraint (#pragma pack). So calculate diff --git a/clang/test/Driver/systemz-alignment.c b/clang/test/Driver/systemz-alignment.c new file mode 100644 index 000..6f3b2bc38be3688 --- /dev/null +++ b/clang/test/Driver/systemz-alignment.c @@ -0,0 +1,32 @@ +// RUN: %clang --target=s390x-linux -S -emit-llvm -o - %s | FileCheck %s +// +// Test that a global variable with an incomplete type gets the minimum +// alignment of 2 per the ABI if no alignment was specified by user. +// +// CHECK: @VarNoAl {{.*}} align 2 +// CHECK-NEXT: @VarExplAl1 {{.*}} align 1 +// CHECK-NEXT: @VarExplAl4 {{.*}} align 4 + +// No alignemnt specified by user. +struct incomplete_ty_noal; +extern struct incomplete_ty_noal VarNoAl; +struct incomplete_ty_noal *fun0 (void) +{ + return &VarNoAl; +} + +// User-specified alignment of 1. +struct incomplete_ty_al1; +extern struct incomplete_ty_al1 __attribute__((aligned(1))) VarExplAl1; +struct incomplete_ty_al1 *fun1 (void) +{ + return &VarExplAl1; +} + +// User-specified alignment of 4. +struct incomplete_ty_al4; +extern struct incomplete_ty_al4 __attribute__((aligned(4))) VarExplAl4; +struct incomplete_ty_al4 *fun2 (void) +{ + return &VarExplAl4; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/72977 @efriedma-quic @rjmccall While working on this (with the other patch: 72886), I found this refactoring at the top of the function which I like. What do you think? >From 90938183b35284cff65d100f3cb5284b816f28cc Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:10:03 +0100 Subject: [PATCH] Refactor ASTContext::getDeclAlign() (NFC) --- clang/lib/AST/ASTContext.cpp | 33 + 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1c893d008cb49f3..d08b9072c0e6298 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1627,28 +1627,21 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { unsigned Align = Target->getCharWidth(); - bool UseAlignAttrOnly = false; - if (unsigned AlignFromAttr = D->getMaxAlignment()) { + const unsigned AlignFromAttr = D->getMaxAlignment(); + if (AlignFromAttr) Align = AlignFromAttr; -// __attribute__((aligned)) can increase or decrease alignment -// *except* on a struct or struct member, where it only increases -// alignment unless 'packed' is also specified. -// -// It is an error for alignas to decrease alignment, so we can -// ignore that possibility; Sema should diagnose it. -if (isa(D)) { - UseAlignAttrOnly = D->hasAttr() || -cast(D)->getParent()->hasAttr(); -} else { - UseAlignAttrOnly = true; -} - } - else if (isa(D)) - UseAlignAttrOnly = -D->hasAttr() || -cast(D)->getParent()->hasAttr(); - + // __attribute__((aligned)) can increase or decrease alignment + // *except* on a struct or struct member, where it only increases + // alignment unless 'packed' is also specified. + // + // It is an error for alignas to decrease alignment, so we can + // ignore that possibility; Sema should diagnose it. + bool IsPackedField = isa(D) && + (D->hasAttr() || + cast(D)->getParent()->hasAttr()); + bool UseAlignAttrOnly = +isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/72977 >From 90938183b35284cff65d100f3cb5284b816f28cc Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:10:03 +0100 Subject: [PATCH 1/2] Refactor ASTContext::getDeclAlign() (NFC) --- clang/lib/AST/ASTContext.cpp | 33 + 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1c893d008cb49f3..d08b9072c0e6298 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1627,28 +1627,21 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { unsigned Align = Target->getCharWidth(); - bool UseAlignAttrOnly = false; - if (unsigned AlignFromAttr = D->getMaxAlignment()) { + const unsigned AlignFromAttr = D->getMaxAlignment(); + if (AlignFromAttr) Align = AlignFromAttr; -// __attribute__((aligned)) can increase or decrease alignment -// *except* on a struct or struct member, where it only increases -// alignment unless 'packed' is also specified. -// -// It is an error for alignas to decrease alignment, so we can -// ignore that possibility; Sema should diagnose it. -if (isa(D)) { - UseAlignAttrOnly = D->hasAttr() || -cast(D)->getParent()->hasAttr(); -} else { - UseAlignAttrOnly = true; -} - } - else if (isa(D)) - UseAlignAttrOnly = -D->hasAttr() || -cast(D)->getParent()->hasAttr(); - + // __attribute__((aligned)) can increase or decrease alignment + // *except* on a struct or struct member, where it only increases + // alignment unless 'packed' is also specified. + // + // It is an error for alignas to decrease alignment, so we can + // ignore that possibility; Sema should diagnose it. + bool IsPackedField = isa(D) && + (D->hasAttr() || + cast(D)->getParent()->hasAttr()); + bool UseAlignAttrOnly = +isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { >From 3a2b09bbdf533df9797f5d40ae1e027852400560 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:31:16 +0100 Subject: [PATCH 2/2] Reformat --- clang/lib/AST/ASTContext.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d08b9072c0e6298..50bb24631c118f4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1640,8 +1640,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { bool IsPackedField = isa(D) && (D->hasAttr() || cast(D)->getParent()->hasAttr()); - bool UseAlignAttrOnly = -isa(D) ? IsPackedField : AlignFromAttr; + bool UseAlignAttrOnly = isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Ensure minimal alignment of global vars of incomplete type. (PR #72886)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/72886 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/72977 >From 000dcadc0fd118df643e3f2ecbe5fcbb2f8eaab0 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:10:03 +0100 Subject: [PATCH 1/3] Refactor ASTContext::getDeclAlign() (NFC) --- clang/lib/AST/ASTContext.cpp | 33 + 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1c893d008cb49f31..d08b9072c0e62985 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1627,28 +1627,21 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { unsigned Align = Target->getCharWidth(); - bool UseAlignAttrOnly = false; - if (unsigned AlignFromAttr = D->getMaxAlignment()) { + const unsigned AlignFromAttr = D->getMaxAlignment(); + if (AlignFromAttr) Align = AlignFromAttr; -// __attribute__((aligned)) can increase or decrease alignment -// *except* on a struct or struct member, where it only increases -// alignment unless 'packed' is also specified. -// -// It is an error for alignas to decrease alignment, so we can -// ignore that possibility; Sema should diagnose it. -if (isa(D)) { - UseAlignAttrOnly = D->hasAttr() || -cast(D)->getParent()->hasAttr(); -} else { - UseAlignAttrOnly = true; -} - } - else if (isa(D)) - UseAlignAttrOnly = -D->hasAttr() || -cast(D)->getParent()->hasAttr(); - + // __attribute__((aligned)) can increase or decrease alignment + // *except* on a struct or struct member, where it only increases + // alignment unless 'packed' is also specified. + // + // It is an error for alignas to decrease alignment, so we can + // ignore that possibility; Sema should diagnose it. + bool IsPackedField = isa(D) && + (D->hasAttr() || + cast(D)->getParent()->hasAttr()); + bool UseAlignAttrOnly = +isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { >From c79760665730a0f2eb70fb86a9d1a7667033c25d Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:31:16 +0100 Subject: [PATCH 2/3] Reformat --- clang/lib/AST/ASTContext.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d08b9072c0e62985..50bb24631c118f4b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1640,8 +1640,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { bool IsPackedField = isa(D) && (D->hasAttr() || cast(D)->getParent()->hasAttr()); - bool UseAlignAttrOnly = -isa(D) ? IsPackedField : AlignFromAttr; + bool UseAlignAttrOnly = isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { >From b688dc79c00b86bccc695507f77868e1721e64a0 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Wed, 22 Nov 2023 11:42:35 +0100 Subject: [PATCH 3/3] Use Eli's version instead --- clang/lib/AST/ASTContext.cpp | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 50bb24631c118f4b..454f07b4303e0632 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1637,10 +1637,12 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { // // It is an error for alignas to decrease alignment, so we can // ignore that possibility; Sema should diagnose it. - bool IsPackedField = isa(D) && - (D->hasAttr() || - cast(D)->getParent()->hasAttr()); - bool UseAlignAttrOnly = isa(D) ? IsPackedField : AlignFromAttr; + bool UseAlignAttrOnly; + if (FieldDecl *FD = dyn_cast(D)) +UseAlignAttrOnly = +FD->hasAttr() || FD->getParent()->hasAttr(); + else +UseAlignAttrOnly = AlignFromAttr != 0; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
@@ -1627,28 +1627,20 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { unsigned Align = Target->getCharWidth(); - bool UseAlignAttrOnly = false; - if (unsigned AlignFromAttr = D->getMaxAlignment()) { + const unsigned AlignFromAttr = D->getMaxAlignment(); + if (AlignFromAttr) Align = AlignFromAttr; -// __attribute__((aligned)) can increase or decrease alignment -// *except* on a struct or struct member, where it only increases -// alignment unless 'packed' is also specified. -// -// It is an error for alignas to decrease alignment, so we can -// ignore that possibility; Sema should diagnose it. -if (isa(D)) { - UseAlignAttrOnly = D->hasAttr() || -cast(D)->getParent()->hasAttr(); -} else { - UseAlignAttrOnly = true; -} - } - else if (isa(D)) - UseAlignAttrOnly = -D->hasAttr() || -cast(D)->getParent()->hasAttr(); - + // __attribute__((aligned)) can increase or decrease alignment + // *except* on a struct or struct member, where it only increases + // alignment unless 'packed' is also specified. + // + // It is an error for alignas to decrease alignment, so we can + // ignore that possibility; Sema should diagnose it. + bool IsPackedField = isa(D) && + (D->hasAttr() || + cast(D)->getParent()->hasAttr()); + bool UseAlignAttrOnly = isa(D) ? IsPackedField : AlignFromAttr; JonPsson1 wrote: That works for me as well: main problem to me with the original code was the duplicated handling of a FieldDecl. I took your suggestion, but removed the braces, which seem superfluous? Or are they required by the coding standard? https://github.com/llvm/llvm-project/pull/72977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Ensure minimal alignment of global vars of incomplete type. (PR #72886)
@@ -0,0 +1,32 @@ +// RUN: %clang --target=s390x-linux -S -emit-llvm -o - %s | FileCheck %s JonPsson1 wrote: I found some other align tests there, like arm-alignment.c, so I thought this should work..? https://github.com/llvm/llvm-project/pull/72886 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/72977 >From 000dcadc0fd118df643e3f2ecbe5fcbb2f8eaab0 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:10:03 +0100 Subject: [PATCH 1/4] Refactor ASTContext::getDeclAlign() (NFC) --- clang/lib/AST/ASTContext.cpp | 33 + 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1c893d008cb49f31..d08b9072c0e62985 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1627,28 +1627,21 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { unsigned Align = Target->getCharWidth(); - bool UseAlignAttrOnly = false; - if (unsigned AlignFromAttr = D->getMaxAlignment()) { + const unsigned AlignFromAttr = D->getMaxAlignment(); + if (AlignFromAttr) Align = AlignFromAttr; -// __attribute__((aligned)) can increase or decrease alignment -// *except* on a struct or struct member, where it only increases -// alignment unless 'packed' is also specified. -// -// It is an error for alignas to decrease alignment, so we can -// ignore that possibility; Sema should diagnose it. -if (isa(D)) { - UseAlignAttrOnly = D->hasAttr() || -cast(D)->getParent()->hasAttr(); -} else { - UseAlignAttrOnly = true; -} - } - else if (isa(D)) - UseAlignAttrOnly = -D->hasAttr() || -cast(D)->getParent()->hasAttr(); - + // __attribute__((aligned)) can increase or decrease alignment + // *except* on a struct or struct member, where it only increases + // alignment unless 'packed' is also specified. + // + // It is an error for alignas to decrease alignment, so we can + // ignore that possibility; Sema should diagnose it. + bool IsPackedField = isa(D) && + (D->hasAttr() || + cast(D)->getParent()->hasAttr()); + bool UseAlignAttrOnly = +isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { >From c79760665730a0f2eb70fb86a9d1a7667033c25d Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 21 Nov 2023 12:31:16 +0100 Subject: [PATCH 2/4] Reformat --- clang/lib/AST/ASTContext.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d08b9072c0e62985..50bb24631c118f4b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1640,8 +1640,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { bool IsPackedField = isa(D) && (D->hasAttr() || cast(D)->getParent()->hasAttr()); - bool UseAlignAttrOnly = -isa(D) ? IsPackedField : AlignFromAttr; + bool UseAlignAttrOnly = isa(D) ? IsPackedField : AlignFromAttr; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { >From b688dc79c00b86bccc695507f77868e1721e64a0 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Wed, 22 Nov 2023 11:42:35 +0100 Subject: [PATCH 3/4] Use Eli's version instead --- clang/lib/AST/ASTContext.cpp | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 50bb24631c118f4b..454f07b4303e0632 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1637,10 +1637,12 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { // // It is an error for alignas to decrease alignment, so we can // ignore that possibility; Sema should diagnose it. - bool IsPackedField = isa(D) && - (D->hasAttr() || - cast(D)->getParent()->hasAttr()); - bool UseAlignAttrOnly = isa(D) ? IsPackedField : AlignFromAttr; + bool UseAlignAttrOnly; + if (FieldDecl *FD = dyn_cast(D)) +UseAlignAttrOnly = +FD->hasAttr() || FD->getParent()->hasAttr(); + else +UseAlignAttrOnly = AlignFromAttr != 0; // If we're using the align attribute only, just ignore everything // else about the declaration and its type. if (UseAlignAttrOnly) { >From 8078141fd797b40baf1e097a8d48a6294abf49c7 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Wed, 22 Nov 2023 12:35:45 +0100 Subject: [PATCH 4/4] Add needed const --- clang/lib/AST/ASTContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 454f07b4303e0632..3d9331c6a859acfa 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1638,7 +1638,7 @@ CharUnits ASTContext::getDeclA
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/73134 - Clang FE now has MaxAtomicPromoteWidth and MaxAtomicInlineWidth with a value of 128. It now produces IR instead of calls to __atomic instrinsics for 16 bytes as well. FP loads are first loaded as i128 and then casted to fp128. - Atomic __int128 (and long double) variables are aligned to 16 bytes (like gcc 14). - AtomicExpand pass now expands also 16 byte operations. - tests for __atomic builtins for all integer widths, with test for i128 in both align=8 and align=16 cases. - Resulting behavior of __atomic_is_lock_free / __atomic_always_lock_free / __c11_atomic_is_lock_free is tested in gnu-atomic_is_lock_free.c - shouldExpandAtomicRMWInIR() was already returning true for any FP type. Now that the backend is acepting 16 byte atomics, 16 byte FP atomicrmw:s now also get expanded by AtomicExpand. The default (and used) shouldCastAtomicRMWIInIR() says that if the type is FP, it is casted to integer (see atomicrmw-xchg-07.ll). - TODO: AtomicExpand pass handles with this patch expansion of i128 atomicrmw:s. As a next step smaller integer types should also be possible to handle this way instead of in backend. Original patch rebased. Remove the regalloc handling for CDSG loops. Tests improved. >From e392e34f1c6762cce079e26c90e9d27a868bc5f2 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Fri, 3 Feb 2023 14:32:58 +0100 Subject: [PATCH] [SystemZ] Improve support for 16 byte atomic int/fp types and operations. - Clang FE now has MaxAtomicPromoteWidth and MaxAtomicInlineWidth with a value of 128. It now produces IR instead of calls to __atomic instrinsics for 16 bytes as well. FP loads are first loaded as i128 and then casted to fp128. - Atomic __int128 (and long double) variables are aligned to 16 bytes (like gcc 14). - AtomicExpand pass now expands also 16 byte operations. - tests for __atomic builtins for all integer widths, with test for i128 in both align=8 and align=16 cases. - Resulting behavior of __atomic_is_lock_free / __atomic_always_lock_free / __c11_atomic_is_lock_free is tested in gnu-atomic_is_lock_free.c - shouldExpandAtomicRMWInIR() was already returning true for any FP type. Now that the backend is acepting 16 byte atomics, 16 byte FP atomicrmw:s now also get expanded by AtomicExpand. The default (and used) shouldCastAtomicRMWIInIR() says that if the type is FP, it is casted to integer (see atomicrmw-xchg-07.ll). - TODO: AtomicExpand pass handles with this patch expansion of i128 atomicrmw:s. As a next step smaller integer types should also be possible to handle this way instead of in backend. Original patch rebased. Remove the regalloc handling for CDSG loops. Tests improved. --- clang/lib/Basic/Targets/SystemZ.h | 2 +- clang/test/CodeGen/SystemZ/atomic-alignment.c | 35 ++ .../SystemZ/gnu-atomic-builtins-i128-16Al.c | 257 + .../SystemZ/gnu-atomic-builtins-i128-8Al.c| 301 +++ .../CodeGen/SystemZ/gnu-atomic-builtins-i16.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i32.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i64.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i8.c | 219 .../CodeGen/SystemZ/gnu-atomic_is_lock_free.c | 71 +++ .../Target/SystemZ/SystemZISelLowering.cpp| 6 +- .../CodeGen/SystemZ/atomicrmw-ops-i128.ll | 496 -- .../test/CodeGen/SystemZ/atomicrmw-xchg-07.ll | 37 +- 12 files changed, 2019 insertions(+), 62 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/atomic-alignment.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i16.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i32.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i64.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i8.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free.c diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 9ba255745cf2cc52..e4ec338880f21095 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -60,7 +60,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" "-v128:64-a:8:16-n32:64"); } -MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; +MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; HasStrictFP = true; } diff --git a/clang/test/CodeGen/SystemZ/atomic-alignment.c b/clang/test/CodeGen/SystemZ/atomic-alignment.c new file mode 100644 index ..da478842ca31b2b0 --- /dev/null +++ b/clang/test/CodeGen/SystemZ/atomic-alignment.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple s390x-linux-gn
[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
@@ -1183,6 +1187,35 @@ void SystemZDAGToDAGISel::loadVectorConstant( SelectCode(Op.getNode()); } +SDNode *SystemZDAGToDAGISel::loadPoolVectorConstant(APInt Val, EVT VT, SDLoc DL) { + SDNode *ResNode; + assert (VT.getSizeInBits() == 128); + + SDValue CP = CurDAG->getTargetConstantPool( + ConstantInt::get(Type::getInt128Ty(*CurDAG->getContext()), Val), + TLI->getPointerTy(CurDAG->getDataLayout())); + + EVT PtrVT = CP.getValueType(); + SDValue Ops[] = { +SDValue(CurDAG->getMachineNode(SystemZ::LARL, DL, PtrVT, CP), 0), +CurDAG->getTargetConstant(0, DL, PtrVT), +CurDAG->getRegister(0, PtrVT), +CurDAG->getEntryNode() + }; + ResNode = CurDAG->getMachineNode(SystemZ::VL, DL, VT, MVT::Other, Ops); + + // Annotate ResNode with memory operand information so that MachineInstr + // queries work properly. This e.g. gives the register allocation the + // required information for rematerialization. + MachineFunction& MF = CurDAG->getMachineFunction(); + MachineMemOperand *MemOp = + MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), + MachineMemOperand::MOLoad, 8, Align(8)); + JonPsson1 wrote: I think the third argument is the size in bytes, and it should be 16. https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
@@ -1466,7 +1509,15 @@ static SDValue convertValVTToLocVT(SelectionDAG &DAG, const SDLoc &DL, static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In) { SDLoc DL(In); SDValue Lo, Hi; - std::tie(Lo, Hi) = DAG.SplitScalar(In, DL, MVT::i64, MVT::i64); + if (DAG.getTargetLoweringInfo().isTypeLegal(MVT::i128)) { +Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64, In); JonPsson1 wrote: All tests pass even if I remove this entire clause...? https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
@@ -2772,6 +2837,27 @@ static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, // Update the arguments with the TM version if so. static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C) { + // Use VECTOR TEST UNDER MASK for i128 operations. + if (C.Op0.getValueType() == MVT::i128) { JonPsson1 wrote: Beneficial? VTM is 3 cycles, while VN + VCEQ = 2... https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
@@ -2918,16 +3049,17 @@ static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, bool IsSignaling = false) { if (CmpOp1.getOpcode() == ISD::Constant) { assert(!Chain); -uint64_t Constant = cast(CmpOp1)->getZExtValue(); unsigned Opcode, CCValid; JonPsson1 wrote: Was 'Constant = ...' removed on purpose? (I would think that normally it would be factored out like it was, but maybe doesn't matter) https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
@@ -6481,6 +6737,71 @@ SDValue SystemZTargetLowering::combineLOAD( SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; EVT LdVT = N->getValueType(0); + SDLoc DL(N); + + // Replace an i128 load that is used solely to move its value into GPRs + // by separate loads of both halves. + if (LdVT == MVT::i128) { +LoadSDNode *LD = cast(N); +if (!LD->isSimple() || !ISD::isNormalLoad(LD)) + return SDValue(); + +// Scan through all users. +SmallVector, 2> Users; +int UsedElements = 0; +for (SDNode::use_iterator UI = LD->use_begin(), UIEnd = LD->use_end(); + UI != UIEnd; ++UI) { + // Skip the uses of the chain. + if (UI.getUse().getResNo() != 0) +continue; + + // Verify every user is a TRUNCATE to i64 of the low or high half ... + SDNode *User = *UI; + int Index = 1; + if (User->getOpcode() == ISD::SRL && + User->getOperand(1).getOpcode() == ISD::Constant && + cast(User->getOperand(1))->getZExtValue() == 64 && + User->hasOneUse()) { +User = *User->use_begin(); +Index = 0; + } + if (User->getOpcode() != ISD::TRUNCATE || + User->getValueType(0) != MVT::i64) +return SDValue(); + + // ... and no half is extracted twice. + if (UsedElements & (1 << Index)) +return SDValue(); + + UsedElements |= 1 << Index; + Users.push_back(std::make_pair(User, Index)); +} + +// Rewrite each extraction as an independent load. +SmallVector ArgChains; +for (auto UserAndIndex : Users) { + SDNode *User = UserAndIndex.first; + unsigned Offset = User->getValueType(0).getStoreSize() * UserAndIndex.second; + SDValue Ptr = JonPsson1 wrote: Offset = 8 * ... ? https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SystemZ] Support i128 as legal type in VRs (PR #74625)
@@ -1516,48 +1536,206 @@ let Predicates = [FeatureVector] in { } } +//===--===// +// Support for 128-bit integer values in vector registers +//===--===// + +// Loads and stores. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (load bdxaddr12only:$addr)), +(VL bdxaddr12only:$addr)>; + def : Pat<(store (i128 VR128:$src), bdxaddr12only:$addr), +(VST VR128:$src, bdxaddr12only:$addr)>; +} + +// Full i128 move from GPR pair. +let Predicates = [FeatureVector] in + def : Pat<(i128 (or (zext GR64:$x), (shl (anyext GR64:$y), (i32 64, +(VLVGP GR64:$y, GR64:$x)>; + +// Any-extensions from GPR to i128. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (anyext GR32:$x)), (VLVGP32 GR32:$x, GR32:$x)>; + def : Pat<(i128 (anyext GR64:$x)), (VLVGP GR64:$x, GR64:$x)>; +} + +// Any-extending loads into i128. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (extloadi8 bdxaddr12only:$addr)), +(VLREPB bdxaddr12only:$addr)>; + def : Pat<(i128 (extloadi16 bdxaddr12only:$addr)), +(VLREPH bdxaddr12only:$addr)>; + def : Pat<(i128 (extloadi32 bdxaddr12only:$addr)), +(VLREPF bdxaddr12only:$addr)>; + def : Pat<(i128 (extloadi64 bdxaddr12only:$addr)), +(VLREPG bdxaddr12only:$addr)>; +} + +// Truncations from i128 to GPR. +let Predicates = [FeatureVector] in { + def : Pat<(i32 (trunc (i128 VR128:$vec))), +(EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 3), subreg_l32)>; + def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 32, +(EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 2), subreg_l32)>; + def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 64, +(EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 1), subreg_l32)>; + def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 96, +(EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 0), subreg_l32)>; + def : Pat<(i64 (trunc (i128 VR128:$vec))), +(VLGVG VR128:$vec, zero_reg, 1)>; + def : Pat<(i64 (trunc (srl (i128 VR128:$vec), (i32 64, +(VLGVG VR128:$vec, zero_reg, 0)>; +} + +// Truncating stores from i128. +let Predicates = [FeatureVector] in { + def : Pat<(truncstorei8 (i128 VR128:$x), bdxaddr12only:$addr), +(VSTEB VR128:$x, bdxaddr12only:$addr, 15)>; + def : Pat<(truncstorei16 (i128 VR128:$x), bdxaddr12only:$addr), +(VSTEH VR128:$x, bdxaddr12only:$addr, 7)>; + def : Pat<(truncstorei32 (i128 VR128:$x), bdxaddr12only:$addr), +(VSTEF VR128:$x, bdxaddr12only:$addr, 3)>; + def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 32)), bdxaddr12only:$addr), +(VSTEF VR128:$x, bdxaddr12only:$addr, 2)>; + def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 64)), bdxaddr12only:$addr), +(VSTEF VR128:$x, bdxaddr12only:$addr, 1)>; + def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 96)), bdxaddr12only:$addr), +(VSTEF VR128:$x, bdxaddr12only:$addr, 0)>; + def : Pat<(truncstorei64 (i128 VR128:$x), bdxaddr12only:$addr), +(VSTEG VR128:$x, bdxaddr12only:$addr, 1)>; + def : Pat<(truncstorei64 (srl (i128 VR128:$x), (i32 64)), bdxaddr12only:$addr), +(VSTEG VR128:$x, bdxaddr12only:$addr, 0)>; +} + +// Zero-extensions from GPR to i128. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (zext8 (anyext GR32:$x))), +(VLVGB (VGBM 0), GR32:$x, zero_reg, 15)>; + def : Pat<(i128 (zext16 (anyext GR32:$x))), +(VLVGH (VGBM 0), GR32:$x, zero_reg, 7)>; + def : Pat<(i128 (zext GR32:$x)), +(VLVGF (VGBM 0), GR32:$x, zero_reg, 3)>; + def : Pat<(i128 (zext GR64:$x)), +(VLVGG (VGBM 0), GR64:$x, zero_reg, 1)>; +} + +// Zero-extending loads into i128. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (zextloadi8 bdxaddr12only:$addr)), +(VLEB (VGBM 0), bdxaddr12only:$addr, 15)>; + def : Pat<(i128 (zextloadi16 bdxaddr12only:$addr)), +(VLEH (VGBM 0), bdxaddr12only:$addr, 7)>; + def : Pat<(i128 (zextloadi32 bdxaddr12only:$addr)), +(VLEF (VGBM 0), bdxaddr12only:$addr, 3)>; + def : Pat<(i128 (zextloadi64 bdxaddr12only:$addr)), +(VLEG (VGBM 0), bdxaddr12only:$addr, 1)>; +} + +// In-register i128 sign-extensions. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (sext_inreg VR128:$x, i8)), +(VSRAB (VREPB VR128:$x, 15), (VREPIB 120))>; + def : Pat<(i128 (sext_inreg VR128:$x, i16)), +(VSRAB (VREPH VR128:$x, 7), (VREPIB 112))>; + def : Pat<(i128 (sext_inreg VR128:$x, i32)), +(VSRAB (VREPF VR128:$x, 3), (VREPIB 96))>; + def : Pat<(i128 (sext_inreg VR128:$x, i64)), +(VSRAB (VREPG VR128:$x, 1), (VREPIB 64))>; +} + +// Sign-extensions from GPR to i128. +let Predicates = [FeatureVector] in { + def : Pat<(i128 (sext_inreg (anyext
[clang] [llvm] [SystemZ] Support i128 as legal type in VRs (PR #74625)
JonPsson1 wrote: I have looked through the changes and made some comments inline. I built this with expensive checks enabled with all checks passing, and SPEC built successfully. Commenting: ``` @@ -293,7 +293,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, Custom); setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Custom); - // Even though i128 is not a legal type, we still need to custom lower + // Even though i128 is not a legal type, we still need to custom lower **// Update comment** @@ -2144,7 +2145,7 @@ CanLowerReturn(CallingConv::ID CallConv, VerifyVectorTypes(Outs); // Special case that we cannot easily detect in RetCC_SystemZ since - // i128 is not a legal type. + // i128 is not a legal type. **// Update comment** +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td @@ -124,7 +124,7 @@ defm GRX32 : SystemZRegClass<"GRX32", [i32], 32, R12L,R12H,R13L,R13H,R14L,R14H,R15L,R15H) ]>; -// The architecture doesn't really have any i128 support, so model the +// The architecture doesn't really have any i128 support, so model the **// Update comment** ``` I happened to notice some cases with room for improvement: ``` ; Scalar load + insertion + replication could be just a vlrepb. define i128 @fun0(i128 %a, i128 %sh) { ; CHECK-LABEL: fun0: ; CHECK: # %bb.0: ; CHECK-NEXT:l %r0, 12(%r4) // ; CHECK-NEXT:vlvgp %v1, %r0, %r0 // ; CHECK-NEXT:vl %v0, 0(%r3), 3 ; CHECK-NEXT:vrepb %v1, %v1, 15 // ===> vlrepb %v1, 12(%r4) ? ; CHECK-NEXT:vslb %v0, %v0, %v1 ; CHECK-NEXT:vsl %v0, %v0, %v1 ; CHECK-NEXT:vst %v0, 0(%r2), 3 ; CHECK-NEXT:br %r14 %res = shl i128 %a, %sh ret i128 %res } ; %v1 is the shift amount in a VR already. define i128 @fun1(i128 %a, i128 %sh, i128 %t) { ; CHECK-LABEL: fun1: ; CHECK: # %bb.0: ; CHECK-NEXT:vl %v1, 0(%r5), 3 ; CHECK-NEXT:vl %v2, 0(%r4), 3 ; CHECK-NEXT:vaq %v1, %v2, %v1 ; CHECK-NEXT:vlgvf %r0, %v1, 3 // ; CHECK-NEXT:vlvgp %v1, %r0, %r0 // ; CHECK-NEXT:vl %v0, 0(%r3), 3 ; CHECK-NEXT:vrepb %v1, %v1, 15// ===> vrepb %v1, %v1, 15 ; CHECK-NEXT:vslb %v0, %v0, %v1 ; CHECK-NEXT:vsl %v0, %v0, %v1 ; CHECK-NEXT:vst %v0, 0(%r2), 3 ; CHECK-NEXT:br %r14 %s = add i128 %sh, %t %res = shl i128 %a, %s ret i128 %res } ``` As a side question: I forgot why we can get CCMask '5' here: it seems it should be CCMASK_CMP_NE ('6'), if we reverse the LOC operation..? ``` VTM killed %5:vr128bit, killed %4:vr128bit, implicit-def $cc %6:gr64bit = LOCGR killed %3:gr64bit(tied-def 0), killed %2:gr64bit, 13, 8, implicit killed $cc # *** IR Dump After Two-Address instruction pass (twoaddressinstruction) ***: (SystemZInstrInfo::commuteInstructionImpl) VTM killed %5:vr128bit, killed %4:vr128bit, implicit-def $cc %6:gr64bit = COPY killed %2:gr64bit %6:gr64bit = LOCGR %6:gr64bit(tied-def 0), killed %3:gr64bit, 13, 5, implicit killed $cc ``` https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SystemZ] Support i128 as legal type in VRs (PR #74625)
JonPsson1 wrote: Thanks for explanations. Updates to my comments LGTM. https://github.com/llvm/llvm-project/pull/74625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73511 >From de673830f94a519c94874516f4da24705b736b2e Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 17:22:32 +0100 Subject: [PATCH 1/2] IP --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/Basic/TargetInfo.h| 7 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ASTContext.cpp | 15 ++- clang/lib/Basic/Targets/AArch64.cpp | 5 +- clang/lib/Basic/Targets/AArch64.h | 2 +- clang/lib/Basic/Targets/CSKY.cpp | 2 +- clang/lib/Basic/Targets/CSKY.h| 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 3 +- clang/lib/Basic/Targets/SPIR.h| 3 +- clang/lib/Basic/Targets/SystemZ.cpp | 10 ++ clang/lib/Basic/Targets/SystemZ.h | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp | 8 ++ clang/lib/Sema/SemaOpenMP.cpp | 3 +- .../test/CodeGen/SystemZ/unaligned-symbols.c | 104 ++ llvm/lib/Target/SystemZ/SystemZFeatures.td| 5 + 17 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/unaligned-symbols.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043f..9e60ca8fb2ea8c6 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase { /// Return the alignment in bits that should be given to a /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + unsigned getAlignOfGlobalVar(QualType T, bool HasDef) const; /// Return the alignment in characters that should be given to a /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + CharUnits getAlignOfGlobalVarInChars(QualType T, bool HasDef) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index aa0f5023104a1a9..ace9e89eda5869b 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -704,8 +704,11 @@ class TargetInfo : public TransferrableTargetInfo, } /// getMinGlobalAlign - Return the minimum alignment of a global variable, - /// unless its alignment is explicitly reduced via attributes. - virtual unsigned getMinGlobalAlign (uint64_t) const { + /// unless its alignment is explicitly reduced via attributes. It may be + /// that an external symbol needs to be considered unaligned (like + /// artificial symbols created from a linker script). If \param HasDef is + /// false, this symbol does not have a definition and is external. + virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasDef) const { return MinGlobalAlign; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1b02087425b7515..dbfb7580db75355 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4587,6 +4587,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">; +def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; +def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; } // let Flags = [TargetSpecific] def mstrict_align : Flag<["-"], "mstrict-align">, Alias, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0395b3e47ab6f8f..ff15206cbe88621 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1681,7 +1681,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = std::max(Align, getTargetInfo().getMinGlobalAlign( +TypeSize, VD->hasDefinition())); } // Fields can be subject to extra alignment constraints, like if @@ -2502,17 +2503,19 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
JonPsson1 wrote: Patch updated to handle weak symbols as well, by passing the VarDecl to getMinGlobalAlign() so that the SystemZ implementation of it can inspect the VD. Clang builds fine and it seems to be working, but I however find that the tests don't build anymore and not sure exactly what is the best way forward here. I get: ``` ninja check-clang [2/201] Linking CXX executable tools/clang/unittests/Basic/BasicTests FAILED: tools/clang/unittests/Basic/BasicTests : && /home/ijonpan/gcc-latest/bin/g++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -fno-strict-aliasing -O3 -DNDEBUG -Wl,--gc-sections tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/CharInfoTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/DarwinSDKInfoTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/DiagnosticTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/FileEntryTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/FileManagerTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/LineOffsetMappingTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/SanitizersTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/SarifTest.cpp.o tools/clang/unittests/Basic/CMakeFiles/BasicTests.dir/SourceManagerTest.cpp.o -o tools/clang/unittests/Basic/BasicTests lib/libLLVMSupport.a lib/libLLVMSupport.a lib/libllvm_gtest_main.a lib/libllvm_gtest.a lib/libclangBasic.a lib/libclangLex.a lib/libLLVMTestingSupport.a lib/libclangBasic.a lib/libLLVMFrontendOpenMP.a lib/libLLVMScalarOpts.a lib/libLLVMAggressiveInstCombine.a lib/libLLVMInstCombine.a lib/libLLVMFrontendOffloading.a lib/libLLVMTransformUtils.a lib/libLLVMAnalysis.a lib/libLLVMProfileData.a lib/libLLVMSymbolize.a lib/libLLVMDebugInfoPDB.a lib/libLLVMDebugInfoMSF.a lib/libLLVMDebugInfoBTF.a lib/libLLVMDebugInfoDWARF.a lib/libLLVMObject.a lib/libLLVMIRReader.a lib/libLLVMBitReader.a lib/libLLVMAsmParser.a lib/libLLVMCore.a lib/libLLVMRemarks.a lib/libLLVMBitstreamReader.a lib/libLLVMMCParser.a lib/libLLVMMC.a lib/libLLVMDebugInfoCodeView.a lib/libLLVMTextAPI.a lib/libLLVMBinaryFormat.a lib/libLLVMTargetParser.a lib/libllvm_gtest.a lib/libLLVMSupport.a -lrt -ldl -lm /usr/lib64/libz.so /usr/lib64/libzstd.so /usr/lib64/libtinfo.so lib/libLLVMDemangle.a -lpthread && : /usr/bin/ld: lib/libclangBasic.a(SystemZ.cpp.o): in function `clang::targets::SystemZTargetInfo::getMinGlobalAlign(unsigned long, clang::VarDecl const*) const': SystemZ.cpp:(.text._ZNK5clang7targets17SystemZTargetInfo17getMinGlobalAlignEmPKNS_7VarDeclE+0x28): undefined reference to `clang::Decl::getASTContext() const' /usr/bin/ld: SystemZ.cpp:(.text._ZNK5clang7targets17SystemZTargetInfo17getMinGlobalAlignEmPKNS_7VarDeclE+0x36): undefined reference to `clang::VarDecl::hasDefinition(clang::ASTContext&) const' /usr/bin/ld: SystemZ.cpp:(.text._ZNK5clang7targets17SystemZTargetInfo17getMinGlobalAlignEmPKNS_7VarDeclE+0x5e): undefined reference to `clang::ValueDecl::isWeak() const' collect2: error: ld returned 1 exit status ``` https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73511 >From de673830f94a519c94874516f4da24705b736b2e Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 17:22:32 +0100 Subject: [PATCH 1/3] IP --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/Basic/TargetInfo.h| 7 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ASTContext.cpp | 15 ++- clang/lib/Basic/Targets/AArch64.cpp | 5 +- clang/lib/Basic/Targets/AArch64.h | 2 +- clang/lib/Basic/Targets/CSKY.cpp | 2 +- clang/lib/Basic/Targets/CSKY.h| 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 3 +- clang/lib/Basic/Targets/SPIR.h| 3 +- clang/lib/Basic/Targets/SystemZ.cpp | 10 ++ clang/lib/Basic/Targets/SystemZ.h | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp | 8 ++ clang/lib/Sema/SemaOpenMP.cpp | 3 +- .../test/CodeGen/SystemZ/unaligned-symbols.c | 104 ++ llvm/lib/Target/SystemZ/SystemZFeatures.td| 5 + 17 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/unaligned-symbols.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043..9e60ca8fb2ea8c 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase { /// Return the alignment in bits that should be given to a /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + unsigned getAlignOfGlobalVar(QualType T, bool HasDef) const; /// Return the alignment in characters that should be given to a /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + CharUnits getAlignOfGlobalVarInChars(QualType T, bool HasDef) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index aa0f5023104a1a..ace9e89eda5869 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -704,8 +704,11 @@ class TargetInfo : public TransferrableTargetInfo, } /// getMinGlobalAlign - Return the minimum alignment of a global variable, - /// unless its alignment is explicitly reduced via attributes. - virtual unsigned getMinGlobalAlign (uint64_t) const { + /// unless its alignment is explicitly reduced via attributes. It may be + /// that an external symbol needs to be considered unaligned (like + /// artificial symbols created from a linker script). If \param HasDef is + /// false, this symbol does not have a definition and is external. + virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasDef) const { return MinGlobalAlign; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1b02087425b751..dbfb7580db7535 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4587,6 +4587,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">; +def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; +def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; } // let Flags = [TargetSpecific] def mstrict_align : Flag<["-"], "mstrict-align">, Alias, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0395b3e47ab6f8..ff15206cbe8862 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1681,7 +1681,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = std::max(Align, getTargetInfo().getMinGlobalAlign( +TypeSize, VD->hasDefinition())); } // Fields can be subject to extra alignment constraints, like if @@ -2502,17 +2503,19 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const { } ///
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73511 >From de673830f94a519c94874516f4da24705b736b2e Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 17:22:32 +0100 Subject: [PATCH 1/4] IP --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/Basic/TargetInfo.h| 7 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ASTContext.cpp | 15 ++- clang/lib/Basic/Targets/AArch64.cpp | 5 +- clang/lib/Basic/Targets/AArch64.h | 2 +- clang/lib/Basic/Targets/CSKY.cpp | 2 +- clang/lib/Basic/Targets/CSKY.h| 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 3 +- clang/lib/Basic/Targets/SPIR.h| 3 +- clang/lib/Basic/Targets/SystemZ.cpp | 10 ++ clang/lib/Basic/Targets/SystemZ.h | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp | 8 ++ clang/lib/Sema/SemaOpenMP.cpp | 3 +- .../test/CodeGen/SystemZ/unaligned-symbols.c | 104 ++ llvm/lib/Target/SystemZ/SystemZFeatures.td| 5 + 17 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/unaligned-symbols.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043..9e60ca8fb2ea8c 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase { /// Return the alignment in bits that should be given to a /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + unsigned getAlignOfGlobalVar(QualType T, bool HasDef) const; /// Return the alignment in characters that should be given to a /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + CharUnits getAlignOfGlobalVarInChars(QualType T, bool HasDef) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index aa0f5023104a1a..ace9e89eda5869 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -704,8 +704,11 @@ class TargetInfo : public TransferrableTargetInfo, } /// getMinGlobalAlign - Return the minimum alignment of a global variable, - /// unless its alignment is explicitly reduced via attributes. - virtual unsigned getMinGlobalAlign (uint64_t) const { + /// unless its alignment is explicitly reduced via attributes. It may be + /// that an external symbol needs to be considered unaligned (like + /// artificial symbols created from a linker script). If \param HasDef is + /// false, this symbol does not have a definition and is external. + virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasDef) const { return MinGlobalAlign; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1b02087425b751..dbfb7580db7535 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4587,6 +4587,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">; +def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; +def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; } // let Flags = [TargetSpecific] def mstrict_align : Flag<["-"], "mstrict-align">, Alias, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0395b3e47ab6f8..ff15206cbe8862 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1681,7 +1681,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = std::max(Align, getTargetInfo().getMinGlobalAlign( +TypeSize, VD->hasDefinition())); } // Fields can be subject to extra alignment constraints, like if @@ -2502,17 +2503,19 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const { } ///
[clang] [SystemZ] Move new test into existing CodeGen test. (PR #73230)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/73230 The test for emitted alignments is better placed in CodeGen. >From 72e252610893f919d25916b800d2afd1f8b0b9a4 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 12:33:11 +0100 Subject: [PATCH] [SystemZ] Move new test into existing CodeGen test. --- clang/test/CodeGen/SystemZ/align-systemz.c | 13 + clang/test/Driver/systemz-alignment.c | 32 -- 2 files changed, 13 insertions(+), 32 deletions(-) delete mode 100644 clang/test/Driver/systemz-alignment.c diff --git a/clang/test/CodeGen/SystemZ/align-systemz.c b/clang/test/CodeGen/SystemZ/align-systemz.c index 5ba446665fef803..9daff6ee9760974 100644 --- a/clang/test/CodeGen/SystemZ/align-systemz.c +++ b/clang/test/CodeGen/SystemZ/align-systemz.c @@ -25,6 +25,19 @@ void func (void) s = es; } +// Test that a global variable with an incomplete type gets the minimum +// alignment of 2 per the ABI if no alignment was specified by user. +// +// CHECK-DAG: @VarNoAl {{.*}} align 2 +// CHECK-DAG: @VarExplAl1 {{.*}} align 1 +// CHECK-DAG: @VarExplAl4 {{.*}} align 4 +struct incomplete_ty; +extern struct incomplete_ty VarNoAl; +extern struct incomplete_ty __attribute__((aligned(1))) VarExplAl1; +extern struct incomplete_ty __attribute__((aligned(4))) VarExplAl4; +struct incomplete_ty *fun0 (void) { return &VarNoAl; } +struct incomplete_ty *fun1 (void) { return &VarExplAl1; } +struct incomplete_ty *fun2 (void) { return &VarExplAl4; } // The SystemZ ABI aligns __int128_t to only eight bytes. diff --git a/clang/test/Driver/systemz-alignment.c b/clang/test/Driver/systemz-alignment.c deleted file mode 100644 index 6f3b2bc38be3688..000 --- a/clang/test/Driver/systemz-alignment.c +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang --target=s390x-linux -S -emit-llvm -o - %s | FileCheck %s -// -// Test that a global variable with an incomplete type gets the minimum -// alignment of 2 per the ABI if no alignment was specified by user. -// -// CHECK: @VarNoAl {{.*}} align 2 -// CHECK-NEXT: @VarExplAl1 {{.*}} align 1 -// CHECK-NEXT: @VarExplAl4 {{.*}} align 4 - -// No alignemnt specified by user. -struct incomplete_ty_noal; -extern struct incomplete_ty_noal VarNoAl; -struct incomplete_ty_noal *fun0 (void) -{ - return &VarNoAl; -} - -// User-specified alignment of 1. -struct incomplete_ty_al1; -extern struct incomplete_ty_al1 __attribute__((aligned(1))) VarExplAl1; -struct incomplete_ty_al1 *fun1 (void) -{ - return &VarExplAl1; -} - -// User-specified alignment of 4. -struct incomplete_ty_al4; -extern struct incomplete_ty_al4 __attribute__((aligned(4))) VarExplAl4; -struct incomplete_ty_al4 *fun2 (void) -{ - return &VarExplAl4; -} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Ensure minimal alignment of global vars of incomplete type. (PR #72886)
@@ -0,0 +1,32 @@ +// RUN: %clang --target=s390x-linux -S -emit-llvm -o - %s | FileCheck %s JonPsson1 wrote: Sorry, my bad. There is a SystemZ test for this already, so I moved these tests into it instead. I created a new PR: https://github.com/llvm/llvm-project/pull/73230. https://github.com/llvm/llvm-project/pull/72886 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ] Move new test into existing CodeGen test. (PR #73230)
JonPsson1 wrote: Moving recently added tests from Driver to CodeGen, per discussion for original PR (https://github.com/llvm/llvm-project/pull/72886). https://github.com/llvm/llvm-project/pull/73230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SystemZ] Move new test into existing CodeGen test. (PR #73230)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/73230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
@@ -0,0 +1,71 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s +// +// Test __atomic_is_lock_free() for __int128 with default alignment (8 +// bytes), atomic alignment (16 bytes) and with a null pointer. Also test +// __atomic_always_lock_free() and __c11_atomic_is_lock_free(). + +#include +#include + +__int128 Ptr_Al8 __attribute__((aligned(8))); +__int128 Ptr_Al16 __attribute__((aligned(16))); + +// CHECK-LABEL: @fun_PtrAl8_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef nonnull @Ptr_Al8) #[[ATTR2:[0-9]+]] +// CHECK-NEXT:ret i1 [[CALL]] +// +_Bool fun_PtrAl8_is_lock_free() { + return __atomic_is_lock_free(16, &Ptr_Al8); +} + +// CHECK-LABEL: @fun_PtrAl8_always_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 false +// +_Bool fun_PtrAl8_always_lock_free() { + return __atomic_always_lock_free(16, &Ptr_Al8); +} + +// CHECK-LABEL: @fun_PtrAl16_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef nonnull @Ptr_Al16) #[[ATTR2]] JonPsson1 wrote: fun_PtrAl16_is_lock_free: GCC returns true https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
@@ -0,0 +1,71 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s +// +// Test __atomic_is_lock_free() for __int128 with default alignment (8 +// bytes), atomic alignment (16 bytes) and with a null pointer. Also test +// __atomic_always_lock_free() and __c11_atomic_is_lock_free(). + +#include +#include + +__int128 Ptr_Al8 __attribute__((aligned(8))); +__int128 Ptr_Al16 __attribute__((aligned(16))); + +// CHECK-LABEL: @fun_PtrAl8_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef nonnull @Ptr_Al8) #[[ATTR2:[0-9]+]] +// CHECK-NEXT:ret i1 [[CALL]] +// +_Bool fun_PtrAl8_is_lock_free() { + return __atomic_is_lock_free(16, &Ptr_Al8); +} + +// CHECK-LABEL: @fun_PtrAl8_always_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 false +// +_Bool fun_PtrAl8_always_lock_free() { + return __atomic_always_lock_free(16, &Ptr_Al8); +} + +// CHECK-LABEL: @fun_PtrAl16_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef nonnull @Ptr_Al16) #[[ATTR2]] +// CHECK-NEXT:ret i1 [[CALL]] +// +_Bool fun_PtrAl16_is_lock_free() { + return __atomic_is_lock_free(16, &Ptr_Al16); +} + +// CHECK-LABEL: @fun_PtrAl16_always_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 false +// +_Bool fun_PtrAl16_always_lock_free() { + return __atomic_always_lock_free(16, &Ptr_Al16); +} + +// CHECK-LABEL: @fun_noptr_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 true +// +_Bool fun_noptr_is_lock_free() { + return __atomic_is_lock_free(16, 0); JonPsson1 wrote: fun_noptr_is_lock_free: GCC returns true. GCC: (GNU) 14.0.0 20231121 (experimental) https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
@@ -0,0 +1,71 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s +// +// Test __atomic_is_lock_free() for __int128 with default alignment (8 +// bytes), atomic alignment (16 bytes) and with a null pointer. Also test +// __atomic_always_lock_free() and __c11_atomic_is_lock_free(). + +#include +#include + +__int128 Ptr_Al8 __attribute__((aligned(8))); +__int128 Ptr_Al16 __attribute__((aligned(16))); + +// CHECK-LABEL: @fun_PtrAl8_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef nonnull @Ptr_Al8) #[[ATTR2:[0-9]+]] +// CHECK-NEXT:ret i1 [[CALL]] +// +_Bool fun_PtrAl8_is_lock_free() { + return __atomic_is_lock_free(16, &Ptr_Al8); +} + +// CHECK-LABEL: @fun_PtrAl8_always_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 false +// +_Bool fun_PtrAl8_always_lock_free() { + return __atomic_always_lock_free(16, &Ptr_Al8); +} + +// CHECK-LABEL: @fun_PtrAl16_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef nonnull @Ptr_Al16) #[[ATTR2]] +// CHECK-NEXT:ret i1 [[CALL]] +// +_Bool fun_PtrAl16_is_lock_free() { + return __atomic_is_lock_free(16, &Ptr_Al16); +} + +// CHECK-LABEL: @fun_PtrAl16_always_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 false +// +_Bool fun_PtrAl16_always_lock_free() { + return __atomic_always_lock_free(16, &Ptr_Al16); +} + +// CHECK-LABEL: @fun_noptr_is_lock_free( +// CHECK-NEXT: entry: +// CHECK-NEXT:ret i1 true +// +_Bool fun_noptr_is_lock_free() { + return __atomic_is_lock_free(16, 0); JonPsson1 wrote: Hmm, it seems that GCC is returning true for all of these in this test case, probably because the way it is written: the Ptr_Al8 is placed after the 16-byte aligned Ptr_Al16, so Ptr_Al8 also gets the greater (over)alignment. Maybe I should try these in two separate files instead. https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73134 >From bf9b6b735c131833ec9457f23b72322fd50ef821 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Fri, 3 Feb 2023 14:32:58 +0100 Subject: [PATCH 1/2] [SystemZ] Improve support for 16 byte atomic int/fp types and operations. - Clang FE now has MaxAtomicPromoteWidth and MaxAtomicInlineWidth with a value of 128. It now produces IR instead of calls to __atomic instrinsics for 16 bytes as well. FP loads are first loaded as i128 and then casted to fp128. - Atomic __int128 (and long double) variables are aligned to 16 bytes (like gcc 14). - AtomicExpand pass now expands also 16 byte operations. - tests for __atomic builtins for all integer widths, with test for i128 in both align=8 and align=16 cases. - Resulting behavior of __atomic_is_lock_free / __atomic_always_lock_free / __c11_atomic_is_lock_free is tested in gnu-atomic_is_lock_free.c - shouldExpandAtomicRMWInIR() was already returning true for any FP type. Now that the backend is acepting 16 byte atomics, 16 byte FP atomicrmw:s now also get expanded by AtomicExpand. The default (and used) shouldCastAtomicRMWIInIR() says that if the type is FP, it is casted to integer (see atomicrmw-xchg-07.ll). - TODO: AtomicExpand pass handles with this patch expansion of i128 atomicrmw:s. As a next step smaller integer types should also be possible to handle this way instead of in backend. Original patch rebased. Remove the regalloc handling for CDSG loops. Tests improved. --- clang/lib/Basic/Targets/SystemZ.h | 2 +- clang/test/CodeGen/SystemZ/atomic-alignment.c | 35 ++ .../SystemZ/gnu-atomic-builtins-i128-16Al.c | 257 + .../SystemZ/gnu-atomic-builtins-i128-8Al.c| 301 +++ .../CodeGen/SystemZ/gnu-atomic-builtins-i16.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i32.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i64.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i8.c | 219 .../gnu-atomic_is_lock_free-i128-16Al.c | 54 ++ .../gnu-atomic_is_lock_free-i128-8Al.c| 28 + .../Target/SystemZ/SystemZISelLowering.cpp| 6 +- .../CodeGen/SystemZ/atomicrmw-ops-i128.ll | 496 -- .../test/CodeGen/SystemZ/atomicrmw-xchg-07.ll | 37 +- 13 files changed, 2030 insertions(+), 62 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/atomic-alignment.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i16.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i32.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i64.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i8.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free-i128-8Al.c diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 9ba255745cf2cc52..e4ec338880f21095 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -60,7 +60,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" "-v128:64-a:8:16-n32:64"); } -MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; +MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; HasStrictFP = true; } diff --git a/clang/test/CodeGen/SystemZ/atomic-alignment.c b/clang/test/CodeGen/SystemZ/atomic-alignment.c new file mode 100644 index ..da478842ca31b2b0 --- /dev/null +++ b/clang/test/CodeGen/SystemZ/atomic-alignment.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O3 -emit-llvm %s -o - | FileCheck %s +// +// Test alignment of 128 bit Atomic int/fp types, as well as loading +// from memory with a simple addition. The fp128 is loaded as i128 and +// then casted. + +// CHECK: @Atomic_int128 = {{.*}} i128 0, align 16 +// CHECK: @Atomic_fp128 = {{.*}} fp128 0xL, align 16 + +// CHECK-LABEL: @f1 +// CHECK: %atomic-load = load atomic i128, ptr @Atomic_int128 seq_cst, align 16 +// CHECK-NEXT: %add = add nsw i128 %atomic-load, 1 +// CHECK-NEXT: store i128 %add, ptr %agg.result, align 8 +// CHECK-NEXT: ret void + +// CHECK-LABEL: @f2 +// CHECK: %atomic-load = load atomic i128, ptr @Atomic_fp128 seq_cst, align 16 +// CHECK-NEXT: %0 = bitcast i128 %atomic-load to fp128 +// CHECK-NEXT: %add = fadd fp128 %0, 0xL3FFF +// CHECK-NEXT: store fp128 %add, ptr %agg.result, align 8 +// CHECK-NEXT: ret void + + +#include + +_Atomic __int128Atomic_int128; +_Atomic long double Atomic_fp128; + +__int128 f1() { + return Atomic_int128 + 1; +} + +long double
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
@@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s +// +// Test __atomic_is_lock_free() and __atomic_always_lock_free() for __int128 +// with 16 byte alignment. + +#include +#include + JonPsson1 wrote: The first two functions here should return true..? https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
@@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s +// +// Test __atomic_is_lock_free() and __atomic_always_lock_free() for __int128 +// with 16 byte alignment. + +#include +#include + +__int128 Int128_Al16 __attribute__((aligned(16))); + +// CHECK-LABEL: @fun0 +// CHECK: tail call zeroext i1 @__atomic_is_lock_free +_Bool fun0() { + return __atomic_is_lock_free(16, &Int128_Al16); +} + +// CHECK-LABEL: @fun1 +// CHECK: ret i1 false +_Bool fun1() { + return __atomic_always_lock_free(16, &Int128_Al16); +} + +// Also test these with a 16 byte size and null-pointer. +// CHECK-LABEL: @fun2 +// CHECK: ret i1 true +_Bool fun2() { + return __atomic_is_lock_free(16, 0); JonPsson1 wrote: > But this seems actually incorrect - when using default assumptions, the > operation should not be lock-free ... https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
JonPsson1 wrote: Not sure about GCC here, as far as I can see, it is returning true for both of the 8-byte aligned cases in gnu-atomic_is_lock_free-i128-8Al.c, also now that the alignment is actually 8... GCC is returning true for all in gnu-atomic_is_lock_free-i128-16Al.c, except for except for emitting a call to __c11_atomic_is_lock_free. https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73134 >From bf9b6b735c131833ec9457f23b72322fd50ef821 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Fri, 3 Feb 2023 14:32:58 +0100 Subject: [PATCH 1/3] [SystemZ] Improve support for 16 byte atomic int/fp types and operations. - Clang FE now has MaxAtomicPromoteWidth and MaxAtomicInlineWidth with a value of 128. It now produces IR instead of calls to __atomic instrinsics for 16 bytes as well. FP loads are first loaded as i128 and then casted to fp128. - Atomic __int128 (and long double) variables are aligned to 16 bytes (like gcc 14). - AtomicExpand pass now expands also 16 byte operations. - tests for __atomic builtins for all integer widths, with test for i128 in both align=8 and align=16 cases. - Resulting behavior of __atomic_is_lock_free / __atomic_always_lock_free / __c11_atomic_is_lock_free is tested in gnu-atomic_is_lock_free.c - shouldExpandAtomicRMWInIR() was already returning true for any FP type. Now that the backend is acepting 16 byte atomics, 16 byte FP atomicrmw:s now also get expanded by AtomicExpand. The default (and used) shouldCastAtomicRMWIInIR() says that if the type is FP, it is casted to integer (see atomicrmw-xchg-07.ll). - TODO: AtomicExpand pass handles with this patch expansion of i128 atomicrmw:s. As a next step smaller integer types should also be possible to handle this way instead of in backend. Original patch rebased. Remove the regalloc handling for CDSG loops. Tests improved. --- clang/lib/Basic/Targets/SystemZ.h | 2 +- clang/test/CodeGen/SystemZ/atomic-alignment.c | 35 ++ .../SystemZ/gnu-atomic-builtins-i128-16Al.c | 257 + .../SystemZ/gnu-atomic-builtins-i128-8Al.c| 301 +++ .../CodeGen/SystemZ/gnu-atomic-builtins-i16.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i32.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i64.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i8.c | 219 .../gnu-atomic_is_lock_free-i128-16Al.c | 54 ++ .../gnu-atomic_is_lock_free-i128-8Al.c| 28 + .../Target/SystemZ/SystemZISelLowering.cpp| 6 +- .../CodeGen/SystemZ/atomicrmw-ops-i128.ll | 496 -- .../test/CodeGen/SystemZ/atomicrmw-xchg-07.ll | 37 +- 13 files changed, 2030 insertions(+), 62 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/atomic-alignment.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i16.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i32.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i64.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i8.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free-i128-8Al.c diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 9ba255745cf2cc5..e4ec338880f2109 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -60,7 +60,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" "-v128:64-a:8:16-n32:64"); } -MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; +MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; HasStrictFP = true; } diff --git a/clang/test/CodeGen/SystemZ/atomic-alignment.c b/clang/test/CodeGen/SystemZ/atomic-alignment.c new file mode 100644 index 000..da478842ca31b2b --- /dev/null +++ b/clang/test/CodeGen/SystemZ/atomic-alignment.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O3 -emit-llvm %s -o - | FileCheck %s +// +// Test alignment of 128 bit Atomic int/fp types, as well as loading +// from memory with a simple addition. The fp128 is loaded as i128 and +// then casted. + +// CHECK: @Atomic_int128 = {{.*}} i128 0, align 16 +// CHECK: @Atomic_fp128 = {{.*}} fp128 0xL, align 16 + +// CHECK-LABEL: @f1 +// CHECK: %atomic-load = load atomic i128, ptr @Atomic_int128 seq_cst, align 16 +// CHECK-NEXT: %add = add nsw i128 %atomic-load, 1 +// CHECK-NEXT: store i128 %add, ptr %agg.result, align 8 +// CHECK-NEXT: ret void + +// CHECK-LABEL: @f2 +// CHECK: %atomic-load = load atomic i128, ptr @Atomic_fp128 seq_cst, align 16 +// CHECK-NEXT: %0 = bitcast i128 %atomic-load to fp128 +// CHECK-NEXT: %add = fadd fp128 %0, 0xL3FFF +// CHECK-NEXT: store fp128 %add, ptr %agg.result, align 8 +// CHECK-NEXT: ret void + + +#include + +_Atomic __int128Atomic_int128; +_Atomic long double Atomic_fp128; + +__int128 f1() { + return Atomic_int128 + 1; +} + +long double f2(
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
JonPsson1 wrote: Sorry for the confusion of the files: the tests for __atomic_is_lock_free() and friends are now in back a single file atomic_is_lock_free-i128.c. The C library call is also included as it also changes behavior with this patch. Current test output in CHECKs, with previous problems remaining. I see that these can be called for `long double / Atomic` as well, and clang is now changing output with the patch. GCC however seems to return 'true' for any such calls, regardless of alignment / type, so I suspect this is not really expected to work. IIUC, the builtins are only intended for use with integral types. The library call may not be limited to ints. Waiting with these until later. https://github.com/llvm/llvm-project/pull/73134 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/73511 External symbols created from a linker script may not get the ABI minimum alignment and must therefore be treated as unaligned by the compiler. To implement this, getMinGlobalAlign() (and getAlignOfGlobalVar) gets a second parameter 'HasDef', which lets SystemZTargetInfo::getMinGlobalAlign() handle this. My first idea was to pass a VarDecl to getMinGlobalAlign(), and assume the value to be external only in cases of (VD && !VD->hasDefiniton()). I got however link problems with 'ninja check', so opted to pass a boolean 'HasDef' instead. In SemaOpenMP.cpp the check with VD was added, and in CodeGenModule.cpp 'true' is passed for strings (which I am hoping is correct as the strings seem to be passed to the functions which makes it look like they are being created for the module...) The assumption generally would then be that everything is generated for the module except for a VarDecl that returns false in hasDefinition(). This is controlled by a new CL option '-munaligned-symbols', where I looked at -munaligned-access (e.g. RISCVTargetInfo::handleTargetFeatures() / FastUnalignedAccess). SystemZ: - Test: I reused Andreas' test for GCC and also added cases of char arrays and structs, but not sure if those are relevant/needed after all as they just worked without any extra handling... - The backend seems to emit a GOT lookup also for the external and aligned cases - I suppose this is because the linker will fixup those... >From c2f300a46eea861fac1a7f253e5f2998eb6740cd Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 17:22:32 +0100 Subject: [PATCH] IP --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/Basic/TargetInfo.h| 7 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ASTContext.cpp | 15 ++- clang/lib/Basic/Targets/AArch64.cpp | 5 +- clang/lib/Basic/Targets/AArch64.h | 2 +- clang/lib/Basic/Targets/CSKY.cpp | 2 +- clang/lib/Basic/Targets/CSKY.h| 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 3 +- clang/lib/Basic/Targets/SPIR.h| 3 +- clang/lib/Basic/Targets/SystemZ.cpp | 10 ++ clang/lib/Basic/Targets/SystemZ.h | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp | 8 ++ clang/lib/Sema/SemaOpenMP.cpp | 3 +- .../test/CodeGen/SystemZ/unaligned-symbols.c | 104 ++ llvm/lib/Target/SystemZ/SystemZFeatures.td| 5 + 17 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/unaligned-symbols.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043f..9e60ca8fb2ea8c6 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase { /// Return the alignment in bits that should be given to a /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + unsigned getAlignOfGlobalVar(QualType T, bool HasDef) const; /// Return the alignment in characters that should be given to a /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + CharUnits getAlignOfGlobalVarInChars(QualType T, bool HasDef) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 41f3c2e403cbef6..1a536b3448df162 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -705,8 +705,11 @@ class TargetInfo : public TransferrableTargetInfo, } /// getMinGlobalAlign - Return the minimum alignment of a global variable, - /// unless its alignment is explicitly reduced via attributes. - virtual unsigned getMinGlobalAlign (uint64_t) const { + /// unless its alignment is explicitly reduced via attributes. It may be + /// that an external symbol needs to be considered unaligned (like + /// artificial symbols created from a linker script). If \param HasDef is + /// false, this symbol does not have a definition and is external. + virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasDef) const { return MinGlobalAlign; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index b2f2bcb6ac37910..1ad01c2307c3079 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4544,6 +4544,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; def mno_unaligned_access : Flag<["-"], "m
[llvm] [clang] [SystemZ] Properly support 16 byte atomic int/fp types and ops. (PR #73134)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73134 >From bf9b6b735c131833ec9457f23b72322fd50ef821 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Fri, 3 Feb 2023 14:32:58 +0100 Subject: [PATCH 1/5] [SystemZ] Improve support for 16 byte atomic int/fp types and operations. - Clang FE now has MaxAtomicPromoteWidth and MaxAtomicInlineWidth with a value of 128. It now produces IR instead of calls to __atomic instrinsics for 16 bytes as well. FP loads are first loaded as i128 and then casted to fp128. - Atomic __int128 (and long double) variables are aligned to 16 bytes (like gcc 14). - AtomicExpand pass now expands also 16 byte operations. - tests for __atomic builtins for all integer widths, with test for i128 in both align=8 and align=16 cases. - Resulting behavior of __atomic_is_lock_free / __atomic_always_lock_free / __c11_atomic_is_lock_free is tested in gnu-atomic_is_lock_free.c - shouldExpandAtomicRMWInIR() was already returning true for any FP type. Now that the backend is acepting 16 byte atomics, 16 byte FP atomicrmw:s now also get expanded by AtomicExpand. The default (and used) shouldCastAtomicRMWIInIR() says that if the type is FP, it is casted to integer (see atomicrmw-xchg-07.ll). - TODO: AtomicExpand pass handles with this patch expansion of i128 atomicrmw:s. As a next step smaller integer types should also be possible to handle this way instead of in backend. Original patch rebased. Remove the regalloc handling for CDSG loops. Tests improved. --- clang/lib/Basic/Targets/SystemZ.h | 2 +- clang/test/CodeGen/SystemZ/atomic-alignment.c | 35 ++ .../SystemZ/gnu-atomic-builtins-i128-16Al.c | 257 + .../SystemZ/gnu-atomic-builtins-i128-8Al.c| 301 +++ .../CodeGen/SystemZ/gnu-atomic-builtins-i16.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i32.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i64.c | 219 .../CodeGen/SystemZ/gnu-atomic-builtins-i8.c | 219 .../gnu-atomic_is_lock_free-i128-16Al.c | 54 ++ .../gnu-atomic_is_lock_free-i128-8Al.c| 28 + .../Target/SystemZ/SystemZISelLowering.cpp| 6 +- .../CodeGen/SystemZ/atomicrmw-ops-i128.ll | 496 -- .../test/CodeGen/SystemZ/atomicrmw-xchg-07.ll | 37 +- 13 files changed, 2030 insertions(+), 62 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/atomic-alignment.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i16.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i32.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i64.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i8.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free-i128-16Al.c create mode 100644 clang/test/CodeGen/SystemZ/gnu-atomic_is_lock_free-i128-8Al.c diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 9ba255745cf2cc5..e4ec338880f2109 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -60,7 +60,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" "-v128:64-a:8:16-n32:64"); } -MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; +MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; HasStrictFP = true; } diff --git a/clang/test/CodeGen/SystemZ/atomic-alignment.c b/clang/test/CodeGen/SystemZ/atomic-alignment.c new file mode 100644 index 000..da478842ca31b2b --- /dev/null +++ b/clang/test/CodeGen/SystemZ/atomic-alignment.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O3 -emit-llvm %s -o - | FileCheck %s +// +// Test alignment of 128 bit Atomic int/fp types, as well as loading +// from memory with a simple addition. The fp128 is loaded as i128 and +// then casted. + +// CHECK: @Atomic_int128 = {{.*}} i128 0, align 16 +// CHECK: @Atomic_fp128 = {{.*}} fp128 0xL, align 16 + +// CHECK-LABEL: @f1 +// CHECK: %atomic-load = load atomic i128, ptr @Atomic_int128 seq_cst, align 16 +// CHECK-NEXT: %add = add nsw i128 %atomic-load, 1 +// CHECK-NEXT: store i128 %add, ptr %agg.result, align 8 +// CHECK-NEXT: ret void + +// CHECK-LABEL: @f2 +// CHECK: %atomic-load = load atomic i128, ptr @Atomic_fp128 seq_cst, align 16 +// CHECK-NEXT: %0 = bitcast i128 %atomic-load to fp128 +// CHECK-NEXT: %add = fadd fp128 %0, 0xL3FFF +// CHECK-NEXT: store fp128 %add, ptr %agg.result, align 8 +// CHECK-NEXT: ret void + + +#include + +_Atomic __int128Atomic_int128; +_Atomic long double Atomic_fp128; + +__int128 f1() { + return Atomic_int128 + 1; +} + +long double f2(
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
@@ -1687,7 +1687,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = std::max(Align, getTargetInfo().getMinGlobalAlign( +TypeSize, VD->hasDefinition())); JonPsson1 wrote: Good point! It seems to me though that this is something the backend must handle. Even with this patch, e.g. a weak 4-byte integer would get the natural alignment, and could later be replaced with an unaligned 4-byte integer by the linker. This patch only removes the ABI minimal alignment, i.e. the requirement to align everything by at least 2 bytes. A recent GCC does not handle this either: it emits a LARL for a weak int. Could it be that the linker preserves the alignment of the original (weak) object? https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
JonPsson1 wrote: Eli, are you supposed to press some button before I merge this? https://github.com/llvm/llvm-project/pull/72977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
@@ -1687,7 +1687,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = std::max(Align, getTargetInfo().getMinGlobalAlign( +TypeSize, VD->hasDefinition())); JonPsson1 wrote: I can't see that this is working with weak symbols with (recent) GCC: ``` test2.c: #include char __attribute__((weak)) c0_weak = 0; char __attribute__((weak)) c1_weak = 0; int main() { printf("%d\n", c0_weak + c1_weak); } test2_1.c: char __attribute__((aligned(1))) c0_weak = 1; char __attribute__((aligned(1))) c1_weak = 1; ``` ``` gcc ./test2.c ./test2_1.c -O3 -munaligned-symbols -S -c main: .LFB11: .cfi_startproc larl%r2,c0_weak larl%r1,c1_weak ... ``` ``` ~/gcc-latest/bin/gcc ./test2.c ./test2_1.c -O3 -munaligned-symbols /usr/bin/ld: /tmp/ccj8BnuO.o(.text.startup+0x2): misaligned symbol `c0_weak' (0x1004021) for relocation R_390_PC32DBL collect2: error: ld returned 1 exit status ``` https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor ASTContext::getDeclAlign() (NFC) (PR #72977)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/72977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
JonPsson1 wrote: This seems to do the trick: ``` diff --git a/clang/unittests/Basic/CMakeLists.txt b/clang/unittests/Basic/CMakeLists.txt index 3844ba4..5f162b3 100644 --- a/clang/unittests/Basic/CMakeLists.txt +++ b/clang/unittests/Basic/CMakeLists.txt @@ -18,6 +18,7 @@ clang_target_link_libraries(BasicTests PRIVATE + clangAST clangBasic clangLex ) target_link_libraries(BasicTests ``` @chapuni : It seems you removed clangAST recently from exactly this place (077a2a4) - do you have any comment as to if it would be ok to add it back..? https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
@@ -11,6 +11,7 @@ //===--===// #include "SystemZ.h" +#include "clang/AST/Decl.h" JonPsson1 wrote: What is the motivation for this? I mean, is there any general consensus that this really should be avoided for the purpose of building the tests (note that clang itself builds fine)? Why did you remove clangAST from the cmake file to begin with - was there some discussion preceding this? The reason I am passing the VarDecl to the target is that in order to have the (systemz) target return a minimum alignment value it needs to know things about the Variable. Since this is very target specific, it would be a bit weird to have in common code something like isVarExternalOrWeak(), or would it not? AFIK this is only relevant for SystemZ so it would be best to only do this check in the target. Besides, if some other target needs to check something else, it could do so if the *VD is there. @efriedma-quic do you have any opinion? https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 84831bd - [SystemZ] Make 128 bit integers be aligned to 8 bytes.
Author: Jonas Paulsson Date: 2022-08-03T15:39:54+02:00 New Revision: 84831bdfedbad8221a529a640d0f4bd9d0e3ba7b URL: https://github.com/llvm/llvm-project/commit/84831bdfedbad8221a529a640d0f4bd9d0e3ba7b DIFF: https://github.com/llvm/llvm-project/commit/84831bdfedbad8221a529a640d0f4bd9d0e3ba7b.diff LOG: [SystemZ] Make 128 bit integers be aligned to 8 bytes. The SystemZ ABI says that 128 bit integers should be aligned to only 8 bytes. Reviewed By: Ulrich Weigand, Nikita Popov Differential Revision: https://reviews.llvm.org/D130900 Added: llvm/test/CodeGen/SystemZ/unaligned-02.ll Modified: clang/include/clang/Basic/TargetInfo.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/TargetInfo.cpp clang/lib/Basic/Targets/SystemZ.h clang/test/CodeGen/SystemZ/align-systemz.c clang/test/CodeGen/SystemZ/systemz-abi.c clang/test/CodeGen/SystemZ/zos-alignment.c Removed: diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index b4f3a69259fad..6f9ee65544450 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -78,6 +78,7 @@ struct TransferrableTargetInfo { unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; + unsigned char Int128Align; // Fixed point bit widths unsigned char ShortAccumWidth, ShortAccumAlign; @@ -470,6 +471,9 @@ class TargetInfo : public virtual TransferrableTargetInfo, unsigned getLongLongWidth() const { return LongLongWidth; } unsigned getLongLongAlign() const { return LongLongAlign; } + /// getInt128Align() - Returns the alignment of Int128. + unsigned getInt128Align() const { return Int128Align; } + /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and /// 'unsigned short _Accum' for this target, in bits. unsigned getShortAccumWidth() const { return ShortAccumWidth; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index eefb07465b1cb..21fd3953eb159 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2082,7 +2082,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case BuiltinType::Int128: case BuiltinType::UInt128: Width = 128; - Align = 128; // int128_t is 128-bit aligned on all targets. + Align = Target->getInt128Align(); break; case BuiltinType::ShortAccum: case BuiltinType::UShortAccum: diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 6685145ea6d2e..4e2446315a379 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -45,6 +45,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { IntWidth = IntAlign = 32; LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; + Int128Align = 128; // Fixed point default bit widths ShortAccumWidth = ShortAccumAlign = 16; diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index e4f242e624cb1..7def024d07a77 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -40,6 +40,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { TLSSupported = true; IntWidth = IntAlign = 32; LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; +Int128Align = 64; PointerWidth = PointerAlign = 64; LongDoubleWidth = 128; LongDoubleAlign = 64; diff --git a/clang/test/CodeGen/SystemZ/align-systemz.c b/clang/test/CodeGen/SystemZ/align-systemz.c index 8cc33a83f8686..72d988e413291 100644 --- a/clang/test/CodeGen/SystemZ/align-systemz.c +++ b/clang/test/CodeGen/SystemZ/align-systemz.c @@ -26,6 +26,14 @@ void func (void) } +// The SystemZ ABI aligns __int128_t to only eight bytes. + +struct S_int128 { __int128_t B; } Obj_I128; +__int128_t GlobI128; +// CHECK: @Obj_I128 = global %struct.S_int128 zeroinitializer, align 8 +// CHECK: @GlobI128 = global i128 0, align 8 + + // Alignment should be respected for coerced argument loads struct arg { long y __attribute__((packed, aligned(4))); }; @@ -40,4 +48,3 @@ void test (void) // CHECK-LABEL: @test // CHECK: load i64, i64* getelementptr inbounds (%struct.arg, %struct.arg* @x, i32 0, i32 0), align 4 - diff --git a/clang/test/CodeGen/SystemZ/systemz-abi.c b/clang/test/CodeGen/SystemZ/systemz-abi.c index e79a287852e2d..1e7e83684005a 100644 --- a/clang/test/CodeGen/SystemZ/systemz-abi.c +++ b/clang/test/CodeGen/SystemZ/systemz-abi.c @@ -43,7 +43,7 @@ long long pass_longlong(long long arg) { return arg; } // CHECK-LABEL: define{{.*}} i64 @pass_longlong(i64 %{{.*}}) __int128 pass_int128(__int128 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_int128(i128* noalias sret(i128) align 16 %{{.*}}, i128* %0) +// CHECK-LABEL: define{{.*}} vo
[clang] 46f83ca - [InlineAsm] Add support for address operands ("p").
Author: Jonas Paulsson Date: 2022-04-13T12:50:21+02:00 New Revision: 46f83caebc8f2329bcf16b3edf6785dff480c5e3 URL: https://github.com/llvm/llvm-project/commit/46f83caebc8f2329bcf16b3edf6785dff480c5e3 DIFF: https://github.com/llvm/llvm-project/commit/46f83caebc8f2329bcf16b3edf6785dff480c5e3.diff LOG: [InlineAsm] Add support for address operands ("p"). This patch adds support for inline assembly address operands using the "p" constraint on X86 and SystemZ. This was in fact broken on X86 (see example at https://reviews.llvm.org/D110267, Nov 23). These operands should probably be treated the same as memory operands by CodeGenPrepare, which have been commented with "TODO" there. Review: Xiang Zhang and Ulrich Weigand Differential Revision: https://reviews.llvm.org/D10 Added: clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c llvm/test/CodeGen/SystemZ/inline-asm-addr.ll llvm/test/CodeGen/X86/inline-asm-p-constraint.ll Modified: clang/lib/Basic/Targets/SystemZ.h clang/lib/Basic/Targets/X86.cpp clang/test/CodeGen/asm.c llvm/docs/LangRef.rst llvm/include/llvm/CodeGen/TargetLowering.h llvm/include/llvm/IR/InlineAsm.h llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Removed: diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 92cefeea5d264..f0306642a6656 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -82,6 +82,16 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; + std::string convertConstraint(const char *&Constraint) const override { +switch (Constraint[0]) { +case 'p': // Keep 'p' constraint. + return std::string("p"); +default: + break; +} +return TargetInfo::convertConstraint(Constraint); + } + const char *getClobbers() const override { // FIXME: Is this really right? return ""; diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 1ec2bb9c249f0..b83b3517ddf90 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -1490,8 +1490,8 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("{si}"); case 'D': return std::string("{di}"); - case 'p': // address -return std::string("im"); + case 'p': // Keep 'p' constraint (address). +return std::string("p"); case 't': // top of floating point stack. return std::string("{st}"); case 'u':// second from top of floating point stack. diff --git a/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c b/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c new file mode 100644 index 0..3157d0ef62416 --- /dev/null +++ b/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -no-opaque-pointers -triple s390x-linux-gnu -O2 -emit-llvm \ +// RUN: -o - %s 2>&1 | FileCheck %s +// REQUIRES: systemz-registered-target + +long *A; +long Idx; +unsigned long Addr; + +unsigned long fun_BD12_p() { +// CHECK-LABEL: define{{.*}} i64 @fun_BD12_p() +// CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "p" (&A[100])); + return Addr; +} + +unsigned long fun_BDX12_p() { +// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_p() +// CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "p" (&A[Idx + 100])); + return Addr; +} + +unsigned long fun_BD20_p() { +// CHECK-LABEL: define{{.*}} i64 @fun_BD20_p() +// CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "p" (&A[1000])); + return Addr; +} + +unsigned long fun_BDX20_p() { +// CHECK-LABEL: define{{.*}} i64 @fun_BDX20_p() +// CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "p" (&A[Idx + 1000])); + return Addr; +} diff --git a/clang/test/CodeGen/asm.c b/clang/test/CodeGen/asm.c index 99bcccd33d825..ec7e6d1556cb6 100644 --- a/clang/test/CodeGen/asm.c +++ b/clang/test/CodeGen/asm.c @@ -274,3 +274,13 @@ int t32(int cond) label_true: return 1; } + +void *t33(void *ptr) +{ + void *ret; + asm ("lea %1, %0" : "=r" (ret) : "p" (ptr)); + return ret; + + // CHECK: @t33 + // CHECK: %1 = call i8* asm "lea $1, $0", "=r,p,~{dirflag},~{fpsr},~{flags}"(i8* %0) +} diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 1a218c0a5c756..98e90a65073ad 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs
[clang] 4aa5dc1 - [SystemZ] Handle SystemZ specific inline assembly address operands.
Author: Jonas Paulsson Date: 2022-04-19T16:55:45+02:00 New Revision: 4aa5dc15f0869f8a5fb6fe760c517d2d5d4c710e URL: https://github.com/llvm/llvm-project/commit/4aa5dc15f0869f8a5fb6fe760c517d2d5d4c710e DIFF: https://github.com/llvm/llvm-project/commit/4aa5dc15f0869f8a5fb6fe760c517d2d5d4c710e.diff LOG: [SystemZ] Handle SystemZ specific inline assembly address operands. Handle ZQ, ZR, ZS and ZT inline assembly operand constraints. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D110267 Added: Modified: clang/lib/Basic/Targets/SystemZ.cpp clang/lib/Basic/Targets/SystemZ.h clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c llvm/include/llvm/IR/InlineAsm.h llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp llvm/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/lib/Target/SystemZ/SystemZISelLowering.h llvm/test/CodeGen/SystemZ/inline-asm-addr.ll Removed: diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp index e3e0da21f8d5f..3af9216315132 100644 --- a/clang/lib/Basic/Targets/SystemZ.cpp +++ b/clang/lib/Basic/Targets/SystemZ.cpp @@ -59,6 +59,17 @@ bool SystemZTargetInfo::validateAsmConstraint( default: return false; + case 'Z': +switch (Name[1]) { +default: + return false; +case 'Q': // Address with base and unsigned 12-bit displacement +case 'R': // Likewise, plus an index +case 'S': // Address with base and signed 20-bit displacement +case 'T': // Likewise, plus an index + break; +} +LLVM_FALLTHROUGH; case 'a': // Address register case 'd': // Data register (equivalent to 'r') case 'f': // Floating-point register diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index f0306642a6656..d12045c756c1f 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -86,6 +86,20 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { switch (Constraint[0]) { case 'p': // Keep 'p' constraint. return std::string("p"); +case 'Z': + switch (Constraint[1]) { + case 'Q': // Address with base and unsigned 12-bit displacement + case 'R': // Likewise, plus an index + case 'S': // Address with base and signed 20-bit displacement + case 'T': // Likewise, plus an index +// "^" hints llvm that this is a 2 letter constraint. +// "Constraint++" is used to promote the string iterator +// to the next constraint. +return std::string("^") + std::string(Constraint++, 2); + default: +break; + } + break; default: break; } diff --git a/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c b/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c index 3157d0ef62416..fd91abcc75954 100644 --- a/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c +++ b/clang/test/CodeGen/SystemZ/systemz-inline-asm-03.c @@ -6,6 +6,34 @@ long *A; long Idx; unsigned long Addr; +unsigned long fun_BD12_Q() { +// CHECK-LABEL: define{{.*}} i64 @fun_BD12_Q() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZQ"(i64* nonnull %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZQ" (&A[100])); + return Addr; +} + +unsigned long fun_BD12_R() { +// CHECK-LABEL: define{{.*}} i64 @fun_BD12_R() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZR"(i64* nonnull %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZR" (&A[100])); + return Addr; +} + +unsigned long fun_BD12_S() { +// CHECK-LABEL: define{{.*}} i64 @fun_BD12_S() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZS"(i64* nonnull %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZS" (&A[100])); + return Addr; +} + +unsigned long fun_BD12_T() { +// CHECK-LABEL: define{{.*}} i64 @fun_BD12_T() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZT"(i64* nonnull %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZT" (&A[100])); + return Addr; +} + unsigned long fun_BD12_p() { // CHECK-LABEL: define{{.*}} i64 @fun_BD12_p() // CHECK: call i64 asm "lay $0, $1", "=r,p"(i64* nonnull %arrayidx) @@ -13,6 +41,34 @@ unsigned long fun_BD12_p() { return Addr; } +unsigned long fun_BDX12_Q() { +// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_Q() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZQ"(i64* %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZQ" (&A[Idx + 100])); + return Addr; +} + +unsigned long fun_BDX12_R() { +// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_R() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZR"(i64* %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZR" (&A[Idx + 100])); + return Addr; +} + +unsigned long fun_BDX12_S() { +// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_S() +// CHECK: call i64 asm "lay $0, $1", "=r,^ZS"(i64* %arrayidx) + asm("lay %0, %1" : "=r" (Addr) : "ZS" (&A[Idx + 100])); + return Addr; +} + +unsigned long fun_BDX12_T() { +// CHECK-LABEL: define{{.*}} i64 @fun_BDX12_T() +// CHECK: call i64 asm
[clang] 9b38e2e - [SystemZ] Fix C++ ABI for passing args of structs containing zero width bitfield.
Author: Jonas Paulsson Date: 2022-04-26T17:16:14+02:00 New Revision: 9b38e2efa0f0c819ec696d13731ac1ce08f81930 URL: https://github.com/llvm/llvm-project/commit/9b38e2efa0f0c819ec696d13731ac1ce08f81930 DIFF: https://github.com/llvm/llvm-project/commit/9b38e2efa0f0c819ec696d13731ac1ce08f81930.diff LOG: [SystemZ] Fix C++ ABI for passing args of structs containing zero width bitfield. A struct like { float a; int :0; } should per the SystemZ ABI be passed in a GPR, but to match a bug in GCC it has been passed in an FPR (see 759449c). GCC has now corrected the C++ ABI for this case, and this patch for clang follows suit. Reviewed By: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D122388 Added: Modified: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/SystemZ/systemz-abi.cpp Removed: diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index c5a031d5487cf..ecbb3505bb91c 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -7514,12 +7514,9 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { // Check the fields. for (const auto *FD : RD->fields()) { - // For compatibility with GCC, ignore empty bitfields in C++ mode. // Unlike isSingleElementStruct(), empty structure and array fields // do count. So do anonymous bitfields that aren't zero-sized. - if (getContext().getLangOpts().CPlusPlus && - FD->isZeroLengthBitField(getContext())) -continue; + // Like isSingleElementStruct(), ignore C++20 empty data members. if (FD->hasAttr() && isEmptyRecord(getContext(), FD->getType(), true)) diff --git a/clang/test/CodeGen/SystemZ/systemz-abi.cpp b/clang/test/CodeGen/SystemZ/systemz-abi.cpp index 9a0b2e39c6070..a76bba3561b44 100644 --- a/clang/test/CodeGen/SystemZ/systemz-abi.cpp +++ b/clang/test/CodeGen/SystemZ/systemz-abi.cpp @@ -15,12 +15,10 @@ class agg_double_class pass_agg_double_class(class agg_double_class arg) { retur // SOFT-FLOAT-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias sret(%class.agg_double_class) align 8 %{{.*}}, i64 %{{.*}}) -// For compatibility with GCC, this structure is passed in an FPR in C++, -// but passed in a GPR in C (checked in systemz-abi.c). - +// This structure is passed in a GPR in C++ (and C, checked in systemz-abi.c). struct agg_float_cpp { float a; int : 0; }; struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, float %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}}) // SOFT-FLOAT-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}}) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/86691 - Factor out a shouldCastToInt() method. - Also pass through pointer type values to not be casted to integer. The follow up improvement patch per recent review. The non-ieee FP types left out as it seems easier if someone working with that target does this part including test updates, which should be simple enough by now. Next step might be to allow FP CmpXchg, but leaving that for someone interested in that. :) CC @uweigand >From 2a9f19f7390242754a5bb304474a3e283883ad4a Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 26 Mar 2024 01:16:25 +0100 Subject: [PATCH] Refactoring with shouldCastToInt(). Also include atomic pointers. --- clang/lib/CodeGen/CGAtomic.cpp | 80 +- clang/test/CodeGen/atomic.c| 9 ++-- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index fb03d013e8afc7..f543529efe5b69 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -197,11 +197,11 @@ namespace { llvm::Value *getScalarRValValueOrNull(RValue RVal) const; /// Converts an rvalue to integer value if needed. -llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; +llvm::Value *convertRValueToInt(RValue RVal, bool CmpXchg = false) const; RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP = true) const; + bool CmpXchg = false) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -264,7 +264,7 @@ namespace { llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, - bool CastFP = true); + bool CmpXchg = false); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -272,7 +272,9 @@ namespace { llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure = llvm::AtomicOrdering::SequentiallyConsistent); -/// Emits atomic compare-and-exchange op as LLVM instruction. +/// Emits atomic compare-and-exchange op as LLVM instruction. Operands +/// must be of integer or pointer type, so float must be casted. +/// TODO: this could change - see comment in AtomicExpandPass.cpp. std::pair EmitAtomicCompareExchangeOp( llvm::Value *ExpectedVal, llvm::Value *DesiredVal, llvm::AtomicOrdering Success = @@ -1399,13 +1401,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } +static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) { + // TODO: Also pass through non-ieee FP types. + bool KeepType = (ValTy->isIntegerTy() || ValTy->isPointerTy() || + (ValTy->isIEEELikeFPTy() && !CmpXchg)); + return !KeepType; +} + RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP) const { + bool CmpXchg) const { // Try not to in some easy cases. - assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && - "Expected integer or floating point value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() || + Val->getType()->isIEEELikeFPTy()) && + "Expected integer, pointer or floating point value when converting " + "result."); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1414,13 +1425,11 @@ RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { +if (!shouldCastToInt(ValTy, CmpXchg)) { assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && "Different integer types."); return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); -} else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); -else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) +} else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) return
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
JonPsson1 wrote: > > The non-ieee FP types left out as it seems easier if someone working with > > that target does this part including test updates, which should be simple > > enough by now. > > Just add the tests I think this case isn't that simple as it is an 80 bit value. Currently that is loaded atomically first with i128, then stored as a temporary and then loaded as an fp80. If I remove that casting, the verifier complains "atomic memory access' operand must have a power-of-two size". https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
@@ -1399,13 +1401,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } +static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) { JonPsson1 wrote: This is a bit messy... - For one thing, there can't currently be an atomic CmpXchg of float type - per the spec - so that must be casted to int. That would be a later patch on its own, including as well changes in the spec document and AtomicExpand. - An atomic struct needs to be casted to integer in EmitAtomicLoadOp(). - In ConvertToValueOrAtomic() and convertRValueToInt(), scalars are treated specially. But still FP80 and float/CmpXchg scalars currrently need casting. - FP80 also seems like a separate patch if there's a need. I guess maybe in that case it does make sense to cast it to i128 here, as there is only one target using it, and it's a special non-power-of-2 case..? So it still looks to me that there are these two changes that would first need handling, and then this could probably be improved further. https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/86691 >From ea3c2d02073ecd3761b53783ad78c132ba88486e Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 26 Mar 2024 01:16:25 +0100 Subject: [PATCH 1/2] Refactoring with shouldCastToInt(). Also include atomic pointers. --- clang/lib/CodeGen/CGAtomic.cpp | 80 +- clang/test/CodeGen/atomic.c| 9 ++-- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index fb03d013e8afc7..f543529efe5b69 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -197,11 +197,11 @@ namespace { llvm::Value *getScalarRValValueOrNull(RValue RVal) const; /// Converts an rvalue to integer value if needed. -llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; +llvm::Value *convertRValueToInt(RValue RVal, bool CmpXchg = false) const; RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP = true) const; + bool CmpXchg = false) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -264,7 +264,7 @@ namespace { llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, - bool CastFP = true); + bool CmpXchg = false); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -272,7 +272,9 @@ namespace { llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure = llvm::AtomicOrdering::SequentiallyConsistent); -/// Emits atomic compare-and-exchange op as LLVM instruction. +/// Emits atomic compare-and-exchange op as LLVM instruction. Operands +/// must be of integer or pointer type, so float must be casted. +/// TODO: this could change - see comment in AtomicExpandPass.cpp. std::pair EmitAtomicCompareExchangeOp( llvm::Value *ExpectedVal, llvm::Value *DesiredVal, llvm::AtomicOrdering Success = @@ -1399,13 +1401,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } +static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) { + // TODO: Also pass through non-ieee FP types. + bool KeepType = (ValTy->isIntegerTy() || ValTy->isPointerTy() || + (ValTy->isIEEELikeFPTy() && !CmpXchg)); + return !KeepType; +} + RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP) const { + bool CmpXchg) const { // Try not to in some easy cases. - assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && - "Expected integer or floating point value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() || + Val->getType()->isIEEELikeFPTy()) && + "Expected integer, pointer or floating point value when converting " + "result."); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1414,13 +1425,11 @@ RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { +if (!shouldCastToInt(ValTy, CmpXchg)) { assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && "Different integer types."); return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); -} else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); -else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) +} else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); } @@ -1457,10 +1466,10 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, } llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, - bool IsVolatile, bool CastFP) { + bool IsVolatile, bool CmpXchg) { // Okay, we're doing this natively. Address Addr = g
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
JonPsson1 wrote: > > I think this case isn't that simple as it is an 80 bit value. Currently > > that is loaded atomically first with i128, then stored as a temporary and > > then loaded as an fp80. If I remove that casting, the verifier complains > > "atomic memory access' operand must have a power-of-two size". > > I think this should be more targeted based on the bitesize. PPCf128 should be > simple Patch updated to handle all FP types except FP80. https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/86691 >From 0b4ee03b3e095d904c4ce37eee8dee0e5e055a4c Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 26 Mar 2024 01:16:25 +0100 Subject: [PATCH 1/3] Refactoring with shouldCastToInt(). Also include atomic pointers. --- clang/lib/CodeGen/CGAtomic.cpp | 80 +- clang/test/CodeGen/atomic.c| 9 ++-- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 56198385de9dcb..74bc127d3d2445 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -197,11 +197,11 @@ namespace { llvm::Value *getScalarRValValueOrNull(RValue RVal) const; /// Converts an rvalue to integer value if needed. -llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; +llvm::Value *convertRValueToInt(RValue RVal, bool CmpXchg = false) const; RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP = true) const; + bool CmpXchg = false) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -264,7 +264,7 @@ namespace { llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, - bool CastFP = true); + bool CmpXchg = false); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -272,7 +272,9 @@ namespace { llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure = llvm::AtomicOrdering::SequentiallyConsistent); -/// Emits atomic compare-and-exchange op as LLVM instruction. +/// Emits atomic compare-and-exchange op as LLVM instruction. Operands +/// must be of integer or pointer type, so float must be casted. +/// TODO: this could change - see comment in AtomicExpandPass.cpp. std::pair EmitAtomicCompareExchangeOp( llvm::Value *ExpectedVal, llvm::Value *DesiredVal, llvm::AtomicOrdering Success = @@ -1401,13 +1403,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } +static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) { + // TODO: Also pass through non-ieee FP types. + bool KeepType = (ValTy->isIntegerTy() || ValTy->isPointerTy() || + (ValTy->isIEEELikeFPTy() && !CmpXchg)); + return !KeepType; +} + RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP) const { + bool CmpXchg) const { // Try not to in some easy cases. - assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && - "Expected integer or floating point value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() || + Val->getType()->isIEEELikeFPTy()) && + "Expected integer, pointer or floating point value when converting " + "result."); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1416,13 +1427,11 @@ RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { +if (!shouldCastToInt(ValTy, CmpXchg)) { assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && "Different integer types."); return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); -} else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); -else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) +} else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); } @@ -1459,10 +1468,10 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, } llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, - bool IsVolatile, bool CastFP) { + bool IsVolatile, bool CmpXchg) { // Okay, we're doing this natively. Address Addr = g
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
@@ -1399,13 +1401,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } +static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) { JonPsson1 wrote: I thought it was a bit more clear than 'CastFP', as the reason for it now is the compare-and-exchange instruction only. Also added comment. https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
@@ -134,14 +134,11 @@ static _Atomic float glob_flt = 0.0f; void force_global_uses(void) { (void)glob_pointer; - // CHECK: %[[LOCAL_INT:.+]] = load atomic i32, ptr @[[GLOB_POINTER]] seq_cst - // CHECK-NEXT: inttoptr i32 %[[LOCAL_INT]] to ptr + // CHECK: load atomic ptr, ptr @[[GLOB_POINTER]] seq_cst (void)glob_pointer_from_int; - // CHECK: %[[LOCAL_INT_2:.+]] = load atomic i32, ptr @[[GLOB_POINTER_FROM_INT]] seq_cst - // CHECK-NEXT: inttoptr i32 %[[LOCAL_INT_2]] to ptr + // CHECK-NEXT: load atomic ptr, ptr @[[GLOB_POINTER_FROM_INT]] seq_cst (void)nonstatic_glob_pointer_from_int; - // CHECK: %[[LOCAL_INT_3:.+]] = load atomic i32, ptr @[[NONSTATIC_GLOB_POINTER_FROM_INT]] seq_cst - // CHECK-NEXT: inttoptr i32 %[[LOCAL_INT_3]] to ptr + // CHECK-NEXT: load atomic ptr, ptr @[[NONSTATIC_GLOB_POINTER_FROM_INT]] seq_cst JonPsson1 wrote: Added tests for double and long double, and also a run for systemz as the long double type is fp80 on x86, evidently. https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
JonPsson1 wrote: Updated per review. https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFE] Improve handling of casting of atomic memory operations. (PR #86691)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/86691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/83446 >From 7abe41b453f5cd2b6ea4b566701531c2c2a73476 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 29 Feb 2024 14:16:57 +0100 Subject: [PATCH 1/2] Don't do casting of atomic FP loads/stores in FE. --- clang/lib/CodeGen/CGAtomic.cpp| 96 --- .../CodeGen/SystemZ/atomic_fp_load_store.c| 84 clang/test/CodeGen/atomic.c | 3 +- clang/test/CodeGen/c11atomics-ios.c | 8 +- clang/test/OpenMP/atomic_read_codegen.c | 10 +- clang/test/OpenMP/atomic_write_codegen.c | 13 +-- 6 files changed, 156 insertions(+), 58 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/atomic_fp_load_store.c diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index a8d846b4f6a592..fb03d013e8afc7 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -194,12 +194,14 @@ namespace { RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot, SourceLocation loc, bool AsValue) const; -/// Converts a rvalue to integer value. -llvm::Value *convertRValueToInt(RValue RVal) const; +llvm::Value *getScalarRValValueOrNull(RValue RVal) const; -RValue ConvertIntToValueOrAtomic(llvm::Value *IntVal, - AggValueSlot ResultSlot, - SourceLocation Loc, bool AsValue) const; +/// Converts an rvalue to integer value if needed. +llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; + +RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, + SourceLocation Loc, bool AsValue, + bool CastFP = true) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -261,7 +263,8 @@ namespace { void EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. -llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile); +llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, + bool CastFP = true); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -1396,12 +1399,13 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } -RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, - AggValueSlot ResultSlot, - SourceLocation Loc, - bool AsValue) const { +RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, + AggValueSlot ResultSlot, + SourceLocation Loc, bool AsValue, + bool CastFP) const { // Try not to in some easy cases. - assert(IntVal->getType()->isIntegerTy() && "Expected integer value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && + "Expected integer or floating point value"); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1410,13 +1414,14 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy()) { - assert(IntVal->getType() == ValTy && "Different integer types."); - return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); +if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { + assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && + "Different integer types."); + return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); } else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); -else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) - return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); + return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); +else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) + return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); } // Create a temporary. This needs to be big enough to hold the @@ -1433,8 +1438,7 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, // Slam the integer into the temporary. Address CastTemp = castToAtomicI
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
JonPsson1 wrote: > test the volatile is preserved too? Tests added for 'atomic volatile' memory accesses as well. https://github.com/llvm/llvm-project/pull/83446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
@@ -1953,13 +1966,22 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, } // Okay, we're doing this natively. -llvm::Value *intValue = atomics.convertRValueToInt(rvalue); +llvm::Value *ValToStore = +atomics.convertRValueToInt(rvalue, /*CastFP=*/false); // Do the atomic store. -Address addr = atomics.castToAtomicIntPointer(atomics.getAtomicAddress()); -intValue = Builder.CreateIntCast( -intValue, addr.getElementType(), /*isSigned=*/false); -llvm::StoreInst *store = Builder.CreateStore(intValue, addr); +Address Addr = atomics.getAtomicAddress(); +bool ShouldCastToInt = true; +if (llvm::Value *Value = atomics.getScalarRValValueOrNull(rvalue)) + if (isa(Value->getType()) || + Value->getType()->isIEEELikeFPTy()) +ShouldCastToInt = false; +if (ShouldCastToInt) { JonPsson1 wrote: Thanks for review - I'll try to get back to this soon. https://github.com/llvm/llvm-project/pull/83446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/83446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/83446 The casting of FP atomic loads and stores are always done by the front-end, even though the AtomicExpandPass will do it if the target requests it (which is the default). This patch removes this casting in the front-end entirely. @efriedma-quic @arsenm @uweigand >From 58de0db5378adc54d85ee6fbd291716871cd3c6d Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 29 Feb 2024 14:16:57 +0100 Subject: [PATCH] Don't do casting of atomic FP loads/stores in FE. --- clang/lib/CodeGen/CGAtomic.cpp| 96 --- .../CodeGen/SystemZ/atomic_fp_load_store.c| 84 clang/test/CodeGen/atomic.c | 3 +- clang/test/CodeGen/c11atomics-ios.c | 8 +- clang/test/OpenMP/atomic_read_codegen.c | 10 +- clang/test/OpenMP/atomic_write_codegen.c | 13 +-- 6 files changed, 156 insertions(+), 58 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/atomic_fp_load_store.c diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index a8d846b4f6a592..fb03d013e8afc7 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -194,12 +194,14 @@ namespace { RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot, SourceLocation loc, bool AsValue) const; -/// Converts a rvalue to integer value. -llvm::Value *convertRValueToInt(RValue RVal) const; +llvm::Value *getScalarRValValueOrNull(RValue RVal) const; -RValue ConvertIntToValueOrAtomic(llvm::Value *IntVal, - AggValueSlot ResultSlot, - SourceLocation Loc, bool AsValue) const; +/// Converts an rvalue to integer value if needed. +llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; + +RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, + SourceLocation Loc, bool AsValue, + bool CastFP = true) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -261,7 +263,8 @@ namespace { void EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. -llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile); +llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, + bool CastFP = true); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -1396,12 +1399,13 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } -RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, - AggValueSlot ResultSlot, - SourceLocation Loc, - bool AsValue) const { +RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, + AggValueSlot ResultSlot, + SourceLocation Loc, bool AsValue, + bool CastFP) const { // Try not to in some easy cases. - assert(IntVal->getType()->isIntegerTy() && "Expected integer value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && + "Expected integer or floating point value"); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1410,13 +1414,14 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy()) { - assert(IntVal->getType() == ValTy && "Different integer types."); - return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); +if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { + assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && + "Different integer types."); + return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); } else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); -else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) - return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); + return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); +else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) + return RValue::get(CGF.Builder.CreateB
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
@@ -1410,13 +1414,14 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy()) { - assert(IntVal->getType() == ValTy && "Different integer types."); - return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); +if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { + assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && + "Different integer types."); + return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); } else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); -else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) - return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); + return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); +else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) + return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); JonPsson1 wrote: As AtomicExpandPass doesn't do any casting of AtomicCmpXchg - at least currently - I think the other users of ConvertIntToValueOrAtomic() (which emit AtomicCmpXchg) need the current behavior. https://github.com/llvm/llvm-project/pull/83446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
@@ -1410,13 +1414,14 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); -if (ValTy->isIntegerTy()) { - assert(IntVal->getType() == ValTy && "Different integer types."); - return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); +if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { + assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && + "Different integer types."); + return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); } else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); -else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) - return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); + return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); +else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) + return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); JonPsson1 wrote: Ah, I see, AtomicExpandPass is actually casting pointers to int, but not with the target hook to control it... https://github.com/llvm/llvm-project/pull/83446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Don't do casting of atomic FP loads/stores in FE. (PR #83446)
https://github.com/JonPsson1 edited https://github.com/llvm/llvm-project/pull/83446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
JonPsson1 wrote: @efriedma-quic LGTY? https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
JonPsson1 wrote: Thanks for review! https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 closed https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e976053 - [clang, SystemZ] Fix test case for buildbot.
Author: Jonas Paulsson Date: 2024-01-27T19:02:36+01:00 New Revision: e976053a63c251e9b65733ed3574e5c3de62084c URL: https://github.com/llvm/llvm-project/commit/e976053a63c251e9b65733ed3574e5c3de62084c DIFF: https://github.com/llvm/llvm-project/commit/e976053a63c251e9b65733ed3574e5c3de62084c.diff LOG: [clang, SystemZ] Fix test case for buildbot. It seems the automatic Value naming starts on %1 instead of %0 sometimes. Added: Modified: clang/test/CodeGen/SystemZ/unaligned-symbols.c Removed: diff --git a/clang/test/CodeGen/SystemZ/unaligned-symbols.c b/clang/test/CodeGen/SystemZ/unaligned-symbols.c index 193e092b99c2b58..31fc211393dd719 100644 --- a/clang/test/CodeGen/SystemZ/unaligned-symbols.c +++ b/clang/test/CodeGen/SystemZ/unaligned-symbols.c @@ -105,8 +105,8 @@ unsigned char foo6 () { // A weak symbol could be replaced with an unaligned one at link time. // CHECK-LABEL: foo7 -// ALIGNED: %0 = load i8, ptr @Weaksym, align 2 -// UNALIGN: %0 = load i8, ptr @Weaksym, align 1 +// ALIGNED: load i8, ptr @Weaksym, align 2 +// UNALIGN: load i8, ptr @Weaksym, align 1 unsigned char __attribute__((weak)) Weaksym = 0; unsigned char foo7 () { return Weaksym; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang, SystemZ] Split test into Driver and CodeGen parts (NFC) (PR #79808)
JonPsson1 wrote: LGTM https://github.com/llvm/llvm-project/pull/79808 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang, SystemZ] Split test into Driver and CodeGen parts (NFC) (PR #79808)
https://github.com/JonPsson1 approved this pull request. https://github.com/llvm/llvm-project/pull/79808 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
@@ -11,6 +11,7 @@ //===--===// #include "SystemZ.h" +#include "clang/AST/Decl.h" JonPsson1 wrote: ping! Any further comments / opinions on how to best do this, please? https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73511 >From 5c1c5d401775089bc600b85227f5e7bd974d4bd0 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 17:22:32 +0100 Subject: [PATCH 1/2] Initial Also handle weak symbols Fix test for -emit-llvm clang-format --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/Basic/TargetInfo.h| 6 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ASTContext.cpp | 12 +- clang/lib/Basic/Targets/AArch64.cpp | 5 +- clang/lib/Basic/Targets/AArch64.h | 3 +- clang/lib/Basic/Targets/CSKY.cpp | 3 +- clang/lib/Basic/Targets/CSKY.h| 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 3 +- clang/lib/Basic/Targets/SPIR.h| 3 +- clang/lib/Basic/Targets/SystemZ.cpp | 11 ++ clang/lib/Basic/Targets/SystemZ.h | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp | 8 ++ clang/lib/Sema/SemaOpenMP.cpp | 2 +- .../test/CodeGen/SystemZ/unaligned-symbols.c | 113 ++ llvm/lib/Target/SystemZ/SystemZFeatures.td| 5 + 17 files changed, 179 insertions(+), 21 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/unaligned-symbols.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043..2c42602bef5a6f 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase { /// Return the alignment in bits that should be given to a /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + unsigned getAlignOfGlobalVar(QualType T, const VarDecl *VD) const; /// Return the alignment in characters that should be given to a /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 3eb23ebdacf0ed..7ac6bf24124cdd 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -50,6 +50,7 @@ class DiagnosticsEngine; class LangOptions; class CodeGenOptions; class MacroBuilder; +class VarDecl; /// Contains information gathered from parsing the contents of TargetAttr. struct ParsedTargetAttr { @@ -704,8 +705,9 @@ class TargetInfo : public TransferrableTargetInfo, } /// getMinGlobalAlign - Return the minimum alignment of a global variable, - /// unless its alignment is explicitly reduced via attributes. - virtual unsigned getMinGlobalAlign (uint64_t) const { + /// unless its alignment is explicitly reduced via attributes. If \param VD + /// is non-null, it may be used to examine the specific variable's attributes. + virtual unsigned getMinGlobalAlign(uint64_t Size, const VarDecl *VD) const { return MinGlobalAlign; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d2e6c3ff721c27..29f2b5c8b00512 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4601,6 +4601,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">; +def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; +def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; } // let Flags = [TargetSpecific] def mstrict_align : Flag<["-"], "mstrict-align">, Alias, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0fc0831b221aab..a6314c83f06ca7 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1688,7 +1688,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = +std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize, VD)); } // Fields can be subject to extr
[llvm] [clang] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
@@ -11,6 +11,7 @@ //===--===// #include "SystemZ.h" +#include "clang/AST/Decl.h" JonPsson1 wrote: Ok, that makes more sense to me know considering different ways of building clang, thanks. Patch updated: I tried to follow your suggestion by splitting up the work and basically inspecting the VarDecl in ASTContext and then pass only a boolean to TargetInfo. Is this something like what you had in mind? https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/73511 >From 5c1c5d401775089bc600b85227f5e7bd974d4bd0 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 23 Nov 2023 17:22:32 +0100 Subject: [PATCH 1/3] Initial Also handle weak symbols Fix test for -emit-llvm clang-format --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/Basic/TargetInfo.h| 6 +- clang/include/clang/Driver/Options.td | 4 + clang/lib/AST/ASTContext.cpp | 12 +- clang/lib/Basic/Targets/AArch64.cpp | 5 +- clang/lib/Basic/Targets/AArch64.h | 3 +- clang/lib/Basic/Targets/CSKY.cpp | 3 +- clang/lib/Basic/Targets/CSKY.h| 2 +- clang/lib/Basic/Targets/NVPTX.cpp | 3 +- clang/lib/Basic/Targets/SPIR.h| 3 +- clang/lib/Basic/Targets/SystemZ.cpp | 11 ++ clang/lib/Basic/Targets/SystemZ.h | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp | 8 ++ clang/lib/Sema/SemaOpenMP.cpp | 2 +- .../test/CodeGen/SystemZ/unaligned-symbols.c | 113 ++ llvm/lib/Target/SystemZ/SystemZFeatures.td| 5 + 17 files changed, 179 insertions(+), 21 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/unaligned-symbols.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043f..2c42602bef5a6f3 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2406,11 +2406,11 @@ class ASTContext : public RefCountedBase { /// Return the alignment in bits that should be given to a /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + unsigned getAlignOfGlobalVar(QualType T, const VarDecl *VD) const; /// Return the alignment in characters that should be given to a /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 3eb23ebdacf0edd..7ac6bf24124cdda 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -50,6 +50,7 @@ class DiagnosticsEngine; class LangOptions; class CodeGenOptions; class MacroBuilder; +class VarDecl; /// Contains information gathered from parsing the contents of TargetAttr. struct ParsedTargetAttr { @@ -704,8 +705,9 @@ class TargetInfo : public TransferrableTargetInfo, } /// getMinGlobalAlign - Return the minimum alignment of a global variable, - /// unless its alignment is explicitly reduced via attributes. - virtual unsigned getMinGlobalAlign (uint64_t) const { + /// unless its alignment is explicitly reduced via attributes. If \param VD + /// is non-null, it may be used to examine the specific variable's attributes. + virtual unsigned getMinGlobalAlign(uint64_t Size, const VarDecl *VD) const { return MinGlobalAlign; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d2e6c3ff721c27e..29f2b5c8b005120 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4601,6 +4601,10 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">; +def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; +def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, + HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; } // let Flags = [TargetSpecific] def mstrict_align : Flag<["-"], "mstrict-align">, Alias, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0fc0831b221aab3..a6314c83f06ca73 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1688,7 +1688,8 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { if (VD->hasGlobalStorage() && !ForAlignof) { uint64_t TypeSize = !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; -Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +Align = +std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize, VD)); } // Fields can be subject
[clang] [llvm] [clang, SystemZ] Pass HasDef flag to getMinGlobalAlign(). (PR #73511)
@@ -11,6 +11,7 @@ //===--===// #include "SystemZ.h" +#include "clang/AST/Decl.h" JonPsson1 wrote: Ah, one more #include to remove that I missed - thanks :) https://github.com/llvm/llvm-project/pull/73511 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c0f1eac - [SystemZ] Don't allow CL option -mpacked-stack with -mbackchain.
Author: Jonas Paulsson Date: 2020-01-03T12:26:54-08:00 New Revision: c0f1eac008e61e8345e3f41347cfd191e4ecb215 URL: https://github.com/llvm/llvm-project/commit/c0f1eac008e61e8345e3f41347cfd191e4ecb215 DIFF: https://github.com/llvm/llvm-project/commit/c0f1eac008e61e8345e3f41347cfd191e4ecb215.diff LOG: [SystemZ] Don't allow CL option -mpacked-stack with -mbackchain. -mpacked-stack is currently not supported with -mbackchain, so this should result in a compilation error message instead of being silently ignored. Review: Ulrich Weigand Added: clang/test/Driver/mbackchain.c Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 86aee334436a..808cca76c6be 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2481,6 +2481,7 @@ def mrecord_mcount : Flag<["-"], "mrecord-mcount">, HelpText<"Generate a __mcoun Flags<[CC1Option]>, Group; def mpacked_stack : Flag<["-"], "mpacked-stack">, HelpText<"Use packed stack layout (SystemZ only).">, Flags<[CC1Option]>, Group; +def mno_packed_stack : Flag<["-"], "mno-packed-stack">, Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group; def mno_mips16 : Flag<["-"], "mno-mips16">, Group; def mmicromips : Flag<["-"], "mmicromips">, Group; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1b8eca0ea0d7..e75dd6badc14 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1991,8 +1991,20 @@ void Clang::AddSparcTargetArgs(const ArgList &Args, void Clang::AddSystemZTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - if (Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false)) + bool HasBackchain = Args.hasFlag(options::OPT_mbackchain, + options::OPT_mno_backchain, false); + bool HasPackedStack = Args.hasFlag(options::OPT_mpacked_stack, + options::OPT_mno_packed_stack, false); + if (HasBackchain && HasPackedStack) { +const Driver &D = getToolChain().getDriver(); +D.Diag(diag::err_drv_unsupported_opt) + << Args.getLastArg(options::OPT_mpacked_stack)->getAsString(Args) + + " " + Args.getLastArg(options::OPT_mbackchain)->getAsString(Args); + } + if (HasBackchain) CmdArgs.push_back("-mbackchain"); + if (HasPackedStack) +CmdArgs.push_back("-mpacked-stack"); } void Clang::AddX86TargetArgs(const ArgList &Args, @@ -5014,8 +5026,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } - Args.AddLastArg(CmdArgs, options::OPT_mpacked_stack); - if (Args.getLastArg(options::OPT_fapple_kext) || (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType))) CmdArgs.push_back("-fapple-kext"); diff --git a/clang/test/Driver/mbackchain.c b/clang/test/Driver/mbackchain.c new file mode 100644 index ..33076829ccd7 --- /dev/null +++ b/clang/test/Driver/mbackchain.c @@ -0,0 +1,3 @@ +// RUN: %clang -target s390x -c -### %s -mpacked-stack -mbackchain 2>&1 | FileCheck %s + +// CHECK: error: unsupported option '-mpacked-stack -mbackchain' diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 3e2b376d3be6..3cdf6bf98ee0 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -68,6 +68,8 @@ static bool usePackedStack(MachineFunction &MF) { bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC; bool BackChain = MF.getFunction().hasFnAttribute("backchain"); bool FramAddressTaken = MF.getFrameInfo().isFrameAddressTaken(); + if (HasPackedStackAttr && BackChain) +report_fatal_error("packed-stack with backchain is currently unsupported."); return HasPackedStackAttr && !IsVarArg && CallConv && !BackChain && !FramAddressTaken; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c78da03 - [clang] Improve handling of physical registers in inline assembly operands.
Author: Jonas Paulsson Date: 2020-10-13T15:09:52+02:00 New Revision: c78da037783bda0f27f4d82060149166e6f0c796 URL: https://github.com/llvm/llvm-project/commit/c78da037783bda0f27f4d82060149166e6f0c796 DIFF: https://github.com/llvm/llvm-project/commit/c78da037783bda0f27f4d82060149166e6f0c796.diff LOG: [clang] Improve handling of physical registers in inline assembly operands. Change EmitAsmStmt() to - Not tie physregs with the "+r" constraint, but instead add the hard register as an input constraint. This makes "+r" and "=r":"r" look the same in the output. Background: Macro intensive user code may contain inline assembly statements with multiple operands constrained to the same physreg. Such a case (with the operand constraints "+r" : "r") currently triggers the TwoAddressInstructionPass assertion against any extra use of a tied register. Furthermore, TwoAddress will insert a COPY to that physreg even though isel has already done so (for the non-tied use), which may lead to a second redundant instruction currently. A simple fix for this is to not emit tied physreg uses in the first place for the "+r" constraint, which is what this patch does. - Give an error on multiple outputs to the same physical register. This should be reported and this is also what GCC does. Review: Ulrich Weigand, Aaron Ballman, Jennifer Yu, Craig Topper Differential Revision: https://reviews.llvm.org/D87279 Added: clang/test/CodeGen/systemz-inline-asm-02.c Modified: clang/lib/CodeGen/CGStmt.cpp clang/test/CodeGen/systemz-inline-asm.c Removed: diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index c9e6ce2df2c0..a69007e67b26 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" @@ -1836,7 +1837,8 @@ SimplifyConstraint(const char *Constraint, const TargetInfo &Target, static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, - const AsmStmt &Stmt, const bool EarlyClobber) { + const AsmStmt &Stmt, const bool EarlyClobber, + std::string *GCCReg = nullptr) { const DeclRefExpr *AsmDeclRef = dyn_cast(&AsmExpr); if (!AsmDeclRef) return Constraint; @@ -1861,6 +1863,8 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, } // Canonicalize the register here before returning it. Register = Target.getNormalizedGCCRegisterName(Register); + if (GCCReg != nullptr) +*GCCReg = Register.str(); return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; } @@ -2059,6 +2063,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // Keep track of out constraints for tied input operand. std::vector OutputConstraints; + // Keep track of defined physregs. + llvm::SmallSet PhysRegOutputs; + // An inline asm can be marked readonly if it meets the following conditions: // - it doesn't have any sideeffects // - it doesn't clobber memory @@ -2078,9 +2085,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { const Expr *OutExpr = S.getOutputExpr(i); OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); +std::string GCCReg; OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, getTarget(), CGM, S, - Info.earlyClobber()); + Info.earlyClobber(), + &GCCReg); +// Give an error on multiple outputs to same physreg. +if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second) + CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg); + OutputConstraints.push_back(OutputConstraint); LValue Dest = EmitLValue(OutExpr); if (!Constraints.empty()) @@ -2167,7 +2180,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize()); - if (Info.allowsRegister()) + // Don't tie physregs. + if (Info.allowsRegister() && GCCReg.empty()) InOutConstraints += llvm::utostr(i); else InOutConstraints += OutputConstraint; diff --git a/clang/test/CodeGen/systemz-inline-asm-02.c b/clang/test/CodeGen/systemz-inline-asm-02.c new file mode 100644 index ..754d7e66f04b --- /dev/null +++ b/clang/test/CodeGen/systemz-inline-asm-02.c @@ -0
[clang] 625fa47 - Revert "[clang] Improve handling of physical registers in inline assembly operands."
Author: Jonas Paulsson Date: 2020-10-14T08:42:51+02:00 New Revision: 625fa47617022b2d1ed7b940f9621162874175ee URL: https://github.com/llvm/llvm-project/commit/625fa47617022b2d1ed7b940f9621162874175ee DIFF: https://github.com/llvm/llvm-project/commit/625fa47617022b2d1ed7b940f9621162874175ee.diff LOG: Revert "[clang] Improve handling of physical registers in inline assembly operands." This reverts commit c78da037783bda0f27f4d82060149166e6f0c796. Temporarily reverted due to https://bugs.llvm.org/show_bug.cgi?id=47837. Added: Modified: clang/lib/CodeGen/CGStmt.cpp clang/test/CodeGen/systemz-inline-asm.c Removed: clang/test/CodeGen/systemz-inline-asm-02.c diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index a69007e67b26..c9e6ce2df2c0 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -21,7 +21,6 @@ #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" @@ -1837,8 +1836,7 @@ SimplifyConstraint(const char *Constraint, const TargetInfo &Target, static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, - const AsmStmt &Stmt, const bool EarlyClobber, - std::string *GCCReg = nullptr) { + const AsmStmt &Stmt, const bool EarlyClobber) { const DeclRefExpr *AsmDeclRef = dyn_cast(&AsmExpr); if (!AsmDeclRef) return Constraint; @@ -1863,8 +1861,6 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, } // Canonicalize the register here before returning it. Register = Target.getNormalizedGCCRegisterName(Register); - if (GCCReg != nullptr) -*GCCReg = Register.str(); return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; } @@ -2063,9 +2059,6 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // Keep track of out constraints for tied input operand. std::vector OutputConstraints; - // Keep track of defined physregs. - llvm::SmallSet PhysRegOutputs; - // An inline asm can be marked readonly if it meets the following conditions: // - it doesn't have any sideeffects // - it doesn't clobber memory @@ -2085,15 +2078,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { const Expr *OutExpr = S.getOutputExpr(i); OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); -std::string GCCReg; OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, getTarget(), CGM, S, - Info.earlyClobber(), - &GCCReg); -// Give an error on multiple outputs to same physreg. -if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second) - CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg); - + Info.earlyClobber()); OutputConstraints.push_back(OutputConstraint); LValue Dest = EmitLValue(OutExpr); if (!Constraints.empty()) @@ -2180,8 +2167,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize()); - // Don't tie physregs. - if (Info.allowsRegister() && GCCReg.empty()) + if (Info.allowsRegister()) InOutConstraints += llvm::utostr(i); else InOutConstraints += OutputConstraint; diff --git a/clang/test/CodeGen/systemz-inline-asm-02.c b/clang/test/CodeGen/systemz-inline-asm-02.c deleted file mode 100644 index 754d7e66f04b.. --- a/clang/test/CodeGen/systemz-inline-asm-02.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \ -// RUN: | FileCheck %s -// REQUIRES: systemz-registered-target - -// Test that an error is given if a physreg is defined by multiple operands. -int test_physreg_defs(void) { - register int l __asm__("r7") = 0; - - // CHECK: error: multiple outputs to hard register: r7 - __asm__("" : "+r"(l), "=r"(l)); - - return l; -} diff --git a/clang/test/CodeGen/systemz-inline-asm.c b/clang/test/CodeGen/systemz-inline-asm.c index 19ab9d092afc..2dc5023c55cb 100644 --- a/clang/test/CodeGen/systemz-inline-asm.c +++ b/clang/test/CodeGen/systemz-inline-asm.c @@ -129,17 +129,3 @@ long double test_f128(long double f, long double g) { // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g) // CHECK: store fp128 [[RESULT]], fp128* [[DEST]] } - -// Test that there are no tied phys
[clang] 42a8286 - Reapply "[clang] Improve handling of physical registers in inline
Author: Jonas Paulsson Date: 2020-10-21T10:53:40+02:00 New Revision: 42a82862b625279028130e62846d057425bca691 URL: https://github.com/llvm/llvm-project/commit/42a82862b625279028130e62846d057425bca691 DIFF: https://github.com/llvm/llvm-project/commit/42a82862b625279028130e62846d057425bca691.diff LOG: Reapply "[clang] Improve handling of physical registers in inline assembly operands." Earlyclobbers are now excepted from this change (original commit: c78da03). Review: Ulrich Weigand, Nick Desaulniers Differential Revision: https://reviews.llvm.org/D87279 Added: clang/test/CodeGen/systemz-inline-asm-02.c Modified: clang/lib/CodeGen/CGStmt.cpp clang/test/CodeGen/aarch64-inline-asm.c clang/test/CodeGen/systemz-inline-asm.c Removed: diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 4b813be086e1..3f8f77654f6d 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" @@ -1953,7 +1954,8 @@ SimplifyConstraint(const char *Constraint, const TargetInfo &Target, static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, - const AsmStmt &Stmt, const bool EarlyClobber) { + const AsmStmt &Stmt, const bool EarlyClobber, + std::string *GCCReg = nullptr) { const DeclRefExpr *AsmDeclRef = dyn_cast(&AsmExpr); if (!AsmDeclRef) return Constraint; @@ -1978,6 +1980,8 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, } // Canonicalize the register here before returning it. Register = Target.getNormalizedGCCRegisterName(Register); + if (GCCReg != nullptr) +*GCCReg = Register.str(); return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; } @@ -2176,6 +2180,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // Keep track of out constraints for tied input operand. std::vector OutputConstraints; + // Keep track of defined physregs. + llvm::SmallSet PhysRegOutputs; + // An inline asm can be marked readonly if it meets the following conditions: // - it doesn't have any sideeffects // - it doesn't clobber memory @@ -2195,9 +2202,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { const Expr *OutExpr = S.getOutputExpr(i); OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); +std::string GCCReg; OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, getTarget(), CGM, S, - Info.earlyClobber()); + Info.earlyClobber(), + &GCCReg); +// Give an error on multiple outputs to same physreg. +if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second) + CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg); + OutputConstraints.push_back(OutputConstraint); LValue Dest = EmitLValue(OutExpr); if (!Constraints.empty()) @@ -2284,7 +2297,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize()); - if (Info.allowsRegister()) + // Only tie earlyclobber physregs. + if (Info.allowsRegister() && (GCCReg.empty() || Info.earlyClobber())) InOutConstraints += llvm::utostr(i); else InOutConstraints += OutputConstraint; diff --git a/clang/test/CodeGen/aarch64-inline-asm.c b/clang/test/CodeGen/aarch64-inline-asm.c index 0889a7157f0b..a6e8faef8b9e 100644 --- a/clang/test/CodeGen/aarch64-inline-asm.c +++ b/clang/test/CodeGen/aarch64-inline-asm.c @@ -74,3 +74,9 @@ void test_gcc_registers(void) { asm volatile("mov r0, r1\n"); // CHECK: call void asm sideeffect "mov r0, r1\0A", ""() } + +void test_tied_earlyclobber(void) { + register int a asm("x1"); + asm("" : "+&r"(a)); + // CHECK: call i32 asm "", "=&{x1},0"(i32 %0) +} diff --git a/clang/test/CodeGen/systemz-inline-asm-02.c b/clang/test/CodeGen/systemz-inline-asm-02.c new file mode 100644 index ..754d7e66f04b --- /dev/null +++ b/clang/test/CodeGen/systemz-inline-asm-02.c @@ -0,0 +1,13 @@ +// RUN: not %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s 2>&1 \ +// RUN: | FileCheck %s +// REQUIRES: systemz-registered-target + +// Test that an error is given if a physreg is defined by multiple operands. +int test_physreg_defs(v
[clang] b3ac5b8 - [SystemZ] Fix vecintrin.h to not emit alignment hints in vec_xl/vec_xst.
Author: Jonas Paulsson Date: 2021-02-12T18:26:36-06:00 New Revision: b3ac5b84cdd46fc62a7215ae6b11f3c005900461 URL: https://github.com/llvm/llvm-project/commit/b3ac5b84cdd46fc62a7215ae6b11f3c005900461 DIFF: https://github.com/llvm/llvm-project/commit/b3ac5b84cdd46fc62a7215ae6b11f3c005900461.diff LOG: [SystemZ] Fix vecintrin.h to not emit alignment hints in vec_xl/vec_xst. vec_xl() and vec_xst() should not emit alignment hints since they take a scalar pointer and also add a byte offset if passed. This patch uses memcpy to achieve the desired result. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D96471 Added: Modified: clang/lib/Headers/vecintrin.h clang/test/CodeGen/SystemZ/builtins-systemz-zvector-constrained.c Removed: diff --git a/clang/lib/Headers/vecintrin.h b/clang/lib/Headers/vecintrin.h index e58c9769e8cb..1fd7436b2c60 100644 --- a/clang/lib/Headers/vecintrin.h +++ b/clang/lib/Headers/vecintrin.h @@ -1016,64 +1016,84 @@ vec_scatter_element(__vector double __vec, static inline __ATTRS_o_ai __vector signed char vec_xl(long __offset, const signed char *__ptr) { - return *(const __vector signed char *) - ((const char *)__ptr + __offset); + __vector signed char V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector signed char)); + return V; } static inline __ATTRS_o_ai __vector unsigned char vec_xl(long __offset, const unsigned char *__ptr) { - return *(const __vector unsigned char *) - ((const char *)__ptr + __offset); + __vector unsigned char V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector unsigned char)); + return V; } static inline __ATTRS_o_ai __vector signed short vec_xl(long __offset, const signed short *__ptr) { - return *(const __vector signed short *) - ((const char *)__ptr + __offset); + __vector signed short V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector signed short)); + return V; } static inline __ATTRS_o_ai __vector unsigned short vec_xl(long __offset, const unsigned short *__ptr) { - return *(const __vector unsigned short *) - ((const char *)__ptr + __offset); + __vector unsigned short V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector unsigned short)); + return V; } static inline __ATTRS_o_ai __vector signed int vec_xl(long __offset, const signed int *__ptr) { - return *(const __vector signed int *) - ((const char *)__ptr + __offset); + __vector signed int V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector signed int)); + return V; } static inline __ATTRS_o_ai __vector unsigned int vec_xl(long __offset, const unsigned int *__ptr) { - return *(const __vector unsigned int *) - ((const char *)__ptr + __offset); + __vector unsigned int V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector unsigned int)); + return V; } static inline __ATTRS_o_ai __vector signed long long vec_xl(long __offset, const signed long long *__ptr) { - return *(const __vector signed long long *) - ((const char *)__ptr + __offset); + __vector signed long long V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector signed long long)); + return V; } static inline __ATTRS_o_ai __vector unsigned long long vec_xl(long __offset, const unsigned long long *__ptr) { - return *(const __vector unsigned long long *) - ((const char *)__ptr + __offset); + __vector unsigned long long V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector unsigned long long)); + return V; } #if __ARCH__ >= 12 static inline __ATTRS_o_ai __vector float vec_xl(long __offset, const float *__ptr) { - return *(const __vector float *) - ((const char *)__ptr + __offset); + __vector float V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector float)); + return V; } #endif static inline __ATTRS_o_ai __vector double vec_xl(long __offset, const double *__ptr) { - return *(const __vector double *) - ((const char *)__ptr + __offset); + __vector double V; + __builtin_memcpy(&V, ((const char *)__ptr + __offset), + sizeof(__vector double)); + return V; } /*-- vec_xld2 ---*/ @@ -1081,64 +1101,82 @@ vec_xl(long __offset, const double *__ptr) { // This prototype is deprecated. static inline __ATTRS_o_ai __vector signed char vec_xld2(long __offset, const signed char *__ptr) { - return *(const __vector signed char *) - ((const char *)__ptr + __offset); + __vector signed char V;
[clang] e57bd1f - [CFE, SystemZ] New target hook testFPKind() for checks of FP values.
Author: Jonas Paulsson Date: 2021-02-18T12:36:46-06:00 New Revision: e57bd1ff4fb65208cb3060b62e1c48aa0aac623f URL: https://github.com/llvm/llvm-project/commit/e57bd1ff4fb65208cb3060b62e1c48aa0aac623f DIFF: https://github.com/llvm/llvm-project/commit/e57bd1ff4fb65208cb3060b62e1c48aa0aac623f.diff LOG: [CFE, SystemZ] New target hook testFPKind() for checks of FP values. The recent commit 00a6254 "Stop traping on sNaN in builtin_isnan" changed the lowering in constrained FP mode of builtin_isnan from an FP comparison to integer operations to avoid trapping. SystemZ has a special instruction "Test Data Class" which is the preferred way to do this check. This patch adds a new target hook "testFPKind()" that lets SystemZ emit the s390_tdc intrinsic instead. testFPKind() takes the BuiltinID as an argument and is expected to soon handle more opcodes than just 'builtin_isnan'. Review: Thomas Preud'homme, Ulrich Weigand Differential Revision: https://reviews.llvm.org/D96568 Added: clang/test/CodeGen/SystemZ/strictfp_builtins.c Modified: clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/TargetInfo.cpp clang/lib/CodeGen/TargetInfo.h Removed: diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ed59a1e3161e..3ab5d2a5b684 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2997,6 +2997,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType(; } +if (Value *Result = getTargetHooks().testFPKind(V, BuiltinID, Builder, CGM)) + return RValue::get(Result); + // NaN has all exp bits set and a non zero significand. Therefore: // isnan(V) == ((exp mask - (abs(V) & exp mask)) < 0) unsigned bitsize = Ty->getScalarSizeInBits(); diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index d42541282aea..a11768d3807b 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -21,6 +21,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/Builtins.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/CodeGen/SwiftCallingConv.h" #include "llvm/ADT/SmallBitVector.h" @@ -30,6 +31,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/IntrinsicsNVPTX.h" +#include "llvm/IR/IntrinsicsS390.h" #include "llvm/IR/Type.h" #include "llvm/Support/raw_ostream.h" #include // std::sort @@ -7200,8 +7202,37 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI) : TargetCodeGenInfo( std::make_unique(CGT, HasVector, SoftFloatABI)) {} -}; + llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID, + CGBuilderTy &Builder, + CodeGenModule &CGM) const override { +assert(V->getType()->isFloatingPointTy() && "V should have an FP type."); +// Only use TDC in constrained FP mode. +if (!Builder.getIsFPConstrained()) + return nullptr; + +llvm::Type *Ty = V->getType(); +if (Ty->isFloatTy() || Ty->isDoubleTy() || Ty->isFP128Ty()) { + llvm::Module &M = CGM.getModule(); + auto &Ctx = M.getContext(); + llvm::Function *TDCFunc = + llvm::Intrinsic::getDeclaration(&M, llvm::Intrinsic::s390_tdc, Ty); + unsigned TDCBits = 0; + switch (BuiltinID) { + case Builtin::BI__builtin_isnan: +TDCBits = 0xf; +break; + default: +break; + } + if (TDCBits) +return Builder.CreateCall( +TDCFunc, +{V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)}); +} +return nullptr; + } +}; } bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const { diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 0df9667e91e1..e6e474544fc4 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CGBuilder.h" #include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" @@ -126,6 +127,16 @@ class TargetCodeGenInfo { return Address; } + /// Performs a target specific test of a floating point value for things + /// like IsNaN, Infinity, ... Nullptr is returned if no implementation + /// exists. + virtual llvm::Value * + testFPKind(llvm::Value *V, unsigned BuiltinID, CGBuilderTy &Builder, + CodeGenModule &CGM) const { +assert(V->getType()->isFloatingPointTy() && "V should have an FP type."); +return nullptr; + } + /// Corrects the low-level
[clang] 9cfd301 - [SystemZ] Test for isinf and isfinite in testFPKind().
Author: Jonas Paulsson Date: 2021-03-15T15:02:39-06:00 New Revision: 9cfd301ec8b5ed6eb49bcc4b85e6f2af1a90b305 URL: https://github.com/llvm/llvm-project/commit/9cfd301ec8b5ed6eb49bcc4b85e6f2af1a90b305 DIFF: https://github.com/llvm/llvm-project/commit/9cfd301ec8b5ed6eb49bcc4b85e6f2af1a90b305.diff LOG: [SystemZ] Test for isinf and isfinite in testFPKind(). Recognize BI__builtin_isinf and BI__builtin_isfinite (and a few other opcodes for finite) in testFPKind() and handle with TDC. Review: Ulrich Weigand. Differential Revision: https://reviews.llvm.org/D97901 Added: Modified: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/SystemZ/strictfp_builtins.c Removed: diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 4f5b928f1fe6..c3df36fc1ea2 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -7218,6 +7218,18 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { case Builtin::BI__builtin_isnan: TDCBits = 0xf; break; + case Builtin::BIfinite: + case Builtin::BI__finite: + case Builtin::BIfinitef: + case Builtin::BI__finitef: + case Builtin::BIfinitel: + case Builtin::BI__finitel: + case Builtin::BI__builtin_isfinite: +TDCBits = 0xfc0; +break; + case Builtin::BI__builtin_isinf: +TDCBits = 0x30; +break; default: break; } diff --git a/clang/test/CodeGen/SystemZ/strictfp_builtins.c b/clang/test/CodeGen/SystemZ/strictfp_builtins.c index 2181da9b8637..58909f16a6dd 100644 --- a/clang/test/CodeGen/SystemZ/strictfp_builtins.c +++ b/clang/test/CodeGen/SystemZ/strictfp_builtins.c @@ -9,7 +9,7 @@ // CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4 // CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4 // CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4 -// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) [[ATTR2:#.*]] +// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) #[[ATTR2:[0-9]+]] // CHECK-NEXT:ret i32 [[TMP1]] // int test_isnan_float(float f) { @@ -21,7 +21,7 @@ int test_isnan_float(float f) { // CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8 // CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8 // CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 -// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) [[ATTR2]] +// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 15) #[[ATTR2]] // CHECK-NEXT:ret i32 [[TMP1]] // int test_isnan_double(double d) { @@ -34,10 +34,84 @@ int test_isnan_double(double d) { // CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8 // CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8 // CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8 -// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) [[ATTR2]] +// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 15) #[[ATTR2]] // CHECK-NEXT:ret i32 [[TMP2]] // int test_isnan_long_double(long double ld) { return __builtin_isnan(ld); } +// CHECK-LABEL: @test_isinf_float( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT:store float [[F:%.*]], float* [[F_ADDR]], align 4 +// CHECK-NEXT:[[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4 +// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 48) #[[ATTR2]] +// CHECK-NEXT:ret i32 [[TMP1]] +// +int test_isinf_float(float f) { + return __builtin_isinf(f); +} + +// CHECK-LABEL: @test_isinf_double( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[D_ADDR:%.*]] = alloca double, align 8 +// CHECK-NEXT:store double [[D:%.*]], double* [[D_ADDR]], align 8 +// CHECK-NEXT:[[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 +// CHECK-NEXT:[[TMP1:%.*]] = call i32 @llvm.s390.tdc.f64(double [[TMP0]], i64 48) #[[ATTR2]] +// CHECK-NEXT:ret i32 [[TMP1]] +// +int test_isinf_double(double d) { + return __builtin_isinf(d); +} + +// CHECK-LABEL: @test_isinf_long_double( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[LD_ADDR:%.*]] = alloca fp128, align 8 +// CHECK-NEXT:[[LD:%.*]] = load fp128, fp128* [[TMP0:%.*]], align 8 +// CHECK-NEXT:store fp128 [[LD]], fp128* [[LD_ADDR]], align 8 +// CHECK-NEXT:[[TMP1:%.*]] = load fp128, fp128* [[LD_ADDR]], align 8 +// CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.s390.tdc.f128(fp128 [[TMP1]], i64 48) #[[ATTR2]] +// CHECK-NEXT:ret i32 [[TMP2]] +// +int test_isinf_long_double(long double ld) { + return __builtin_isinf(ld); +} + +// CHECK-LABEL: @test_isfinite_float( +// CHECK-NEXT: entry: +// CHECK-NEXT:
[clang] 858f347 - [Clang, SystemZ] Add support for option -mno-pic-data-is-text-relative.
Author: Jonas Paulsson Date: 2022-11-17T11:32:32-05:00 New Revision: 858f347c1758e2f1da5a94e3de0baae7cae2a590 URL: https://github.com/llvm/llvm-project/commit/858f347c1758e2f1da5a94e3de0baae7cae2a590 DIFF: https://github.com/llvm/llvm-project/commit/858f347c1758e2f1da5a94e3de0baae7cae2a590.diff LOG: [Clang, SystemZ] Add support for option -mno-pic-data-is-text-relative. Add support for this GCC option which has the purpose of disallowing text relative accesses of module local symbols with PIC. In effect, this changes the code model to "medium". Reviewed By: uweigand, efriedma, MaskRay Differential Revision: https://reviews.llvm.org/D137044 Added: Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/pic.c Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index a501306632afb..f90aea1e21948 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2697,6 +2697,8 @@ def fpic : Flag<["-"], "fpic">, Group; def fno_pic : Flag<["-"], "fno-pic">, Group; def fpie : Flag<["-"], "fpie">, Group; def fno_pie : Flag<["-"], "fno-pie">, Group; +defm pic_data_is_text_relative : SimpleMFlag<"pic-data-is-text-relative", + "Assume", "Don't assume", " data segments are relative to text segment">; def fdirect_access_external_data : Flag<["-"], "fdirect-access-external-data">, Group, Flags<[CC1Option]>, HelpText<"Don't use GOT indirection to reference external data symbols">; def fno_direct_access_external_data : Flag<["-"], "fno-direct-access-external-data">, Group, Flags<[CC1Option]>, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 90c4bb51c6ecf..46f642508 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5104,6 +5104,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, unsigned PICLevel; bool IsPIE; std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(TC, Args); + Arg *LastPICDataRelArg = + Args.getLastArg(options::OPT_mno_pic_data_is_text_relative, + options::OPT_mpic_data_is_text_relative); + bool NoPICDataIsTextRelative = false; + if (LastPICDataRelArg) { +if (LastPICDataRelArg->getOption().matches( +options::OPT_mno_pic_data_is_text_relative)) { + NoPICDataIsTextRelative = true; + if (!PICLevel) +D.Diag(diag::err_drv_argument_only_allowed_with) +<< "-mno-pic-data-is-text-relative" +<< "-fpic/-fpie"; +} +if (!Triple.isSystemZ()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << (NoPICDataIsTextRelative ? "-mno-pic-data-is-text-relative" + : "-mpic-data-is-text-relative") + << RawTriple.str(); + } bool IsROPI = RelocationModel == llvm::Reloc::ROPI || RelocationModel == llvm::Reloc::ROPI_RWPI; @@ -5132,6 +5151,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(PICLevel == 1 ? "1" : "2"); if (IsPIE) CmdArgs.push_back("-pic-is-pie"); +if (NoPICDataIsTextRelative) + CmdArgs.push_back("-mcmodel=medium"); } if (RelocationModel == llvm::Reloc::ROPI || diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c index 0ff07b0f0f453..153437daf9a32 100644 --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -1,5 +1,5 @@ -// Test the driver's control over the PIC behavior. These consist of tests of -// the relocation model flags and the pic level flags passed to CC1. +// Test the driver's control over the PIC behavior. These mainly consist of +// tests of the relocation model flags and the pic level flags passed to CC1. // // CHECK-NO-PIC: "-mrelocation-model" "static" // CHECK-NO-PIC-NOT: "-pic-level" @@ -45,6 +45,11 @@ // // CHECK-NO-UNUSED-ARG-NOT: argument unused during compilation // +// CHECK-NO-PIC-DATA-TEXT-REL: "-mcmodel=medium" +// CHECK-PIC-DATA-TEXT-REL-NOT: "-mcmodel=medium" +// CHECK-NO-PIC-DATA-TEXT-REL-NON-SYSTEMZ: error: unsupported option '-mno-pic-data-is-text-relative' for target 'arm-arm-none-eabi' +// CHECK-PIC-DATA-TEXT-REL-NON-SYSTEMZ: error: unsupported option '-mpic-data-is-text-relative' for target 'arm-arm-none-eabi' +// // RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC // RUN: %clang -c %s -target i386-unknown-unknown -fpic -### 2>&1 \ @@ -313,3 +318,12 @@ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 // RUN: %clang -fPIC -c %s -target armv7-pc-windows-gnu -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC + +// RUN: %clang -c --target=s390x-linux-gnu -mno-pic-data-is-text-relative %s \ +// RUN: -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO
[clang] 0eff46f - [SystemZ] Fix handling of vectors and their exposure of the vector ABI.
Author: Jonas Paulsson Date: 2023-01-27T20:24:09+01:00 New Revision: 0eff46f87f16772f93bdc584865e945162aff170 URL: https://github.com/llvm/llvm-project/commit/0eff46f87f16772f93bdc584865e945162aff170 DIFF: https://github.com/llvm/llvm-project/commit/0eff46f87f16772f93bdc584865e945162aff170.diff LOG: [SystemZ] Fix handling of vectors and their exposure of the vector ABI. - Global vector variables expose the vector ABI through their alignments only if they are >=16 bytes in size. - Vectors passed between functions expose the vector ABI only if they are <=16 bytes in size. LLVM test suite builds with gcc/clang now give the same gnu attributes emitted. Reviewed By: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D141409 Added: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03b.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-08b.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-09b.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17b.c Modified: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c Removed: diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index be1dbe8480c6e..a9119abad81d8 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -7418,18 +7418,28 @@ class SystemZABIInfo : public ABIInfo { }; class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { + ASTContext &Ctx; + + const SystemZABIInfo &getABIInfo() const { +return static_cast(TargetCodeGenInfo::getABIInfo()); + } + // These are used for speeding up the search for a visible vector ABI. mutable bool HasVisibleVecABIFlag = false; mutable std::set SeenTypes; - // Returns true (the first time) if Ty is or found to make use of a vector - // type (e.g. as a function argument). - bool isVectorTypeBased(const Type *Ty) const; + // Returns true (the first time) if Ty is, or is found to include, a vector + // type that exposes the vector ABI. This is any vector >=16 bytes which + // with vector support are aligned to only 8 bytes. When IsParam is true, + // the type belongs to a value as passed between functions. If it is a + // vector <=16 bytes it will be passed in a vector register (if supported). + bool isVectorTypeBased(const Type *Ty, bool IsParam) const; public: SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI) : TargetCodeGenInfo( -std::make_unique(CGT, HasVector, SoftFloatABI)) { +std::make_unique(CGT, HasVector, SoftFloatABI)), +Ctx(CGT.getContext()) { SwiftInfo = std::make_unique(CGT, /*SwiftErrorInRegister=*/false); } @@ -7439,9 +7449,9 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { // indicating a visible vector ABI is added. Eventually this will result in // a GNU attribute indicating the vector ABI of the module. Ty is the type // of a variable or function parameter that is globally visible. - void handleExternallyVisibleObjABI(const Type *Ty, - CodeGen::CodeGenModule &M) const { -if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty)) { + void handleExternallyVisibleObjABI(const Type *Ty, CodeGen::CodeGenModule &M, + bool IsParam) const { +if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) { M.getModule().addModuleFlag(llvm::Module::Warning, "s390x-visible-vector-ABI", 1); HasVisibleVecABIFlag = true; @@ -7457,11 +7467,13 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { // variable or function. if (const auto *VD = dyn_cast(D)) { if (VD->isExternallyVisible()) -handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M); +handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M, + /*IsParam*/false); } else if (const FunctionDecl *FD = dyn_cast(D)) { if (FD->isExternallyVisible()) -handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M); +handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M, + /*IsParam*/false); } } @@ -7571,17 +7583,18 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) - for (const auto &I : CXXRD->bases()) { -QualType Base = I.getType(); + if (CXXRD->hasDefinition()) +for (const auto &I : CXXRD->bases()) { + QualType Base = I.getType(); -// Empty bases don't affect things either way. -if (isEmptyRecord(getContext(), Base, true)) - continue; + // Empty bases don't affect things either way. + if (isEmptyRecord(getContext(), Bas
[clang] 82879c2 - [SystemZ] Support the kernel back chain.
Author: Jonas Paulsson Date: 2020-02-23T13:42:36-08:00 New Revision: 82879c2913da69ef2deadee9d075140a84eb6e8c URL: https://github.com/llvm/llvm-project/commit/82879c2913da69ef2deadee9d075140a84eb6e8c DIFF: https://github.com/llvm/llvm-project/commit/82879c2913da69ef2deadee9d075140a84eb6e8c.diff LOG: [SystemZ] Support the kernel back chain. In order to build the Linux kernel, the back chain must be supported with packed-stack. The back chain is then stored topmost in the register save area. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D74506 Added: llvm/test/CodeGen/SystemZ/frame-23.ll llvm/test/CodeGen/SystemZ/frame-24.ll llvm/test/CodeGen/SystemZ/frameaddr-02.ll Modified: clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/mbackchain.c llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp llvm/lib/Target/SystemZ/SystemZFrameLowering.h llvm/lib/Target/SystemZ/SystemZISelLowering.cpp Removed: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 32b2b417162c..4bd0b5e1fb27 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2007,21 +2007,19 @@ void Clang::AddSystemZTargetArgs(const ArgList &Args, options::OPT_mno_backchain, false); bool HasPackedStack = Args.hasFlag(options::OPT_mpacked_stack, options::OPT_mno_packed_stack, false); - if (HasBackchain && HasPackedStack) { + systemz::FloatABI FloatABI = + systemz::getSystemZFloatABI(getToolChain().getDriver(), Args); + bool HasSoftFloat = (FloatABI == systemz::FloatABI::Soft); + if (HasBackchain && HasPackedStack && !HasSoftFloat) { const Driver &D = getToolChain().getDriver(); D.Diag(diag::err_drv_unsupported_opt) - << Args.getLastArg(options::OPT_mpacked_stack)->getAsString(Args) + - " " + Args.getLastArg(options::OPT_mbackchain)->getAsString(Args); + << "-mpacked-stack -mbackchain -mhard-float"; } if (HasBackchain) CmdArgs.push_back("-mbackchain"); if (HasPackedStack) CmdArgs.push_back("-mpacked-stack"); - - systemz::FloatABI FloatABI = - systemz::getSystemZFloatABI(getToolChain().getDriver(), Args); - - if (FloatABI == systemz::FloatABI::Soft) { + if (HasSoftFloat) { // Floating point operations and argument passing are soft. CmdArgs.push_back("-msoft-float"); CmdArgs.push_back("-mfloat-abi"); diff --git a/clang/test/Driver/mbackchain.c b/clang/test/Driver/mbackchain.c index 33076829ccd7..f0a4f86558d7 100644 --- a/clang/test/Driver/mbackchain.c +++ b/clang/test/Driver/mbackchain.c @@ -1,3 +1,7 @@ // RUN: %clang -target s390x -c -### %s -mpacked-stack -mbackchain 2>&1 | FileCheck %s +// RUN: %clang -target s390x -c -### %s -mpacked-stack -mbackchain -msoft-float \ +// RUN: 2>&1 | FileCheck %s --check-prefix=KERNEL-BUILD +// REQUIRES: systemz-registered-target -// CHECK: error: unsupported option '-mpacked-stack -mbackchain' +// CHECK: error: unsupported option '-mpacked-stack -mbackchain -mhard-float' +// KERNEL-BUILD-NOT: error: unsupported option diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 0d9150394d8c..5b0b56f3e488 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -62,18 +62,6 @@ SystemZFrameLowering::SystemZFrameLowering() RegSpillOffsets[SpillOffsetTable[I].Reg] = SpillOffsetTable[I].Offset; } -static bool usePackedStack(MachineFunction &MF) { - bool HasPackedStackAttr = MF.getFunction().hasFnAttribute("packed-stack"); - bool IsVarArg = MF.getFunction().isVarArg(); - bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC; - bool BackChain = MF.getFunction().hasFnAttribute("backchain"); - bool FramAddressTaken = MF.getFrameInfo().isFrameAddressTaken(); - if (HasPackedStackAttr && BackChain) -report_fatal_error("packed-stack with backchain is currently unsupported."); - return HasPackedStackAttr && !IsVarArg && CallConv && !BackChain && - !FramAddressTaken; -} - bool SystemZFrameLowering:: assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, @@ -87,71 +75,44 @@ assignCalleeSavedSpillSlots(MachineFunction &MF, unsigned LowGPR = 0; unsigned HighGPR = SystemZ::R15D; int StartSPOffset = SystemZMC::CallFrameSize; - int CurrOffset; - if (!usePackedStack(MF)) { -for (auto &CS : CSI) { - unsigned Reg = CS.getReg(); - int Offset = RegSpillOffsets[Reg]; - if (Offset) { -if (SystemZ::GR64BitRegClass.contains(Reg) && StartSPOffset > Offset) { - LowGPR = Reg; - StartSPOffset = Offset; -} -Offset -= SystemZMC::CallFrameSize; -int FrameIdx
[clang] 9376714 - [Clang FE] Recognize -mnop-mcount CL option (SystemZ only).
Author: Jonas Paulsson Date: 2019-11-05T12:12:36+01:00 New Revision: 93767143147b7d765c6ce8123a4226d449228649 URL: https://github.com/llvm/llvm-project/commit/93767143147b7d765c6ce8123a4226d449228649 DIFF: https://github.com/llvm/llvm-project/commit/93767143147b7d765c6ce8123a4226d449228649.diff LOG: [Clang FE] Recognize -mnop-mcount CL option (SystemZ only). Recognize -mnop-mcount from the command line and add a function attribute "mnop-mcount"="true" when passed. When this option is used, a nop is added instead of a call to fentry. This is used when building the Linux Kernel. If this option is passed for any other target than SystemZ, an error is generated. Review: Ulrich Weigand https://reviews.llvm.org/D67763 Added: clang/test/CodeGen/mnop-mcount.c Modified: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/DiagnosticCommonKinds.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp Removed: diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 99559b5abe7b..f0d101534e57 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -112,6 +112,7 @@ VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200) CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled. +CODEGENOPT(MNopMCount , 1, 0) ///< Set when -mnop-mcount is enabled. CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to ///< be generated. CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 7a416c282e3d..d6281f157eea 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -271,6 +271,8 @@ def err_target_unsupported_mcmse : Error< "-mcmse is not supported for %0">; def err_opt_not_valid_with_opt : Error< "option '%0' cannot be specified with '%1'">; +def err_opt_not_valid_without_opt : Error< + "option '%0' cannot be specified without '%1'">; def err_opt_not_valid_on_target : Error< "option '%0' cannot be specified on this target">; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d75a0f601d7e..fa609281a6cc 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2448,6 +2448,8 @@ def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, Group def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group; def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">, Flags<[CC1Option]>, Group; +def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">, + Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group; def mno_mips16 : Flag<["-"], "mno-mips16">, Group; def mmicromips : Flag<["-"], "mmicromips">, Group; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1b1d391a63df..89dd06948baa 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -893,6 +893,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, Fn->addFnAttr("instrument-function-entry-inlined", getTarget().getMCountName()); } + if (CGM.getCodeGenOpts().MNopMCount) { +if (getContext().getTargetInfo().getTriple().getArch() != +llvm::Triple::systemz) + CGM.getDiags().Report(diag::err_opt_not_valid_on_target) +<< "-mnop-mcount"; +if (!CGM.getCodeGenOpts().CallFEntry) + CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) +<< "-mnop-mcount" << "-mfentry"; +Fn->addFnAttr("mnop-mcount", "true"); + } } } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 16bf68254d19..6f3f7bfe61f4 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4616,6 +4616,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (TC.SupportsProfiling()) Args.AddLastArg(CmdArgs, options::OPT_mfentry); + if (TC.SupportsProfiling()) +Args.AddLastArg(CmdArgs, options::OPT_mnop_mcount); + if (Args.getLastArg(options::OPT_fapple_kext) || (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType))) CmdArgs.push_back("-fapple-kext"); diff --git a/clang
[clang] 599d1cc - [Clang FE, SystemZ] Recognize -mpacked-stack CL option
Author: Jonas Paulsson Date: 2019-12-17T11:26:17-08:00 New Revision: 599d1cc07a51e9a556afa2a995930f7ffe0e42cd URL: https://github.com/llvm/llvm-project/commit/599d1cc07a51e9a556afa2a995930f7ffe0e42cd DIFF: https://github.com/llvm/llvm-project/commit/599d1cc07a51e9a556afa2a995930f7ffe0e42cd.diff LOG: [Clang FE, SystemZ] Recognize -mpacked-stack CL option Recognize -mpacked-stack from the command line and add a function attribute "mpacked-stack" when passed. This is needed for building the Linux kernel. If this option is passed for any other target than SystemZ, an error is generated. Review: Ulrich Weigand https://reviews.llvm.org/D71441 Added: clang/test/CodeGen/packed-stack.c Modified: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp Removed: diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index c8d03f2bb2aa..c6700333c13a 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -113,6 +113,7 @@ VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200) CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled. CODEGENOPT(MNopMCount , 1, 0) ///< Set when -mnop-mcount is enabled. +CODEGENOPT(PackedStack , 1, 0) ///< Set when -mpacked-stack is enabled. CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to ///< be generated. CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index b4ff681c70f8..38504d6330da 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2474,6 +2474,8 @@ def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at functi Flags<[CC1Option]>, Group; def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">, Flags<[CC1Option]>, Group; +def mpacked_stack : Flag<["-"], "mpacked-stack">, HelpText<"Use packed stack layout (SystemZ only).">, + Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group; def mno_mips16 : Flag<["-"], "mno-mips16">, Group; def mmicromips : Flag<["-"], "mmicromips">, Group; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index a2d34d41db2e..0db17431814f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -971,6 +971,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } } + if (CGM.getCodeGenOpts().PackedStack) { +if (getContext().getTargetInfo().getTriple().getArch() != +llvm::Triple::systemz) + CGM.getDiags().Report(diag::err_opt_not_valid_on_target) +<< "-mpacked-stack"; +Fn->addFnAttr("packed-stack"); + } + if (RetTy->isVoidType()) { // Void type; nothing to return. ReturnValue = Address::invalid(); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 5c28a3ab1735..5bf0efcf0503 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5014,6 +5014,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (TC.SupportsProfiling()) Args.AddLastArg(CmdArgs, options::OPT_mnop_mcount); + Args.AddLastArg(CmdArgs, options::OPT_mpacked_stack); + if (Args.getLastArg(options::OPT_fapple_kext) || (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType))) CmdArgs.push_back("-fapple-kext"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 852adbbdea58..23de18babda1 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1104,6 +1104,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.CallFEntry = Args.hasArg(OPT_mfentry); Opts.MNopMCount = Args.hasArg(OPT_mnop_mcount); + Opts.PackedStack = Args.hasArg(OPT_mpacked_stack); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) { diff --git a/clang/test/CodeGen/packed-stack.c b/clang/test/CodeGen/packed-stack.c new file mode 100644 index ..eaf00a7f8b0e --- /dev/null +++ b/clang/test/CodeGen/packed-stack.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -mpacked-stack -triple s390x-ibm-linux -emit-llvm \ +// RUN: -o - %s 2>&1 | FileCheck %s +/
[clang] ca52059 - [Clang FE, SystemZ] Don't add "true" value for the "mnop-mcount" attribute.
Author: Jonas Paulsson Date: 2019-12-18T11:04:13-08:00 New Revision: ca520592c081a76b45613ec794ebee4920933c1c URL: https://github.com/llvm/llvm-project/commit/ca520592c081a76b45613ec794ebee4920933c1c DIFF: https://github.com/llvm/llvm-project/commit/ca520592c081a76b45613ec794ebee4920933c1c.diff LOG: [Clang FE, SystemZ] Don't add "true" value for the "mnop-mcount" attribute. Let the "mnop-mcount" function attribute simply be present or non-present. Update SystemZ backend as well to use hasFnAttribute() instead. Review: Ulrich Weigand https://reviews.llvm.org/D71669 Added: Modified: clang/lib/CodeGen/CodeGenFunction.cpp clang/test/CodeGen/mnop-mcount.c llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll Removed: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 0db17431814f..89ce31e9b450 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -966,7 +966,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (!CGM.getCodeGenOpts().CallFEntry) CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) << "-mnop-mcount" << "-mfentry"; -Fn->addFnAttr("mnop-mcount", "true"); +Fn->addFnAttr("mnop-mcount"); } } } diff --git a/clang/test/CodeGen/mnop-mcount.c b/clang/test/CodeGen/mnop-mcount.c index 08d000dc4131..a6b10b625050 100644 --- a/clang/test/CodeGen/mnop-mcount.c +++ b/clang/test/CodeGen/mnop-mcount.c @@ -17,9 +17,9 @@ int __attribute__((no_instrument_function)) no_instrument(void) { return foo(); } -//CHECK: attributes #0 = { {{.*}}"mnop-mcount"="true"{{.*}} } +//CHECK: attributes #0 = { {{.*}}"mnop-mcount"{{.*}} } //CHECK: attributes #1 = { {{.*}} } -//CHECK-NOT: attributes #1 = { {{.*}}"mnop-mcount"="true"{{.*}} } +//CHECK-NOT: attributes #1 = { {{.*}}"mnop-mcount"{{.*}} } //NOMFENTRY: error: option '-mnop-mcount' cannot be specified without '-mfentry' //NOPG-NOT: attributes #0 = { {{.*}}"mnop-mcount"{{.*}} } //NOPG-NOT: attributes #1 = { {{.*}}"mnop-mcount"{{.*}} } diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 10023e9e169c..34f7bc99a0d7 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -553,8 +553,7 @@ static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &Lower) { MCContext &Ctx = MF->getContext(); - if (MF->getFunction().getFnAttribute("mnop-mcount") - .getValueAsString() == "true") { + if (MF->getFunction().hasFnAttribute("mnop-mcount")) { EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); return; } diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 751034c2d41a..0bcbce68a5fe 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -347,7 +347,7 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { bool runOnMachineFunction(MachineFunction &MF) override { const Function &F = MF.getFunction(); -if (F.getFnAttribute("mnop-mcount").getValueAsString() == "true" && +if (F.hasFnAttribute("mnop-mcount") && F.getFnAttribute("fentry-call").getValueAsString() != "true") report_fatal_error("mnop-mcount only supported with fentry-call"); diff --git a/llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll b/llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll index 38f1db537b52..99aff5a223e6 100644 --- a/llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll +++ b/llvm/test/CodeGen/SystemZ/mnop-mcount-01.ll @@ -22,5 +22,5 @@ entry: } attributes #0 = { "fentry-call"="true" } -attributes #1 = { "fentry-call"="true" "mnop-mcount"="true" } +attributes #1 = { "fentry-call"="true" "mnop-mcount" } diff --git a/llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll b/llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll index 19b1724d16ad..4a3629111318 100644 --- a/llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll +++ b/llvm/test/CodeGen/SystemZ/mnop-mcount-02.ll @@ -7,5 +7,4 @@ entry: ret void } -attributes #0 = { "instrument-function-entry-inlined"="mcount" "mnop-mcount"="true" } - +attributes #0 = { "instrument-function-entry-inlined"="mcount" "mnop-mcount" } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 2520bef - [Clang FE, SystemZ] Recognize -mrecord-mcount CL option.
Author: Jonas Paulsson Date: 2019-12-19T08:51:55-08:00 New Revision: 2520bef865329d4c04e2de30c222ad0d5ad13ccc URL: https://github.com/llvm/llvm-project/commit/2520bef865329d4c04e2de30c222ad0d5ad13ccc DIFF: https://github.com/llvm/llvm-project/commit/2520bef865329d4c04e2de30c222ad0d5ad13ccc.diff LOG: [Clang FE, SystemZ] Recognize -mrecord-mcount CL option. Recognize -mrecord-mcount from the command line and add a function attribute "mrecord-mcount" when passed. Only valid on SystemZ (when used with -mfentry). Review: Ulrich Weigand https://reviews.llvm.org/D71627 Added: clang/test/CodeGen/mrecord-mcount.c Modified: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp Removed: diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index c6700333c13a..7f26ca8b4d61 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -113,6 +113,7 @@ VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200) CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled. CODEGENOPT(MNopMCount , 1, 0) ///< Set when -mnop-mcount is enabled. +CODEGENOPT(RecordMCount , 1, 0) ///< Set when -mrecord-mcount is enabled. CODEGENOPT(PackedStack , 1, 0) ///< Set when -mpacked-stack is enabled. CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to ///< be generated. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2a72b87355d0..86aee334436a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2477,6 +2477,8 @@ def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at functi Flags<[CC1Option]>, Group; def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">, Flags<[CC1Option]>, Group; +def mrecord_mcount : Flag<["-"], "mrecord-mcount">, HelpText<"Generate a __mcount_loc section entry for each __fentry__ call.">, + Flags<[CC1Option]>, Group; def mpacked_stack : Flag<["-"], "mpacked-stack">, HelpText<"Use packed stack layout (SystemZ only).">, Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 89ce31e9b450..6f7e06b773dc 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -968,6 +968,17 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, << "-mnop-mcount" << "-mfentry"; Fn->addFnAttr("mnop-mcount"); } + + if (CGM.getCodeGenOpts().RecordMCount) { +if (getContext().getTargetInfo().getTriple().getArch() != +llvm::Triple::systemz) + CGM.getDiags().Report(diag::err_opt_not_valid_on_target) +<< "-mrecord-mcount"; +if (!CGM.getCodeGenOpts().CallFEntry) + CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) +<< "-mrecord-mcount" << "-mfentry"; +Fn->addFnAttr("mrecord-mcount"); + } } } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index a79c96d25d98..6b93dc2939e1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4990,6 +4990,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (TC.SupportsProfiling()) Args.AddLastArg(CmdArgs, options::OPT_mnop_mcount); + if (TC.SupportsProfiling()) +Args.AddLastArg(CmdArgs, options::OPT_mrecord_mcount); + Args.AddLastArg(CmdArgs, options::OPT_mpacked_stack); if (Args.getLastArg(options::OPT_fapple_kext) || diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index d68244dce5c4..93193edff9c9 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1104,6 +1104,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.CallFEntry = Args.hasArg(OPT_mfentry); Opts.MNopMCount = Args.hasArg(OPT_mnop_mcount); + Opts.RecordMCount = Args.hasArg(OPT_mrecord_mcount); Opts.PackedStack = Args.hasArg(OPT_mpacked_stack); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); diff --git a/clang/test/CodeGen/mrecord-mcount.c b/clang/test/CodeGen/mrecord-mcount.c new file mode 100644 index ..eecee0e24cdc --- /dev/null +++ b/clang/test/CodeGen/m
[clang] 563e847 - [SystemZ] Support -msoft-float
Author: Jonas Paulsson Date: 2020-02-04T10:32:45-05:00 New Revision: 563e84790f41f9f71c3cb10d0bb9feaa7a339c36 URL: https://github.com/llvm/llvm-project/commit/563e84790f41f9f71c3cb10d0bb9feaa7a339c36 DIFF: https://github.com/llvm/llvm-project/commit/563e84790f41f9f71c3cb10d0bb9feaa7a339c36.diff LOG: [SystemZ] Support -msoft-float This is needed when building the Linux kernel. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D72189 Added: clang/test/Driver/systemz-float-01.c clang/test/Driver/systemz-float-02.c llvm/test/CodeGen/SystemZ/soft-float-01.ll llvm/test/CodeGen/SystemZ/soft-float-02.ll llvm/test/CodeGen/SystemZ/soft-float-03.ll llvm/test/CodeGen/SystemZ/soft-float-04.ll llvm/test/CodeGen/SystemZ/soft-float-args.ll llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll Modified: clang/lib/Basic/Targets/SystemZ.h clang/lib/CodeGen/TargetInfo.cpp clang/lib/Driver/ToolChains/Arch/SystemZ.cpp clang/lib/Driver/ToolChains/Arch/SystemZ.h clang/lib/Driver/ToolChains/Clang.cpp clang/test/CodeGen/systemz-abi.c clang/test/CodeGen/systemz-abi.cpp clang/test/CodeGen/target-data.c llvm/lib/Target/SystemZ/SystemZFeatures.td llvm/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/lib/Target/SystemZ/SystemZISelLowering.h llvm/lib/Target/SystemZ/SystemZSubtarget.cpp llvm/lib/Target/SystemZ/SystemZSubtarget.h llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp llvm/test/CodeGen/SystemZ/args-07.ll llvm/test/CodeGen/SystemZ/vec-abi-align.ll llvm/test/CodeGen/SystemZ/vec-args-06.ll llvm/test/CodeGen/SystemZ/vec-args-07.ll Removed: diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index e751806f4747..9f7ce62d2ce6 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -29,11 +29,12 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { int ISARevision; bool HasTransactionalExecution; bool HasVector; + bool SoftFloat; public: SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), CPU("z10"), ISARevision(8), -HasTransactionalExecution(false), HasVector(false) { +HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { IntMaxType = SignedLong; Int64Type = SignedLong; TLSSupported = true; @@ -109,12 +110,17 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { DiagnosticsEngine &Diags) override { HasTransactionalExecution = false; HasVector = false; +SoftFloat = false; for (const auto &Feature : Features) { if (Feature == "+transactional-execution") HasTransactionalExecution = true; else if (Feature == "+vector") HasVector = true; + else if (Feature == "+soft-float") +SoftFloat = true; } +HasVector &= !SoftFloat; + // If we use the vector ABI, vector types are 64-bit aligned. if (HasVector) { MaxVectorAlign = 64; diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index c803785435ff..94d0f3dac70a 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -6565,10 +6565,11 @@ namespace { class SystemZABIInfo : public SwiftABIInfo { bool HasVector; + bool IsSoftFloatABI; public: - SystemZABIInfo(CodeGenTypes &CGT, bool HV) -: SwiftABIInfo(CGT), HasVector(HV) {} + SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF) +: SwiftABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {} bool isPromotableIntegerType(QualType Ty) const; bool isCompoundType(QualType Ty) const; @@ -6600,8 +6601,8 @@ class SystemZABIInfo : public SwiftABIInfo { class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { public: - SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector) -: TargetCodeGenInfo(new SystemZABIInfo(CGT, HasVector)) {} + SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI) +: TargetCodeGenInfo(new SystemZABIInfo(CGT, HasVector, SoftFloatABI)) {} }; } @@ -6640,6 +6641,9 @@ bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const { } bool SystemZABIInfo::isFPArgumentType(QualType Ty) const { + if (IsSoftFloatABI) +return false; + if (const BuiltinType *BT = Ty->getAs()) switch (BT->getKind()) { case BuiltinType::Float: @@ -6725,7 +6729,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, } else { if (AI.getCoerceToType()) ArgTy = AI.getCoerceToType(); -InFPRs = ArgTy->isFloatTy() || ArgTy->isDoubleTy(); +InFPRs = (!IsSoftFloatABI && (ArgTy->isFloatTy() || ArgTy->isDoubleT
[clang] e943329 - [SystemZ] Add 'REQUIRES:' or '-mtriple' to some newly added tests.
Author: Jonas Paulsson Date: 2020-02-04T10:52:10-05:00 New Revision: e943329ba00772f96fbc1fe5dec836cfd0707a38 URL: https://github.com/llvm/llvm-project/commit/e943329ba00772f96fbc1fe5dec836cfd0707a38 DIFF: https://github.com/llvm/llvm-project/commit/e943329ba00772f96fbc1fe5dec836cfd0707a38.diff LOG: [SystemZ] Add 'REQUIRES:' or '-mtriple' to some newly added tests. Needed to fix buildbots. Added: Modified: clang/test/Driver/systemz-float-02.c llvm/test/CodeGen/SystemZ/soft-float-01.ll llvm/test/CodeGen/SystemZ/soft-float-03.ll llvm/test/CodeGen/SystemZ/soft-float-04.ll llvm/test/CodeGen/SystemZ/soft-float-args.ll llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll Removed: diff --git a/clang/test/Driver/systemz-float-02.c b/clang/test/Driver/systemz-float-02.c index c18a7fa6cdf1..d9ec329485a4 100644 --- a/clang/test/Driver/systemz-float-02.c +++ b/clang/test/Driver/systemz-float-02.c @@ -1,4 +1,5 @@ // RUN: %clang -target s390x-linux-gnu -march=z13 -S %s -o - -msoft-float | FileCheck %s +// REQUIRES: systemz-registered-target // // Check that -msoft-float works all the way to assembly output. diff --git a/llvm/test/CodeGen/SystemZ/soft-float-01.ll b/llvm/test/CodeGen/SystemZ/soft-float-01.ll index 0d70075d5df5..cba8124a6141 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-01.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-01.ll @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=z10 -mattr=soft-float -O0 < %s | FileCheck %s +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z10 -mattr=soft-float -O0 < %s | FileCheck %s ; Arithmetic functions diff --git a/llvm/test/CodeGen/SystemZ/soft-float-03.ll b/llvm/test/CodeGen/SystemZ/soft-float-03.ll index 96cc03676e30..a53bf357d60b 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-03.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-03.ll @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s ; ; Check that soft-float implies "-vector". diff --git a/llvm/test/CodeGen/SystemZ/soft-float-04.ll b/llvm/test/CodeGen/SystemZ/soft-float-04.ll index e939b300c842..1dbe843090b0 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-04.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-04.ll @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=z14 -O3 -mattr=soft-float < %s | FileCheck %s +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z14 -O3 -mattr=soft-float < %s | FileCheck %s ; ; Check that this function with soft-float does not result in a s390.tdc ; intrinsic (which cannot be handled by SoftenFloatOperand). diff --git a/llvm/test/CodeGen/SystemZ/soft-float-args.ll b/llvm/test/CodeGen/SystemZ/soft-float-args.ll index d9dc305502c3..06b362672b1f 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-args.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-args.ll @@ -1,4 +1,4 @@ -; RUN: llc -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s ; ; Test that arguments and return values of fp/vector types are always handled ; with gprs with soft-float. diff --git a/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll b/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll index 0d84c9056f51..728ff2f51263 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-01.ll @@ -1,4 +1,4 @@ -; RUN: not llc < %s -mcpu=z13 -mattr=soft-float -O3 2>&1 | FileCheck %s +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 2>&1 | FileCheck %s ; ; Verify that inline asms cannot use fp/vector registers with soft-float. diff --git a/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll b/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll index 3db346d8214c..c523c05981d8 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-02.ll @@ -1,4 +1,4 @@ -; RUN: not llc < %s -mcpu=z13 -mattr=soft-float -O3 2>&1 | FileCheck %s +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 2>&1 | FileCheck %s ; ; Verify that inline asms cannot use fp/vector registers with soft-float. diff --git a/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll b/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll index e31434c5b55d..f382ad367aaa 100644 --- a/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll +++ b/llvm/test/CodeGen/SystemZ/soft-float-inline-asm-03.ll @@ -1,4 +1,4 @@ -; RUN: not llc < %s -mcpu=z13 -mattr=soft-float -O3 2>&1 | FileCheck %s +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 2>&1 | FileCheck %s ; ; Verify that inline asms cannot use fp/vector registers with
[clang] 7501e53 - [Clang] Give warning for an underaligned 128-bit __sync library call.
Author: Jonas Paulsson Date: 2023-03-15T12:46:06+01:00 New Revision: 7501e53b8d6d7563b047a34d0141630d5afc86c5 URL: https://github.com/llvm/llvm-project/commit/7501e53b8d6d7563b047a34d0141630d5afc86c5 DIFF: https://github.com/llvm/llvm-project/commit/7501e53b8d6d7563b047a34d0141630d5afc86c5.diff LOG: [Clang] Give warning for an underaligned 128-bit __sync library call. On SystemZ, int128 values are generally aligned to only 8 bytes per the ABI while 128 bit atomic ISA instructions exist with a full 16 byte alignment requirement. __sync builtins are emitted as atomicrmw instructions which always require the natural alignment (16 bytes in this case), and they always get it regardless of the alignment of the value being addressed. This patch improves this situation by giving a warning if the alignment is not known to be sufficient. This check is done in CodeGen instead of in Sema as this is currently the only place where the alignment can be computed. This could/should be moved into Sema in case the alignment computation could be made there eventually. Reviewed By: efriedma, jyknight, uweigand Differential Revision: https://reviews.llvm.org/D143813 Added: clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c Modified: clang/include/clang/Basic/DiagnosticFrontendKinds.td clang/include/clang/Basic/DiagnosticGroups.td clang/lib/CodeGen/CGBuiltin.cpp Removed: diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index b35c697701c1d..c1a71d51d91bc 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -309,6 +309,10 @@ def warn_atomic_op_oversized : Warning< "; the access size (%0 bytes) exceeds the max lock-free size (%1 bytes)">, InGroup; +def warn_sync_op_misaligned : Warning< + "__sync builtin operation MUST have natural alignment (consider using __atomic).">, + InGroup; + def warn_alias_with_section : Warning< "%select{alias|ifunc}1 will not be in section '%0' but in the same section " "as the %select{aliasee|resolver}2">, diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 866dca0083810..274f58b1a5ff0 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -801,6 +801,7 @@ def AtomicAlignment : DiagGroup<"atomic-alignment">; def CustomAtomic : DiagGroup<"custom-atomic-properties">; def AtomicProperties : DiagGroup<"atomic-properties", [ImplicitAtomic, CustomAtomic]>; +def SyncAlignment : DiagGroup<"sync-alignment">; def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">; def ARCRetainCycles : DiagGroup<"arc-retain-cycles">; def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index fa8703b1e5202..572d742f36a98 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -28,6 +28,7 @@ #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallPtrSet.h" @@ -223,9 +224,23 @@ static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); } +static void CheckAtomicAlignment(CodeGenFunction &CGF, const CallExpr *E) { + ASTContext &Ctx = CGF.getContext(); + Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0)); + unsigned Bytes = Ptr.getElementType()->isPointerTy() + ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity() + : Ptr.getElementType()->getScalarSizeInBits() / 8; + unsigned Align = Ptr.getAlignment().getQuantity(); + if (Align % Bytes != 0) { +DiagnosticsEngine &Diags = CGF.CGM.getDiags(); +Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned); + } +} + static RValue EmitBinaryAtomic(CodeGenFunction &CGF, llvm::AtomicRMWInst::BinOp Kind, const CallExpr *E) { + CheckAtomicAlignment(CGF, E); return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); } @@ -237,6 +252,7 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, const CallExpr *E, Instruction::BinaryOps Op, bool Invert = false) { + CheckAtomicAlignment(CGF, E); QualType T = E->getType(); assert(E->getArg(0)->getType()->isPointerType()); assert(CGF.getContext().hasSameUnqualifiedType(T, @@ -284,6 +300,7 @@ static RValue
[clang] 790c9ac - [ClangFE] Handle statement expressions properly with CheckAtomicAlignment().
Author: Jonas Paulsson Date: 2023-04-18T19:33:32+02:00 New Revision: 790c9ac529c9ad0d7e89e3de2041d85cfc411b40 URL: https://github.com/llvm/llvm-project/commit/790c9ac529c9ad0d7e89e3de2041d85cfc411b40 DIFF: https://github.com/llvm/llvm-project/commit/790c9ac529c9ad0d7e89e3de2041d85cfc411b40.diff LOG: [ClangFE] Handle statement expressions properly with CheckAtomicAlignment(). Make CheckAtomicAlignment() return the computed pointer for reuse to avoid emitting it twice. Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D148422 Added: Modified: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/SystemZ/sync-builtins-i128-16Al.c Removed: diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 1d79d9a146353..ec1698c4117b8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -170,6 +170,21 @@ static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, return V; } +static llvm::Value *CheckAtomicAlignment(CodeGenFunction &CGF, + const CallExpr *E) { + ASTContext &Ctx = CGF.getContext(); + Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0)); + unsigned Bytes = Ptr.getElementType()->isPointerTy() + ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity() + : Ptr.getElementType()->getScalarSizeInBits() / 8; + unsigned Align = Ptr.getAlignment().getQuantity(); + if (Align % Bytes != 0) { +DiagnosticsEngine &Diags = CGF.CGM.getDiags(); +Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned); + } + return Ptr.getPointer(); +} + /// Utility to insert an atomic instruction based on Intrinsic::ID /// and the expression node. static Value *MakeBinaryAtomicValue( @@ -182,7 +197,7 @@ static Value *MakeBinaryAtomicValue( E->getArg(0)->getType()->getPointeeType())); assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); - llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E); unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); llvm::IntegerType *IntType = @@ -224,23 +239,9 @@ static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); } -static void CheckAtomicAlignment(CodeGenFunction &CGF, const CallExpr *E) { - ASTContext &Ctx = CGF.getContext(); - Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0)); - unsigned Bytes = Ptr.getElementType()->isPointerTy() - ? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity() - : Ptr.getElementType()->getScalarSizeInBits() / 8; - unsigned Align = Ptr.getAlignment().getQuantity(); - if (Align % Bytes != 0) { -DiagnosticsEngine &Diags = CGF.CGM.getDiags(); -Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned); - } -} - static RValue EmitBinaryAtomic(CodeGenFunction &CGF, llvm::AtomicRMWInst::BinOp Kind, const CallExpr *E) { - CheckAtomicAlignment(CGF, E); return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); } @@ -252,14 +253,13 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, const CallExpr *E, Instruction::BinaryOps Op, bool Invert = false) { - CheckAtomicAlignment(CGF, E); QualType T = E->getType(); assert(E->getArg(0)->getType()->isPointerType()); assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(0)->getType()->getPointeeType())); assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); - llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E); unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); llvm::IntegerType *IntType = @@ -300,9 +300,8 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, /// invoke the function EmitAtomicCmpXchgForMSIntrin. static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E, bool ReturnBool) { - CheckAtomicAlignment(CGF, E); QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType(); - llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E); unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); llvm::IntegerType *IntType = llvm::IntegerType::get( @@ -4045,8 +4044,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__sync_lock_release_4: case Builtin::BI__sync_lock_release_8: case Builtin::BI__sync_lock_re
[clang] 481bb44 - [SystemZ] Emit a .gnu_attribute for an externally visible vector abi.
Author: Jonas Paulsson Date: 2022-12-06T12:53:40-06:00 New Revision: 481bb44baab5ce7a005b7d7eee6cafbde672695c URL: https://github.com/llvm/llvm-project/commit/481bb44baab5ce7a005b7d7eee6cafbde672695c DIFF: https://github.com/llvm/llvm-project/commit/481bb44baab5ce7a005b7d7eee6cafbde672695c.diff LOG: [SystemZ] Emit a .gnu_attribute for an externally visible vector abi. On SystemZ, the vector ABI changes depending on the presence of hardware vector support. Therefore, each binary compiled with a visible vector ABI (e.g. one that calls an external function with a vector argument) should be marked with a .gnu_attribute describing this. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D105067 Added: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-00.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-01.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-02.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-04.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-05.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-06.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-07.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-08.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-09.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-10.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-11.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-12.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-13.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-14.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-15.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-16.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-18.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-19.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-20.cpp clang/test/CodeGen/SystemZ/vec-abi-gnuattr-21.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-22.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-23.c clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c llvm/test/MC/SystemZ/gnu-attributes.s Modified: clang/lib/CodeGen/CodeGenTypes.h clang/lib/CodeGen/TargetInfo.cpp llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp llvm/lib/Target/SystemZ/SystemZAsmPrinter.h Removed: diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 69acf605dc36b..e76fda95513f6 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -109,6 +109,7 @@ class CodeGenTypes { const llvm::DataLayout &getDataLayout() const { return TheModule.getDataLayout(); } + CodeGenModule &getCGM() const { return CGM; } ASTContext &getContext() const { return Context; } const ABIInfo &getABIInfo() const { return TheABIInfo; } const TargetInfo &getTarget() const { return Target; } diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 8be0625120ec8..bcb0e7b085743 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -7402,18 +7402,20 @@ class SystemZABIInfo : public ABIInfo { ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType ArgTy) const; - void computeInfo(CGFunctionInfo &FI) const override { -if (!getCXXABI().classifyReturnType(FI)) - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); -for (auto &I : FI.arguments()) - I.info = classifyArgumentType(I.type); - } - + void computeInfo(CGFunctionInfo &FI) const override; Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override; }; class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { + // These are used for speeding up the search for a visible vector ABI. + mutable bool HasVisibleVecABIFlag = false; + mutable std::set SeenTypes; + + // Returns true (the first time) if Ty is or found to make use of a vector + // type (e.g. as a function argument). + bool isVectorTypeBased(const Type *Ty) const; + public: SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI) : TargetCodeGenInfo( @@ -7422,6 +7424,37 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { std::make_unique(CGT, /*SwiftErrorInRegister=*/false); } + // The vector ABI is diff erent when the vector facility is present and when + // a module e.g. defines an externally visible vector variable, a flag + // indicating a visible vector ABI is added. Eventually this will result in + // a GNU attribute indicating the vector ABI of the module. Ty is the type + // of a variable or function parameter that is globally visible. + void handleExternallyVisibleObjABI(const Type *Ty, + CodeGen::CodeGenModule &M) const { +if (!HasVisibleVecABIFlag