[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/71452 Emission of `mustprogress` attribute was previously occuring only when entering `EmitFunctionBody`. Other paths for function body generation may lack the attribute, potentially leading to suboptimal optimizations later in the pipeline. This has been addressed by deferring the attribute emission after the function body has been generated across all the paths. >From f4a92a64c38c726ea091fc21328ee244ac437be0 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Mon, 6 Nov 2023 23:20:31 +0100 Subject: [PATCH] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission Emission of `mustprogress` attribute was previously occuring only when entering `EmitFunctionBody`. Other paths for function body generation may lack the attribute, potentially leading to suboptimal optimizations later in the pipeline. This has been addressed by deferring the attribute emission after the function body has been generated across all the paths. --- clang/lib/CodeGen/CodeGenFunction.cpp | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 6a910abcfe21d2f..f4e2dc373be7f24 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1262,11 +1262,6 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { EmitCompoundStmtWithoutScope(*S); else EmitStmt(Body); - - // This is checked after emitting the function body so we know if there - // are any permitted infinite loops. - if (checkIfFunctionMustProgress()) -CurFn->addFnAttr(llvm::Attribute::MustProgress); } /// When instrumenting to collect profile data, the counts for some blocks @@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. + if (checkIfFunctionMustProgress()) +CurFn->addFnAttr(llvm::Attribute::MustProgress); + // C++11 [stmt.return]p2: // Flowing off the end of a function [...] results in undefined behavior in // a value-returning function. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/71452 >From e02ce12599aabe00e10fc0f8297b3c1bfd46456c Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Mon, 6 Nov 2023 23:20:31 +0100 Subject: [PATCH] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission Emission of `mustprogress` attribute previously occurred only within `EmitFunctionBody`. Other routines for generating function body may lack the attribute, potentially leading to suboptimal optimizations later in the pipeline. Attribute emission is now deferred after the function body has been generated across all the paths. --- clang/lib/CodeGen/CodeGenFunction.cpp | 10 +- clang/test/CXX/special/class.dtor/p3-0x.cpp | 2 +- clang/test/CodeGen/fp-floatcontrol-stack.cpp | 10 +- clang/test/CodeGen/no-builtin.cpp | 8 +- clang/test/CodeGenCXX/apple-kext.cpp | 4 +- clang/test/OpenMP/assumes_codegen.cpp | 36 --- .../test/OpenMP/for_firstprivate_codegen.cpp | 10 +- clang/test/OpenMP/for_lastprivate_codegen.cpp | 30 +++--- clang/test/OpenMP/for_linear_codegen.cpp | 20 ++-- .../OpenMP/parallel_firstprivate_codegen.cpp | 40 .../test/OpenMP/parallel_private_codegen.cpp | 20 ++-- .../OpenMP/parallel_reduction_codegen.cpp | 94 +-- .../OpenMP/sections_firstprivate_codegen.cpp | 20 ++-- .../OpenMP/single_firstprivate_codegen.cpp| 10 +- .../Inputs/basic-cplusplus.cpp.expected | 4 +- ...plicit-template-instantiation.cpp.expected | 8 +- 16 files changed, 162 insertions(+), 164 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 6a910abcfe21d2f..f4e2dc373be7f24 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1262,11 +1262,6 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { EmitCompoundStmtWithoutScope(*S); else EmitStmt(Body); - - // This is checked after emitting the function body so we know if there - // are any permitted infinite loops. - if (checkIfFunctionMustProgress()) -CurFn->addFnAttr(llvm::Attribute::MustProgress); } /// When instrumenting to collect profile data, the counts for some blocks @@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. + if (checkIfFunctionMustProgress()) +CurFn->addFnAttr(llvm::Attribute::MustProgress); + // C++11 [stmt.return]p2: // Flowing off the end of a function [...] results in undefined behavior in // a value-returning function. diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp index f6a64260e0df531..857bdca557fdc4b 100644 --- a/clang/test/CXX/special/class.dtor/p3-0x.cpp +++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp @@ -176,4 +176,4 @@ struct TVC : VX template TVC::~TVC() {} -// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} } +// CHECK: attributes [[ATTRGRP]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp index 7357a42838c2d72..090da25d21207d8 100644 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -224,7 +224,7 @@ float fun_default FUN(1) #endif float y(); // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class ON { @@ -246,10 +246,10 @@ class ON { }; ON on; #pragma float_control(except, off) -// CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class OFF { float w = 2 + y() * 7; // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} diff --git a/clang/test/CodeGen/no-builtin.cpp b/clang/test/CodeGen/no-builtin.cpp index 14bae1fe1a2234a..bfad88e4ec32496 100644 --- a/clang/test/CodeGen/no-builtin.cpp +++ b/clang/test/C
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto ready_for_review https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
antoniofrighetto wrote: I wonder if we should have `return getLangOpts().CPlusPlus11 || getLangOpts().C11;` at line 586: https://github.com/llvm/llvm-project/blob/d1fb9307951319eea3e869d78470341d603c8363/clang/lib/CodeGen/CodeGenFunction.h#L573-L587 But I couldn't find anything strictly related in C11 7.26 and 7.31.15. https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
@@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. antoniofrighetto wrote: Comment was added in https://github.com/llvm/llvm-project/commit/ac73b73c16526c9e51943759ea6cab285a57e33f. Perhaps something along these lines could work better? ```cpp // This is checked after emitting the function body, so as to ensure // that the function adheres to the forward progress guarantee, // which is required by certain optimizations. ``` https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
@@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. antoniofrighetto wrote: Seems like we fail to with some optimizations (e.g., https://github.com/llvm/llvm-project/issues/69833) due to a few non-mustprogress function, when they should likely not be. https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
@@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. antoniofrighetto wrote: Not sure about this, I assumed that this was the only way to know, as per comment says, if there are any permitted infinite loops. https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/71452 >From f80a4277966452934c142bc374bfb4f1acba4ad9 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Mon, 6 Nov 2023 23:20:31 +0100 Subject: [PATCH] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission Emission of `mustprogress` attribute previously occurred only within `EmitFunctionBody`, after generating the function body. Other routines for function body creation may lack the attribute, potentially leading to suboptimal optimizations later in the pipeline. Attribute emission is now anticipated prior to generating the function body. --- clang/lib/CodeGen/CodeGenFunction.cpp | 10 +- clang/test/CXX/special/class.dtor/p3-0x.cpp | 2 +- clang/test/CodeGen/fp-floatcontrol-stack.cpp | 10 +- clang/test/CodeGen/no-builtin.cpp | 8 +- clang/test/CodeGenCXX/apple-kext.cpp | 4 +- clang/test/OpenMP/assumes_codegen.cpp | 36 --- .../test/OpenMP/for_firstprivate_codegen.cpp | 10 +- clang/test/OpenMP/for_lastprivate_codegen.cpp | 30 +++--- clang/test/OpenMP/for_linear_codegen.cpp | 20 ++-- .../OpenMP/parallel_firstprivate_codegen.cpp | 40 .../test/OpenMP/parallel_private_codegen.cpp | 20 ++-- .../OpenMP/parallel_reduction_codegen.cpp | 94 +-- .../OpenMP/sections_firstprivate_codegen.cpp | 20 ++-- .../OpenMP/single_firstprivate_codegen.cpp| 10 +- .../Inputs/basic-cplusplus.cpp.expected | 4 +- ...plicit-template-instantiation.cpp.expected | 8 +- 16 files changed, 162 insertions(+), 164 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 6a910abcfe21d2f..b91e5da6941ca17 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1262,11 +1262,6 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { EmitCompoundStmtWithoutScope(*S); else EmitStmt(Body); - - // This is checked after emitting the function body so we know if there - // are any permitted infinite loops. - if (checkIfFunctionMustProgress()) -CurFn->addFnAttr(llvm::Attribute::MustProgress); } /// When instrumenting to collect profile data, the counts for some blocks @@ -1445,6 +1440,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, if (Body && isa_and_nonnull(Body)) llvm::append_range(FnArgs, FD->parameters()); + // Ensure that the function adheres to the forward progress guarantee, which + // is required by certain optimizations. + if (checkIfFunctionMustProgress()) +CurFn->addFnAttr(llvm::Attribute::MustProgress); + // Generate the body of the function. PGO.assignRegionCounters(GD, CurFn); if (isa(FD)) diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp index f6a64260e0df531..857bdca557fdc4b 100644 --- a/clang/test/CXX/special/class.dtor/p3-0x.cpp +++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp @@ -176,4 +176,4 @@ struct TVC : VX template TVC::~TVC() {} -// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} } +// CHECK: attributes [[ATTRGRP]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp index 7357a42838c2d72..090da25d21207d8 100644 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -224,7 +224,7 @@ float fun_default FUN(1) #endif float y(); // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class ON { @@ -246,10 +246,10 @@ class ON { }; ON on; #pragma float_control(except, off) -// CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class OFF { float w = 2 + y() * 7; // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} diff --git a/clang/test/CodeGen/no-builtin.cpp b/clang/test/CodeGen/no-builtin.cpp index 14bae1fe1a2234a..bfad88e4ec32496 100644 --- a/clang/test/CodeGen/no-builtin.cpp +++ b/clang/test/CodeGen/no-b
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
@@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. antoniofrighetto wrote: Anticipated before function body generation, thanks. https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
@@ -1482,6 +1477,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else llvm_unreachable("no definition for emitted function"); + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. antoniofrighetto wrote: Confirm this closes https://github.com/llvm/llvm-project/issues/69833. https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/71452 >From 970bf07d0b184c7ec356ae8f47b193a5e3ff0309 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Mon, 6 Nov 2023 23:20:31 +0100 Subject: [PATCH] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission Emission of `mustprogress` attribute previously occurred only within `EmitFunctionBody`, after generating the function body. Other routines for function body creation may lack the attribute, potentially leading to suboptimal optimizations later in the pipeline. Attribute emission is now anticipated prior to generating the function body. Fixes: https://github.com/llvm/llvm-project/issues/69833. --- clang/lib/CodeGen/CodeGenFunction.cpp | 10 +- clang/test/CXX/special/class.dtor/p3-0x.cpp | 2 +- clang/test/CodeGen/fp-floatcontrol-stack.cpp | 10 +- clang/test/CodeGen/no-builtin.cpp | 8 +- clang/test/CodeGenCXX/apple-kext.cpp | 4 +- clang/test/OpenMP/assumes_codegen.cpp | 36 --- .../test/OpenMP/for_firstprivate_codegen.cpp | 10 +- clang/test/OpenMP/for_lastprivate_codegen.cpp | 30 +++--- clang/test/OpenMP/for_linear_codegen.cpp | 20 ++-- .../OpenMP/parallel_firstprivate_codegen.cpp | 40 .../test/OpenMP/parallel_private_codegen.cpp | 20 ++-- .../OpenMP/parallel_reduction_codegen.cpp | 94 +-- .../OpenMP/sections_firstprivate_codegen.cpp | 20 ++-- .../OpenMP/single_firstprivate_codegen.cpp| 10 +- .../Inputs/basic-cplusplus.cpp.expected | 4 +- ...plicit-template-instantiation.cpp.expected | 8 +- 16 files changed, 162 insertions(+), 164 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 6a910abcfe21d2f..b91e5da6941ca17 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1262,11 +1262,6 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { EmitCompoundStmtWithoutScope(*S); else EmitStmt(Body); - - // This is checked after emitting the function body so we know if there - // are any permitted infinite loops. - if (checkIfFunctionMustProgress()) -CurFn->addFnAttr(llvm::Attribute::MustProgress); } /// When instrumenting to collect profile data, the counts for some blocks @@ -1445,6 +1440,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, if (Body && isa_and_nonnull(Body)) llvm::append_range(FnArgs, FD->parameters()); + // Ensure that the function adheres to the forward progress guarantee, which + // is required by certain optimizations. + if (checkIfFunctionMustProgress()) +CurFn->addFnAttr(llvm::Attribute::MustProgress); + // Generate the body of the function. PGO.assignRegionCounters(GD, CurFn); if (isa(FD)) diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp index f6a64260e0df531..857bdca557fdc4b 100644 --- a/clang/test/CXX/special/class.dtor/p3-0x.cpp +++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp @@ -176,4 +176,4 @@ struct TVC : VX template TVC::~TVC() {} -// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} } +// CHECK: attributes [[ATTRGRP]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp index 7357a42838c2d72..090da25d21207d8 100644 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -224,7 +224,7 @@ float fun_default FUN(1) #endif float y(); // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class ON { @@ -246,10 +246,10 @@ class ON { }; ON on; #pragma float_control(except, off) -// CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class OFF { float w = 2 + y() * 7; // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} diff --git a/clang/test/CodeGen/no-builtin.cpp b/clang/test/CodeGen/no-builtin.cpp index 14bae1fe1a2234a..bfad88e4ec32496 100644 --- a/clan
[clang] 970bf07 - [clang][CodeGen] Ensure consistent `mustprogress` attribute emission
Author: Antonio Frighetto Date: 2023-11-11T09:43:03+01:00 New Revision: 970bf07d0b184c7ec356ae8f47b193a5e3ff0309 URL: https://github.com/llvm/llvm-project/commit/970bf07d0b184c7ec356ae8f47b193a5e3ff0309 DIFF: https://github.com/llvm/llvm-project/commit/970bf07d0b184c7ec356ae8f47b193a5e3ff0309.diff LOG: [clang][CodeGen] Ensure consistent `mustprogress` attribute emission Emission of `mustprogress` attribute previously occurred only within `EmitFunctionBody`, after generating the function body. Other routines for function body creation may lack the attribute, potentially leading to suboptimal optimizations later in the pipeline. Attribute emission is now anticipated prior to generating the function body. Fixes: https://github.com/llvm/llvm-project/issues/69833. Added: Modified: clang/lib/CodeGen/CodeGenFunction.cpp clang/test/CXX/special/class.dtor/p3-0x.cpp clang/test/CodeGen/fp-floatcontrol-stack.cpp clang/test/CodeGen/no-builtin.cpp clang/test/CodeGenCXX/apple-kext.cpp clang/test/OpenMP/assumes_codegen.cpp clang/test/OpenMP/for_firstprivate_codegen.cpp clang/test/OpenMP/for_lastprivate_codegen.cpp clang/test/OpenMP/for_linear_codegen.cpp clang/test/OpenMP/parallel_firstprivate_codegen.cpp clang/test/OpenMP/parallel_private_codegen.cpp clang/test/OpenMP/parallel_reduction_codegen.cpp clang/test/OpenMP/sections_firstprivate_codegen.cpp clang/test/OpenMP/single_firstprivate_codegen.cpp clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp.expected Removed: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 6a910abcfe21d2f..b91e5da6941ca17 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1262,11 +1262,6 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { EmitCompoundStmtWithoutScope(*S); else EmitStmt(Body); - - // This is checked after emitting the function body so we know if there - // are any permitted infinite loops. - if (checkIfFunctionMustProgress()) -CurFn->addFnAttr(llvm::Attribute::MustProgress); } /// When instrumenting to collect profile data, the counts for some blocks @@ -1445,6 +1440,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, if (Body && isa_and_nonnull(Body)) llvm::append_range(FnArgs, FD->parameters()); + // Ensure that the function adheres to the forward progress guarantee, which + // is required by certain optimizations. + if (checkIfFunctionMustProgress()) +CurFn->addFnAttr(llvm::Attribute::MustProgress); + // Generate the body of the function. PGO.assignRegionCounters(GD, CurFn); if (isa(FD)) diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp index f6a64260e0df531..857bdca557fdc4b 100644 --- a/clang/test/CXX/special/class.dtor/p3-0x.cpp +++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp @@ -176,4 +176,4 @@ struct TVC : VX template TVC::~TVC() {} -// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} } +// CHECK: attributes [[ATTRGRP]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp index 7357a42838c2d72..090da25d21207d8 100644 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -224,7 +224,7 @@ float fun_default FUN(1) #endif float y(); // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class ON { @@ -246,10 +246,10 @@ class ON { }; ON on; #pragma float_control(except, off) -// CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} class OFF { float w = 2 + y() * 7; // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} diff --git a/clang/test/CodeGen/no-builtin.cpp b/clang/test/CodeGen/no-b
[clang] [clang][CodeGen] Ensure consistent `mustprogress` attribute emission across all paths (PR #71452)
https://github.com/antoniofrighetto closed https://github.com/llvm/llvm-project/pull/71452 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 4effdc4 - [clang][CodeGen] Regenerate `wasm-eh.cpp` test (NFC)
Author: Antonio Frighetto Date: 2023-11-11T11:59:59+01:00 New Revision: 4effdc47947b9260a1540ee7d8b699b077cbedb5 URL: https://github.com/llvm/llvm-project/commit/4effdc47947b9260a1540ee7d8b699b077cbedb5 DIFF: https://github.com/llvm/llvm-project/commit/4effdc47947b9260a1540ee7d8b699b077cbedb5.diff LOG: [clang][CodeGen] Regenerate `wasm-eh.cpp` test (NFC) Clang buildbot was previously failing when targeting WebAssembly. Fixes: https://lab.llvm.org/buildbot/#/builders/45/builds/14145. Added: Modified: clang/test/CodeGenCXX/wasm-eh.cpp Removed: diff --git a/clang/test/CodeGenCXX/wasm-eh.cpp b/clang/test/CodeGenCXX/wasm-eh.cpp index 27752f5f580367e..af023f52191b979 100644 --- a/clang/test/CodeGenCXX/wasm-eh.cpp +++ b/clang/test/CodeGenCXX/wasm-eh.cpp @@ -34,7 +34,7 @@ void test0() { // CHECK-NEXT: %[[EXN:.*]] = call ptr @llvm.wasm.get.exception(token %[[CATCHPAD]]) // CHECK-NEXT: store ptr %[[EXN]], ptr %exn.slot // CHECK-NEXT: %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector(token %[[CATCHPAD]]) -// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #8 +// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #7 // CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]] // CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]] @@ -51,7 +51,7 @@ void test0() { // CHECK-NEXT: br label %[[TRY_CONT_BB:.*]] // CHECK: [[CATCH_FALLTHROUGH_BB]] -// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTId) #8 +// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTId) #7 // CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]] // CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]] ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [llvm] [AArch64] Add an AArch64 pass for loop idiom transformations (PR #72273)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/72273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [llvm] [AArch64] Add an AArch64 pass for loop idiom transformations (PR #72273)
@@ -0,0 +1,726 @@ + +//===- AArch64LoopIdiomTransform.cpp - Loop idiom recognition -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "AArch64LoopIdiomTransform.h" +#include "llvm/Analysis/DomTreeUpdater.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/PatternMatch.h" +#include "llvm/InitializePasses.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +using namespace llvm; + +#define DEBUG_TYPE "aarch64-lit" + +static cl::opt +DisableAll("disable-aarch64-lit-all", cl::Hidden, cl::init(false), + cl::desc("Disable AArch64 Loop Idiom Transform Pass.")); + +static cl::opt DisableByteCmp( +"disable-aarch64-lit-bytecmp", cl::Hidden, cl::init(false), +cl::desc("Proceed with AArch64 Loop Idiom Transform Pass, but do " + "not convert byte-compare loop(s).")); + +namespace llvm { + +void initializeAArch64LoopIdiomTransformLegacyPassPass(PassRegistry &); +Pass *createAArch64LoopIdiomTransformPass(); + +} // end namespace llvm + +namespace { + +class AArch64LoopIdiomTransform { + Loop *CurLoop = nullptr; + DominatorTree *DT; + LoopInfo *LI; + const TargetTransformInfo *TTI; + const DataLayout *DL; + +public: + explicit AArch64LoopIdiomTransform(DominatorTree *DT, LoopInfo *LI, + const TargetTransformInfo *TTI, + const DataLayout *DL) + : DT(DT), LI(LI), TTI(TTI), DL(DL) {} + + bool run(Loop *L); + +private: + /// \name Countable Loop Idiom Handling + /// @{ + + bool runOnCountableLoop(); + bool runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, + SmallVectorImpl &ExitBlocks); + + bool recognizeByteCompare(); + Value *expandFindMismatch(IRBuilder<> &Builder, GetElementPtrInst *GEPA, +GetElementPtrInst *GEPB, Value *Start, +Value *MaxLen); + void transformByteCompare(GetElementPtrInst *GEPA, GetElementPtrInst *GEPB, +Value *MaxLen, Value *Index, Value *Start, +bool IncIdx, BasicBlock *FoundBB, +BasicBlock *EndBB); + /// @} +}; + +class AArch64LoopIdiomTransformLegacyPass : public LoopPass { +public: + static char ID; + + explicit AArch64LoopIdiomTransformLegacyPass() : LoopPass(ID) { +initializeAArch64LoopIdiomTransformLegacyPassPass( +*PassRegistry::getPassRegistry()); + } + + StringRef getPassName() const override { +return "Recognize AArch64-specific loop idioms"; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { +AU.addRequired(); +AU.addRequired(); +AU.addRequired(); + } + + bool runOnLoop(Loop *L, LPPassManager &LPM) override; +}; + +bool AArch64LoopIdiomTransformLegacyPass::runOnLoop(Loop *L, +LPPassManager &LPM) { + + if (skipLoop(L)) +return false; + + auto *DT = &getAnalysis().getDomTree(); + auto *LI = &getAnalysis().getLoopInfo(); + auto &TTI = getAnalysis().getTTI( + *L->getHeader()->getParent()); + return AArch64LoopIdiomTransform( + DT, LI, &TTI, &L->getHeader()->getModule()->getDataLayout()) + .run(L); +} + +} // end anonymous namespace + +char AArch64LoopIdiomTransformLegacyPass::ID = 0; + +INITIALIZE_PASS_BEGIN( +AArch64LoopIdiomTransformLegacyPass, "aarch64-lit", +"Transform specific loop idioms into optimised vector forms", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopSimplify) +INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END( +AArch64LoopIdiomTransformLegacyPass, "aarch64-lit", +"Transform specific loop idioms into optimised vector forms", false, false) + +Pass *llvm::createAArch64LoopIdiomTransformPass() { + return new AArch64LoopIdiomTransformLegacyPass(); +} + +PreservedAnalyses +AArch64LoopIdiomTransformPass::run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, + LPMUpdater &) { + if (DisableAll) +return PreservedAnalyses::all(); + + const auto *DL = &L.getHeader()->getModule()->getDataLayout(); + + AArch64LoopIdiomTransform LIT(&AR.DT, &AR.LI, &AR.TTI, DL); + if (!LIT.run(&L)) +return PreservedAnalyses::all(); + + return PreservedAnalyses::none(); +} + +//===-
[clang] [llvm] [clang-tools-extra] [AArch64] Add an AArch64 pass for loop idiom transformations (PR #72273)
@@ -0,0 +1,726 @@ + +//===- AArch64LoopIdiomTransform.cpp - Loop idiom recognition -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "AArch64LoopIdiomTransform.h" +#include "llvm/Analysis/DomTreeUpdater.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/PatternMatch.h" +#include "llvm/InitializePasses.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +using namespace llvm; + +#define DEBUG_TYPE "aarch64-lit" + +static cl::opt +DisableAll("disable-aarch64-lit-all", cl::Hidden, cl::init(false), + cl::desc("Disable AArch64 Loop Idiom Transform Pass.")); + +static cl::opt DisableByteCmp( +"disable-aarch64-lit-bytecmp", cl::Hidden, cl::init(false), +cl::desc("Proceed with AArch64 Loop Idiom Transform Pass, but do " + "not convert byte-compare loop(s).")); + +namespace llvm { + +void initializeAArch64LoopIdiomTransformLegacyPassPass(PassRegistry &); +Pass *createAArch64LoopIdiomTransformPass(); + +} // end namespace llvm + +namespace { + +class AArch64LoopIdiomTransform { + Loop *CurLoop = nullptr; + DominatorTree *DT; + LoopInfo *LI; + const TargetTransformInfo *TTI; + const DataLayout *DL; + +public: + explicit AArch64LoopIdiomTransform(DominatorTree *DT, LoopInfo *LI, + const TargetTransformInfo *TTI, + const DataLayout *DL) + : DT(DT), LI(LI), TTI(TTI), DL(DL) {} + + bool run(Loop *L); + +private: + /// \name Countable Loop Idiom Handling + /// @{ + + bool runOnCountableLoop(); + bool runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, + SmallVectorImpl &ExitBlocks); + + bool recognizeByteCompare(); + Value *expandFindMismatch(IRBuilder<> &Builder, GetElementPtrInst *GEPA, +GetElementPtrInst *GEPB, Value *Start, +Value *MaxLen); + void transformByteCompare(GetElementPtrInst *GEPA, GetElementPtrInst *GEPB, +Value *MaxLen, Value *Index, Value *Start, +bool IncIdx, BasicBlock *FoundBB, +BasicBlock *EndBB); + /// @} +}; + +class AArch64LoopIdiomTransformLegacyPass : public LoopPass { +public: + static char ID; + + explicit AArch64LoopIdiomTransformLegacyPass() : LoopPass(ID) { +initializeAArch64LoopIdiomTransformLegacyPassPass( +*PassRegistry::getPassRegistry()); + } + + StringRef getPassName() const override { +return "Recognize AArch64-specific loop idioms"; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { +AU.addRequired(); +AU.addRequired(); +AU.addRequired(); + } + + bool runOnLoop(Loop *L, LPPassManager &LPM) override; +}; + +bool AArch64LoopIdiomTransformLegacyPass::runOnLoop(Loop *L, +LPPassManager &LPM) { + + if (skipLoop(L)) +return false; + + auto *DT = &getAnalysis().getDomTree(); + auto *LI = &getAnalysis().getLoopInfo(); + auto &TTI = getAnalysis().getTTI( + *L->getHeader()->getParent()); + return AArch64LoopIdiomTransform( + DT, LI, &TTI, &L->getHeader()->getModule()->getDataLayout()) + .run(L); +} + +} // end anonymous namespace + +char AArch64LoopIdiomTransformLegacyPass::ID = 0; + +INITIALIZE_PASS_BEGIN( +AArch64LoopIdiomTransformLegacyPass, "aarch64-lit", +"Transform specific loop idioms into optimised vector forms", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopSimplify) +INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END( +AArch64LoopIdiomTransformLegacyPass, "aarch64-lit", +"Transform specific loop idioms into optimised vector forms", false, false) + +Pass *llvm::createAArch64LoopIdiomTransformPass() { + return new AArch64LoopIdiomTransformLegacyPass(); +} + +PreservedAnalyses +AArch64LoopIdiomTransformPass::run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, + LPMUpdater &) { + if (DisableAll) +return PreservedAnalyses::all(); + + const auto *DL = &L.getHeader()->getModule()->getDataLayout(); + + AArch64LoopIdiomTransform LIT(&AR.DT, &AR.LI, &AR.TTI, DL); + if (!LIT.run(&L)) +return PreservedAnalyses::all(); + + return PreservedAnalyses::none(); +} + +//===-
[llvm] [mlir] [flang] [clang-tools-extra] [libcxx] [openmp] [lldb] [compiler-rt] [libc] [clang] [lld] fix issue 73559. (PR #74926)
antoniofrighetto wrote: Could you kindly squash everything into one commit and provide a meaningful git commit title and git message description? For example: ``` [clang][Parse] `TryAnnotateCXXScopeToken` to be called only when parsing C++ Assume `TryAnnotateCXXScopeToken` to be parsing C++ code in all of its paths. Fixes: https://github.com/llvm/llvm-project/issues/73559. ``` https://github.com/llvm/llvm-project/pull/74926 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/84230 >From 869f015ac440ff1885caf44abffe28cd6ebf0f13 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 6 Mar 2024 23:49:40 +0100 Subject: [PATCH] [clang][CodeGen] Allow `memcpy` replace with trivial auto var init pattern When emitting the storage (or memory copy operations) for constant initializers, the decision whether to split a constant structure or array store into a sequence of field stores or to use `memcpy` is based upon the optimization level and the size of the initializer. In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by allowing constants to be split when the array (or struct) type does not match the type of data the address to the object (constant) is expected to contain. This may happen when `emitStoresForConstant` is called by `EmitAutoVarInit`, as the element type of the address gets shrunk. When this occurs, let the initializer be split into a bunch of stores only under `-ftrivial-auto-var-init=pattern`. Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 43 ++- clang/test/CodeGen/aapcs-align.cpp| 4 +-- clang/test/CodeGen/aapcs64-align.cpp | 8 ++--- clang/test/CodeGen/attr-counted-by.c | 26 -- clang/test/CodeGenCXX/auto-var-init.cpp | 27 +++--- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +-- 7 files changed, 56 insertions(+), 65 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index dc42faf8dbb9fd..2ef5ed04af30b6 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHE
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/84230 >From 3c006a4fbec11e7e8ccaadbf347484077597894f Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 6 Mar 2024 23:49:40 +0100 Subject: [PATCH] [clang][CodeGen] Allow `memcpy` replace with trivial auto var init When emitting the storage (or memory copy operations) for constant initializers, the decision whether to split a constant structure or array store into a sequence of field stores or to use `memcpy` is based upon the optimization level and the size of the initializer. In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by allowing constants to be split when the array (or struct) type does not match the type of data the address to the object (constant) is expected to contain. This may happen when `emitStoresForConstant` is called by `EmitAutoVarInit`, as the element type of the address gets shrunk. When this occurs, let the initializer be split into a bunch of stores only under `-ftrivial-auto-var-init=pattern`. Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 43 ++- clang/test/CodeGen/aapcs-align.cpp| 4 +-- clang/test/CodeGen/aapcs64-align.cpp | 8 ++--- clang/test/CodeGen/attr-counted-by.c | 26 -- clang/test/CodeGenCXX/auto-var-init.cpp | 27 +++--- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +-- 7 files changed, 56 insertions(+), 65 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index dc42faf8dbb9fd..2ef5ed04af30b6 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
antoniofrighetto wrote: @efriedma-quic, comment updated, thanks. https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
antoniofrighetto wrote: @nikic, updated PR description as well, thanks. https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/84230 >From bfc29a350458e9b8d20d7398595c3f36503e2d72 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Thu, 7 Mar 2024 07:49:40 +0100 Subject: [PATCH] [clang][CodeGen] Allow `memcpy` replace with trivial auto var init When emitting the storage (or memory copy operations) for constant initializers, the decision whether to split a constant structure or array store into a sequence of field stores or to use `memcpy` is based upon the optimization level and the size of the initializer. In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by allowing constants to be split when the array (or struct) type does not match the type of data the address to the object (constant) is expected to contain. This may happen when `emitStoresForConstant` is called by `EmitAutoVarInit`, as the element type of the address gets shrunk. When this occurs, let the initializer be split into a bunch of stores only under `-ftrivial-auto-var-init=pattern`. Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 43 ++- clang/test/CodeGen/aapcs-align.cpp| 4 +-- clang/test/CodeGen/aapcs64-align.cpp | 8 ++--- clang/test/CodeGen/attr-counted-by.c | 26 -- clang/test/CodeGenCXX/auto-var-init.cpp | 27 +++--- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +-- 7 files changed, 56 insertions(+), 65 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index dc42faf8dbb9fd..2ef5ed04af30b6 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/84230 >From b433076fcbacba8a3b91446390bbea5843322bcd Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Thu, 7 Mar 2024 07:49:40 +0100 Subject: [PATCH] [clang][CodeGen] Allow `memcpy` replace with trivial auto var init When emitting the storage (or memory copy operations) for constant initializers, the decision whether to split a constant structure or array store into a sequence of field stores or to use `memcpy` is based upon the optimization level and the size of the initializer. In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by allowing constants to be split when the array (or struct) type does not match the type of data the address to the object (constant) is expected to contain. This may happen when `emitStoresForConstant` is called by `EmitAutoVarInit`, as the element type of the address gets shrunk. When this occurs, let the initializer be split into a bunch of stores only under `-ftrivial-auto-var-init=pattern`. Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 43 ++- clang/test/CodeGen/aapcs-align.cpp| 4 +-- clang/test/CodeGen/aapcs64-align.cpp | 8 ++--- clang/test/CodeGen/attr-counted-by.c | 26 -- clang/test/CodeGenCXX/auto-var-init.cpp | 27 +++--- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +-- 7 files changed, 56 insertions(+), 65 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index dc42faf8dbb9fd..2ef5ed04af30b6 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto closed https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b433076 - [clang][CodeGen] Allow `memcpy` replace with trivial auto var init
Author: Antonio Frighetto Date: 2024-03-21T09:55:04+01:00 New Revision: b433076fcbacba8a3b91446390bbea5843322bcd URL: https://github.com/llvm/llvm-project/commit/b433076fcbacba8a3b91446390bbea5843322bcd DIFF: https://github.com/llvm/llvm-project/commit/b433076fcbacba8a3b91446390bbea5843322bcd.diff LOG: [clang][CodeGen] Allow `memcpy` replace with trivial auto var init When emitting the storage (or memory copy operations) for constant initializers, the decision whether to split a constant structure or array store into a sequence of field stores or to use `memcpy` is based upon the optimization level and the size of the initializer. In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by allowing constants to be split when the array (or struct) type does not match the type of data the address to the object (constant) is expected to contain. This may happen when `emitStoresForConstant` is called by `EmitAutoVarInit`, as the element type of the address gets shrunk. When this occurs, let the initializer be split into a bunch of stores only under `-ftrivial-auto-var-init=pattern`. Fixes: https://github.com/llvm/llvm-project/issues/84178. Added: Modified: clang/lib/CodeGen/CGDecl.cpp clang/test/CodeGen/aapcs-align.cpp clang/test/CodeGen/aapcs64-align.cpp clang/test/CodeGen/attr-counted-by.c clang/test/CodeGenCXX/auto-var-init.cpp clang/test/CodeGenOpenCL/amdgpu-printf.cl clang/test/OpenMP/bug54082.c Removed: diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index dc42faf8dbb9fd..2ef5ed04af30b6 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
antoniofrighetto wrote: @tstellar Yes, thanks (I opened a new PR for that: https://github.com/llvm/llvm-project/pull/86106). https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8c6e96d - [clang][Dataflow] Fix unnecessary copy in `initializeFieldsWithValues` (NFC)
Author: Antonio Frighetto Date: 2024-02-13T11:05:26+01:00 New Revision: 8c6e96d9eb35849762fa3ab4d3cc9517c4e14e74 URL: https://github.com/llvm/llvm-project/commit/8c6e96d9eb35849762fa3ab4d3cc9517c4e14e74 DIFF: https://github.com/llvm/llvm-project/commit/8c6e96d9eb35849762fa3ab4d3cc9517c4e14e74.diff LOG: [clang][Dataflow] Fix unnecessary copy in `initializeFieldsWithValues` (NFC) Added: Modified: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp Removed: diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 93a9dac3bc905f..d487944ce92111 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -939,7 +939,7 @@ void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc, } }; - for (const auto [Field, FieldLoc] : Loc.children()) { + for (const auto &[Field, FieldLoc] : Loc.children()) { assert(Field != nullptr); QualType FieldType = Field->getType(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[clang] Avoid memcopy for small structure with padding under … (PR #84230)
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/84230 …-ftrivial-auto-var-init (#71677)" This reverts commit afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d. Fixes regression: https://github.com/llvm/llvm-project/issues/84178. >From bb22eccc90d0e8cb02be5d4c47a08a17baf4d242 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 6 Mar 2024 21:29:13 +0100 Subject: [PATCH] Revert "[clang] Avoid memcopy for small structure with padding under -ftrivial-auto-var-init (#71677)" This reverts commit afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d. Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 35 + clang/test/CodeGen/aapcs-align.cpp| 4 +- clang/test/CodeGen/aapcs64-align.cpp | 8 ++-- clang/test/CodeGenCXX/auto-var-init.cpp | 47 --- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +- 6 files changed, 52 insertions(+), 55 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index bbe14ef4c17244..46cfd3f10a3fb7 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1244,24 +1244,29 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, // If the initializer is small, use a handful of stores. if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + // FIXME: handle the case when STy != Loc.getElementType(). + if (STy == Loc.getElementType()) { +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + Address EltPtr = Builder.CreateStructGEP(Loc, i); + emitStoresForConstant( + CGM, D, EltPtr, isVolatile, Builder, + cast(Builder.CreateExtractValue(constant, i)), + IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + // FIXME: handle the case when ATy != Loc.getElementType(). + if (ATy == Loc.getElementType()) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstArrayGEP(Loc, i); + emitStoresForConstant( + CGM, D, EltPtr, isVolatile, Builder, + cast(Builder.CreateExtractValue(constant, i)), + IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) // CHECK: declare void @f6(i32 noundef, [4 x i32]) // CHECK: declare void @f6m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [4 x i32]) } diff --git a/clang/test/CodeGen/aapcs64-align.cpp b/clang/test/CodeGen/aapcs64-align.cpp index 759413cbc4b56f..de231f2123b975 100644 --- a/clang/test/CodeGen/aapcs64-align.cpp +++ b/clang/test/CodeGen/aapcs64-align.cpp @@ -75,8 +75,8 @@ void g4() { f4m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g4() -// CHECK: call void @f4(i32 noundef 1, [2 x i64] %{{.*}}) -// CHECK: void @f4m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [2 x i64] %{{.*}}) +// CHECK: call void @f4(i32 noundef 1, [2 x i64] [i64 30064771078, i64 0]) +// CHECK: void @f4m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [2 x i64] [i64 30064771078, i64 0]) // CHECK: declare void @f4(i32 noundef, [2 x i64]) // CHECK: declare void @f4
[clang] Revert "[clang] Avoid memcopy for small structure with padding under … (PR #84230)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/84230 >From 91ca7b2e5c98a7caa8a97f05f57e84f68d861fa3 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 6 Mar 2024 23:49:40 +0100 Subject: [PATCH] [clang][CodeGen] Allow memcpy replace with trivial auto var init Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 43 ++- clang/test/CodeGen/aapcs-align.cpp| 4 +-- clang/test/CodeGen/aapcs64-align.cpp | 8 ++--- clang/test/CodeGen/attr-counted-by.c | 26 -- clang/test/CodeGenCXX/auto-var-init.cpp | 6 ++-- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +-- 7 files changed, 43 insertions(+), 57 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index bbe14ef4c17244..aa9997b87ecfa7 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1241,27 +1241,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) // CHECK: declare void @f6(i32 noundef, [4 x i32]) // CHECK: declare void @f6m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [4 x i32]) } diff --git a/clang/test/CodeGen/aapcs64-align.cpp b/clang/test/CodeGen/aapcs64-align.cpp index 759413cbc4b56f..de231f2123b975 100644 --- a/clang/test/CodeGen/aapcs64-align.cpp +++ b/clang/test/CodeGen/aapcs64-align.cpp @@ -75,8 +75,8 @@ void g4() { f4m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g4() -// CHECK: call void @f4(i32 noundef 1, [2 x i64] %{{.*}}) -// CHECK: void @f4m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
antoniofrighetto wrote: I think manually checking if `TrivialAutoVarInit` is set (to `Pattern`?) may be a better fix, as there was only [one codepath](https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGDecl.cpp#L1972-L1974) in which we were not checking this. https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/84230 >From e5af3e3242b34811eb56d91597bfc58e89f9e2db Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 6 Mar 2024 23:49:40 +0100 Subject: [PATCH] [clang][CodeGen] Allow memcpy replace with trivial auto var init With respect to d5934a4112166ce0375295b2347e7d5c43fdf5ed, actually ensure `memcpy`s can be avoided when `-ftrivial-auto-var-init` is set. Fixes: https://github.com/llvm/llvm-project/issues/84178. --- clang/lib/CodeGen/CGDecl.cpp | 43 ++- clang/test/CodeGen/aapcs-align.cpp| 4 +-- clang/test/CodeGen/aapcs64-align.cpp | 8 ++--- clang/test/CodeGen/attr-counted-by.c | 26 -- clang/test/CodeGenCXX/auto-var-init.cpp | 27 +++--- clang/test/CodeGenOpenCL/amdgpu-printf.cl | 9 + clang/test/OpenMP/bug54082.c | 4 +-- 7 files changed, 56 insertions(+), 65 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index bbe14ef4c17244..aa9997b87ecfa7 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1241,27 +1241,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - // If the initializer is small, use a handful of stores. + // If the initializer is small or trivialAutoVarInit is set, use a handful of + // stores. + bool IsTrivialAutoVarInitPattern = + CGM.getContext().getLangOpts().getTrivialAutoVarInit() == + LangOptions::TrivialAutoVarInitKind::Pattern; if (shouldSplitConstantStore(CGM, ConstantSize)) { if (auto *STy = dyn_cast(Ty)) { - const llvm::StructLayout *Layout = - CGM.getDataLayout().getStructLayout(STy); - for (unsigned i = 0; i != constant->getNumOperands(); i++) { -CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i)); -Address EltPtr = Builder.CreateConstInBoundsByteGEP( -Loc.withElementType(CGM.Int8Ty), CurOff); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (STy == Loc.getElementType() || + (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +const llvm::StructLayout *Layout = +CGM.getDataLayout().getStructLayout(STy); +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + CharUnits CurOff = + CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateConstInBoundsByteGEP( + Loc.withElementType(CGM.Int8Ty), CurOff); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } else if (auto *ATy = dyn_cast(Ty)) { - for (unsigned i = 0; i != ATy->getNumElements(); i++) { -Address EltPtr = Builder.CreateConstGEP( -Loc.withElementType(ATy->getElementType()), i); -emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, - constant->getAggregateElement(i), IsAutoInit); + if (ATy == Loc.getElementType() || + (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { +for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstGEP( + Loc.withElementType(ATy->getElementType()), i); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, +constant->getAggregateElement(i), IsAutoInit); +} +return; } - return; } } diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 2886a32974b066..4f393d9e6b7f32 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -134,8 +134,8 @@ void g6() { f6m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}} void @g6 -// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) -// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0]) +// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) +// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) // CHECK: declare void @f6(i32 noundef, [4 x i32]) // CHECK: declare void @f6m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [4 x i32]) } diff --git a/clang/test/CodeGen/aapcs64-align.cpp b/clang/test/CodeGen/aapcs64-align.cpp index 759413cbc4b56f..de231f2123b975 100644 --- a/clang/test/CodeGen/aapcs64-align.cpp +++ b/clang/test/CodeGen/aapcs64-align.cpp @@ -75,8 +75,8 @@ void g4() { f4m(1, 2, 3, 4, 5, s); } // CHECK: define{{.*}}
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
antoniofrighetto wrote: Fixed `auto-var-init.cpp` test failures, believe now it should be aligned with the original intent. https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/84230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 2dea969 - [clang][CodeGen] Introduce `-frecord-command-line` for MachO
Author: Antonio Frighetto Date: 2023-07-24T09:24:59+02:00 New Revision: 2dea969d8337251e4c9335fd601bd4e0e5dee10f URL: https://github.com/llvm/llvm-project/commit/2dea969d8337251e4c9335fd601bd4e0e5dee10f DIFF: https://github.com/llvm/llvm-project/commit/2dea969d8337251e4c9335fd601bd4e0e5dee10f.diff LOG: [clang][CodeGen] Introduce `-frecord-command-line` for MachO Allow clang driver command-line recording when targeting MachO object files as well. Reviewed-by: sgraenitz Differential Revision: https://reviews.llvm.org/D155716 Added: llvm/test/CodeGen/AArch64/commandline-metadata.ll Modified: clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/clang_f_opts.c llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Removed: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index ef20dd5aefe7dc..adb550d9c5da50 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7183,7 +7183,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.hasFlag(options::OPT_frecord_command_line, options::OPT_fno_record_command_line, false); if (FRecordSwitches && !Triple.isOSBinFormatELF() && - !Triple.isOSBinFormatXCOFF()) + !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO()) D.Diag(diag::err_drv_unsupported_opt_for_target) << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args) << TripleStr; diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index e8bc46e23b78a3..8a27140cd16e5f 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -541,7 +541,7 @@ // RUN: %clang -### -S -target x86_64-unknown-linux -fno-record-command-line -frecord-command-line %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES %s // RUN: %clang -### -S -target x86_64-unknown-linux -frecord-command-line -fno-record-command-line %s 2>&1 | FileCheck -check-prefix=CHECK-NO-RECORD-GCC-SWITCHES %s // Test with a couple examples of non-ELF object file formats -// RUN: %clang -### -S -target x86_64-unknown-macosx -frecord-command-line %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES-ERROR %s +// RUN: %clang -### -S -target x86_64-unknown-macosx -frecord-command-line %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES %s // RUN: %clang -### -S -target x86_64-unknown-windows -frecord-command-line %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES-ERROR %s // CHECK-RECORD-GCC-SWITCHES: "-record-command-line" // CHECK-NO-RECORD-GCC-SWITCHES-NOT: "-record-command-line" diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 07ebf5e65431d3..9f92b919824d2d 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -156,6 +156,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { void getNameWithPrefix(SmallVectorImpl &OutName, const GlobalValue *GV, const TargetMachine &TM) const override; + + MCSection *getSectionForCommandLines() const override; }; class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 9e0914f667f02b..3994552884c4f6 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1420,6 +1420,11 @@ MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( return ReadOnlySection; // .const } +MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const { + return getContext().getMachOSection("__TEXT", "__command_line", 0, + SectionKind::getReadOnly()); +} + const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, MachineModuleInfo *MMI, MCStreamer &Streamer) const { diff --git a/llvm/test/CodeGen/AArch64/commandline-metadata.ll b/llvm/test/CodeGen/AArch64/commandline-metadata.ll new file mode 100644 index 00..7c6e01763220d1 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/commandline-metadata.ll @@ -0,0 +1,24 @@ +; RUN: llc -mtriple=arm64-linux-gnu < %s | FileCheck %s +; RUN: llc -mtriple=arm64-apple-darwin < %s | FileCheck %s --check-prefix=CHECK-MACHO + +; Verify that llvm.commandline metadata is emitted to the corresponding command line section. + +; CHECK: .text +; CHECK: .section .GCC.command.line,"MS",@progbits,1 +; CHECK-NEXT: .zero 1 +; CHECK-NEXT: .ascii
[clang] ffb8434 - [clang] Prevent unnecessary copies in `SymbolGraphSerializer` (NFC)
Author: Antonio Frighetto Date: 2023-09-08T17:19:06+02:00 New Revision: ffb8434f6a514fb3c06e0bdaff6d4ee410924ff6 URL: https://github.com/llvm/llvm-project/commit/ffb8434f6a514fb3c06e0bdaff6d4ee410924ff6 DIFF: https://github.com/llvm/llvm-project/commit/ffb8434f6a514fb3c06e0bdaff6d4ee410924ff6.diff LOG: [clang] Prevent unnecessary copies in `SymbolGraphSerializer` (NFC) Added: Modified: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp Removed: diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 229bf04c77fae44..6ee6e72d99ec57b 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -597,7 +597,7 @@ std::optional serializeTemplateMixinImpl(const RecordTy &Record, Object Generics; Array GenericParameters; - for (const auto Param : Template.getParameters()) { + for (const auto &Param : Template.getParameters()) { Object Parameter; Parameter["name"] = Param.Name; Parameter["index"] = Param.Index; @@ -608,7 +608,7 @@ std::optional serializeTemplateMixinImpl(const RecordTy &Record, Generics["parameters"] = std::move(GenericParameters); Array GenericConstraints; - for (const auto Constr : Template.getConstraints()) { + for (const auto &Constr : Template.getConstraints()) { Object Constraint; Constraint["kind"] = Constr.Kind; Constraint["lhs"] = Constr.LHS; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/66243: An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. As per doc-comment in `HandleUnionActiveMemberChange`, it turns out we might not be handling a union, so minor refinement on the function name as well. No problem in undoing this, if any though. Fixes: https://github.com/llvm/llvm-project/issues/65982. >From 717f5817086f7e58633e0d0225313d5c132b1710 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 13 Sep 2023 18:44:19 +0200 Subject: [PATCH] [clang] Bail out when handling union access with virtual inheritance An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: https://github.com/llvm/llvm-project/issues/65982 --- clang/lib/AST/ExprConstant.cpp | 17 - clang/test/SemaCXX/cxx2a-virtual-base-used.cpp | 11 +++ 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaCXX/cxx2a-virtual-base-used.cpp diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index dfa48e9c030b6a3..fea06b97259fe31 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6062,8 +6062,9 @@ const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind; /// operator whose left-hand side might involve a union member access. If it /// does, implicitly start the lifetime of any accessed union elements per /// C++20 [class.union]5. -static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, - const LValue &LHS) { +static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, + const Expr *LHSExpr, + const LValue &LHS) { if (LHS.InvalidBase || LHS.Designator.Invalid) return false; @@ -6118,8 +6119,14 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, break; // Walk path backwards as we walk up from the base to the derived class. for (const CXXBaseSpecifier *Elt : llvm::reverse(ICE->path())) { +if (Elt->isVirtual()) { + // A class with virtual base classes never has a trivial default + // constructor, so S(E) is empty in this case. + E = nullptr; + break; +} + --PathLength; -(void)Elt; assert(declaresSameEntity(Elt->getType()->getAsCXXRecordDecl(), LHS.Designator.Entries[PathLength] .getAsBaseOrMember().getPointer())); @@ -7806,7 +7813,7 @@ class ExprEvaluatorBase // per C++20 [class.union]5. if (Info.getLangOpts().CPlusPlus20 && OCE && OCE->getOperator() == OO_Equal && MD->isTrivial() && -!HandleUnionActiveMemberChange(Info, Args[0], ThisVal)) +!MaybeHandleUnionActiveMemberChange(Info, Args[0], ThisVal)) return false; Args = Args.slice(1); @@ -8679,7 +8686,7 @@ bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) { return false; if (Info.getLangOpts().CPlusPlus20 && - !HandleUnionActiveMemberChange(Info, E->getLHS(), Result)) + !MaybeHandleUnionActiveMemberChange(Info, E->getLHS(), Result)) return false; return handleAssignment(this->Info, E, Result, E->getLHS()->getType(), diff --git a/clang/test/SemaCXX/cxx2a-virtual-base-used.cpp b/clang/test/SemaCXX/cxx2a-virtual-base-used.cpp new file mode 100644 index 000..196a3ab05564b96 --- /dev/null +++ b/clang/test/SemaCXX/cxx2a-virtual-base-used.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++20 -verify=cxx20 -triple=x86_64-linux-gnu %s +// Fixes assertion triggered by https://github.com/llvm/llvm-project/issues/65982 + +struct A { int y; }; +struct B : virtual public A {}; +struct X : public B {}; + +void member_with_virtual_inheritance() { + X x; + x.B::y = 1; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
https://github.com/antoniofrighetto review_requested https://github.com/llvm/llvm-project/pull/66243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
https://github.com/antoniofrighetto review_requested https://github.com/llvm/llvm-project/pull/66243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
https://github.com/antoniofrighetto review_requested https://github.com/llvm/llvm-project/pull/66243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
https://github.com/antoniofrighetto review_requested https://github.com/llvm/llvm-project/pull/66243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 660876a - [clang] Bail out when handling union access with virtual inheritance
Author: Antonio Frighetto Date: 2023-09-14T08:48:59+02:00 New Revision: 660876a4019b81b5a7427a3dcec5ce8c39cd1ee0 URL: https://github.com/llvm/llvm-project/commit/660876a4019b81b5a7427a3dcec5ce8c39cd1ee0 DIFF: https://github.com/llvm/llvm-project/commit/660876a4019b81b5a7427a3dcec5ce8c39cd1ee0.diff LOG: [clang] Bail out when handling union access with virtual inheritance An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: https://github.com/llvm/llvm-project/issues/65982 Added: clang/test/SemaCXX/cxx2a-virtual-base-used.cpp Modified: clang/lib/AST/ExprConstant.cpp Removed: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index dfa48e9c030b6a3..fea06b97259fe31 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6062,8 +6062,9 @@ const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind; /// operator whose left-hand side might involve a union member access. If it /// does, implicitly start the lifetime of any accessed union elements per /// C++20 [class.union]5. -static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, - const LValue &LHS) { +static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, + const Expr *LHSExpr, + const LValue &LHS) { if (LHS.InvalidBase || LHS.Designator.Invalid) return false; @@ -6118,8 +6119,14 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, break; // Walk path backwards as we walk up from the base to the derived class. for (const CXXBaseSpecifier *Elt : llvm::reverse(ICE->path())) { +if (Elt->isVirtual()) { + // A class with virtual base classes never has a trivial default + // constructor, so S(E) is empty in this case. + E = nullptr; + break; +} + --PathLength; -(void)Elt; assert(declaresSameEntity(Elt->getType()->getAsCXXRecordDecl(), LHS.Designator.Entries[PathLength] .getAsBaseOrMember().getPointer())); @@ -7806,7 +7813,7 @@ class ExprEvaluatorBase // per C++20 [class.union]5. if (Info.getLangOpts().CPlusPlus20 && OCE && OCE->getOperator() == OO_Equal && MD->isTrivial() && -!HandleUnionActiveMemberChange(Info, Args[0], ThisVal)) +!MaybeHandleUnionActiveMemberChange(Info, Args[0], ThisVal)) return false; Args = Args.slice(1); @@ -8679,7 +8686,7 @@ bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) { return false; if (Info.getLangOpts().CPlusPlus20 && - !HandleUnionActiveMemberChange(Info, E->getLHS(), Result)) + !MaybeHandleUnionActiveMemberChange(Info, E->getLHS(), Result)) return false; return handleAssignment(this->Info, E, Result, E->getLHS()->getType(), diff --git a/clang/test/SemaCXX/cxx2a-virtual-base-used.cpp b/clang/test/SemaCXX/cxx2a-virtual-base-used.cpp new file mode 100644 index 000..196a3ab05564b96 --- /dev/null +++ b/clang/test/SemaCXX/cxx2a-virtual-base-used.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++20 -verify=cxx20 -triple=x86_64-linux-gnu %s +// Fixes assertion triggered by https://github.com/llvm/llvm-project/issues/65982 + +struct A { int y; }; +struct B : virtual public A {}; +struct X : public B {}; + +void member_with_virtual_inheritance() { + X x; + x.B::y = 1; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
antoniofrighetto wrote: Closing this as landed in 660876a4019b81b5a7427a3dcec5ce8c39cd1ee0. Thanks. https://github.com/llvm/llvm-project/pull/66243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Bail out when handling union access with virtual inheritance (PR #66243)
https://github.com/antoniofrighetto closed https://github.com/llvm/llvm-project/pull/66243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Inliner] Propagate more attributes to params when inlining (PR #91101)
https://github.com/antoniofrighetto commented: I think this makes sense. https://github.com/llvm/llvm-project/pull/91101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [IR] Add getelementptr nusw and nuw flags (PR #90824)
antoniofrighetto wrote: Are the TODOs encompassing all the cases? Why we don't want to set the flags in `PHITransAddr` as well? https://github.com/llvm/llvm-project/pull/90824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr` (PR #92277)
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/92277 Ignore `ImplicitCastExpr` when building `AttrExp` for capability attribute diagnostics. Fixes: https://github.com/llvm/llvm-project/issues/92118. >From fb668a484553f1a62e2461e8cd2bb1484792eb6d Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 15 May 2024 17:03:02 +0200 Subject: [PATCH] [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr` Ignore `ImplicitCastExpr` when building `AttrExp` for capability attribute diagnostics. Fixes: https://github.com/llvm/llvm-project/issues/92118. --- clang/lib/Analysis/ThreadSafetyCommon.cpp | 2 +- clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 33f1f466df244..71de84f698e26 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -197,7 +197,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, else if (const auto *UO = dyn_cast(AttrExp)) { if (UO->getOpcode() == UO_LNot) { Neg = true; - AttrExp = UO->getSubExpr(); + AttrExp = UO->getSubExpr()->IgnoreImplicit(); } } diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index dfb966d3b5902..749d9e135d941 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5341,7 +5341,7 @@ void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightCon void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {} void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) { - dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */ + dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while role 'FlightControl' is held}} */ dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */ } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr` (PR #92277)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/92277 >From 2c2e0507e92bdb77a01828f899ff59e44492b537 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 15 May 2024 17:03:02 +0200 Subject: [PATCH] [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr` Ignore `ImplicitCastExpr` when building `AttrExp` for capability attribute diagnostics. Fixes: https://github.com/llvm/llvm-project/issues/92118. --- clang/lib/Analysis/ThreadSafetyCommon.cpp | 2 +- clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index a3b378c42df33..3e8c959ccee4f 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -197,7 +197,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, else if (const auto *UO = dyn_cast(AttrExp)) { if (UO->getOpcode() == UO_LNot) { Neg = true; - AttrExp = UO->getSubExpr(); + AttrExp = UO->getSubExpr()->IgnoreImplicit(); } } diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index dfb966d3b5902..749d9e135d941 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5341,7 +5341,7 @@ void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightCon void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {} void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) { - dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */ + dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while role 'FlightControl' is held}} */ dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */ } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 2c2e050 - [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr`
Author: Antonio Frighetto Date: 2024-05-18T09:49:10+02:00 New Revision: 2c2e0507e92bdb77a01828f899ff59e44492b537 URL: https://github.com/llvm/llvm-project/commit/2c2e0507e92bdb77a01828f899ff59e44492b537 DIFF: https://github.com/llvm/llvm-project/commit/2c2e0507e92bdb77a01828f899ff59e44492b537.diff LOG: [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr` Ignore `ImplicitCastExpr` when building `AttrExp` for capability attribute diagnostics. Fixes: https://github.com/llvm/llvm-project/issues/92118. Added: Modified: clang/lib/Analysis/ThreadSafetyCommon.cpp clang/test/SemaCXX/warn-thread-safety-analysis.cpp Removed: diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index a3b378c42df33..3e8c959ccee4f 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -197,7 +197,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, else if (const auto *UO = dyn_cast(AttrExp)) { if (UO->getOpcode() == UO_LNot) { Neg = true; - AttrExp = UO->getSubExpr(); + AttrExp = UO->getSubExpr()->IgnoreImplicit(); } } diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index dfb966d3b5902..749d9e135d941 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5341,7 +5341,7 @@ void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightCon void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {} void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) { - dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */ + dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while role 'FlightControl' is held}} */ dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */ } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ThreadSafety] Skip past implicit cast in `translateAttrExpr` (PR #92277)
https://github.com/antoniofrighetto closed https://github.com/llvm/llvm-project/pull/92277 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instrumentation] Move out to Utils (NFC) (PR #108532)
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/108532 Utility functions have been moved out to Utils. Minor opportunity to drop the header where not needed. >From 42fef89fcc75d7f1f869c70d5357fcf3a0d410e1 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 13 Sep 2024 11:43:30 +0200 Subject: [PATCH] [Instrumentation] Move out to Utils (NFC) Utility functions have been moved out to Utils. --- clang/lib/CodeGen/BackendUtil.cpp | 1 - llvm/include/llvm/Passes/PassBuilder.h | 1 - llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h | 2 +- llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h | 2 +- .../llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h | 2 +- .../include/llvm/Transforms/Instrumentation/SanitizerCoverage.h | 2 +- llvm/include/llvm/Transforms/{ => Utils}/Instrumentation.h | 0 llvm/lib/Passes/PassBuilder.cpp | 2 +- llvm/lib/Transforms/IPO/SampleProfile.cpp | 2 +- llvm/lib/Transforms/IPO/SampleProfileProbe.cpp | 2 +- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp| 2 +- llvm/lib/Transforms/Instrumentation/CGProfile.cpp | 2 +- llvm/lib/Transforms/Instrumentation/CMakeLists.txt | 1 - llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 2 +- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp | 2 +- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 2 +- llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp | 2 +- llvm/lib/Transforms/Instrumentation/InstrOrderFile.cpp | 2 +- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | 2 +- llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 2 +- .../Transforms/Instrumentation/NumericalStabilitySanitizer.cpp | 2 +- llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 2 +- llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 2 +- llvm/lib/Transforms/Utils/CMakeLists.txt| 1 + .../Transforms/{Instrumentation => Utils}/Instrumentation.cpp | 2 +- llvm/tools/lli/lli.cpp | 1 - 26 files changed, 21 insertions(+), 24 deletions(-) rename llvm/include/llvm/Transforms/{ => Utils}/Instrumentation.h (100%) rename llvm/lib/Transforms/{Instrumentation => Utils}/Instrumentation.cpp (98%) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 7fa69420298160..d6fdd79db1b5af 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -64,7 +64,6 @@ #include "llvm/Transforms/IPO/LowerTypeTests.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/InstCombine/InstCombine.h" -#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index e1d78a8685aed2..e6ced0cccb9b3c 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -25,7 +25,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO/Inliner.h" #include "llvm/Transforms/IPO/ModuleInliner.h" -#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" #include #include diff --git a/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h b/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h index e5b4520f36a2fd..f92cee0cf1 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h +++ b/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h @@ -13,7 +13,7 @@ #define LLVM_TRANSFORMS_INSTRUMENTATION_GCOVPROFILER_H #include "llvm/IR/PassManager.h" -#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Utils/Instrumentation.h" namespace llvm { /// The gcov-style instrumentation pass diff --git a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h index 0dd37c9ca58b7e..2042700ad6b6ad 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h +++ b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h @@ -14,7 +14,7 @@ #define LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H #include "llvm/IR/PassManager.h" -#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Utils/Instrumentation.h" namespace llvm { diff --git a/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h b/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h index 800a1d583f8015..9efa23108d6a38 100644 --- a/llvm/include/llv
[clang] [llvm] [Instrumentation] Move out to Utils (NFC) (PR #108532)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/108532 >From 4518980e2698b76825d9650373df7414f61062d9 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 13 Sep 2024 11:43:30 +0200 Subject: [PATCH] [Instrumentation] Move out to Utils (NFC) Utility functions have been moved out to Utils. --- clang/lib/CodeGen/BackendUtil.cpp | 1 - llvm/include/llvm/Passes/PassBuilder.h| 1 - .../llvm/Transforms/Instrumentation/GCOVProfiler.h| 2 +- .../llvm/Transforms/Instrumentation/InstrProfiling.h | 2 +- .../Transforms/Instrumentation/SanitizerBinaryMetadata.h | 2 +- .../llvm/Transforms/Instrumentation/SanitizerCoverage.h | 2 +- .../include/llvm/Transforms/{ => Utils}/Instrumentation.h | 0 llvm/lib/Passes/PassBuilder.cpp | 2 +- llvm/lib/Transforms/IPO/SampleProfile.cpp | 2 +- llvm/lib/Transforms/IPO/SampleProfileProbe.cpp| 2 +- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 2 +- llvm/lib/Transforms/Instrumentation/CGProfile.cpp | 2 +- llvm/lib/Transforms/Instrumentation/CMakeLists.txt| 1 - llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 2 +- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp | 2 +- .../lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 2 +- .../Transforms/Instrumentation/IndirectCallPromotion.cpp | 2 +- llvm/lib/Transforms/Instrumentation/InstrOrderFile.cpp| 2 +- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp| 2 +- llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 2 +- .../Instrumentation/NumericalStabilitySanitizer.cpp | 2 +- .../lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 2 +- llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 2 +- llvm/lib/Transforms/Utils/CMakeLists.txt | 1 + .../{Instrumentation => Utils}/Instrumentation.cpp| 8 +--- llvm/tools/lli/lli.cpp| 1 - 26 files changed, 25 insertions(+), 26 deletions(-) rename llvm/include/llvm/Transforms/{ => Utils}/Instrumentation.h (100%) rename llvm/lib/Transforms/{Instrumentation => Utils}/Instrumentation.cpp (95%) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 7fa69420298160..d6fdd79db1b5af 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -64,7 +64,6 @@ #include "llvm/Transforms/IPO/LowerTypeTests.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/InstCombine/InstCombine.h" -#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index e1d78a8685aed2..e6ced0cccb9b3c 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -25,7 +25,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO/Inliner.h" #include "llvm/Transforms/IPO/ModuleInliner.h" -#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" #include #include diff --git a/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h b/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h index e5b4520f36a2fd..f92cee0cf1 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h +++ b/llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h @@ -13,7 +13,7 @@ #define LLVM_TRANSFORMS_INSTRUMENTATION_GCOVPROFILER_H #include "llvm/IR/PassManager.h" -#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Utils/Instrumentation.h" namespace llvm { /// The gcov-style instrumentation pass diff --git a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h index 0dd37c9ca58b7e..2042700ad6b6ad 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h +++ b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h @@ -14,7 +14,7 @@ #define LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H #include "llvm/IR/PassManager.h" -#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Utils/Instrumentation.h" namespace llvm { diff --git a/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h b/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h index 800a1d583f8015..9efa23108d6a38 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h +++ b/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h @@ -16,7 +16,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" -#include "
[clang] [llvm] [CVP] #114820 add 'samesign' for 'icmp' (PR #115642)
https://github.com/antoniofrighetto approved this pull request. https://github.com/llvm/llvm-project/pull/115642 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [CVP] #114820 add 'samesign' for 'icmp' (PR #115642)
https://github.com/antoniofrighetto closed https://github.com/llvm/llvm-project/pull/115642 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [CVP] Add `samesign` flag to `icmp` (PR #115642)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/115642 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [clang][CodeGen][AA] Add `!llvm.errno.tbaa` gathering int-compatible TBAA nodes (PR #125258)
antoniofrighetto wrote: @nikic Mind glancing over the draft quickly? !llvm.errno.tbaa is being attached to individual load/store accessing errno, although I just realized that this information is already embedded in TBAA, so IIUC !llvm.errno.tbaa should just be a module-level list of int-compatible TBAA nodes. Is my latest understanding correct? That would make it much simpler than I thought. Sorry if I’m missing something! https://github.com/llvm/llvm-project/pull/125258 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [InferAttrs] Mark errnomem-setting libcalls as such (PR #124742)
@@ -128,6 +128,15 @@ static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc, ME |= MemoryEffects::argMemOnly(MR); return; } + // TODO: This should be refined to use upcoming Loc.TBAAErrno for errno + // memory, rather than manually inspecting the underlying object. + if (isa(UO)) { +auto *Callee = cast(UO)->getCalledFunction(); +if (Callee && Callee->getName() == "__errno_location") { antoniofrighetto wrote: Right, clang on Windows links against UCRT, which declares _errno. This has to be taken into account. https://github.com/llvm/llvm-project/pull/124742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [InferAttrs] Mark errnomem-setting libcalls as such (PR #124742)
@@ -672,13 +703,15 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); +Changed |= setOnlyAccessesErrnoMemory(F); antoniofrighetto wrote: Does not modify the content of the path string in input, so it should make sense to have the pointer argument readonly? Agree that all the other functions have OS/file-system side-effects, so they do access inaccessible memory and errno. https://github.com/llvm/llvm-project/pull/124742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [InferAttrs] Mark errnomem-setting libcalls as such (PR #124742)
@@ -554,6 +579,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); +Changed |= setOnlyAccessesErrnoMemory(F); antoniofrighetto wrote: Hmm, shouldn’t marking all pointer arguments as readonly be semantically equivalent to having ArgMem: Ref? https://github.com/llvm/llvm-project/pull/124742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
@@ -82,7 +82,7 @@ define void @test_store(ptr %p) { @G = external global ptr define i8 @test_store_capture(ptr %p) { -; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none) +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none, errnomem: none) antoniofrighetto wrote: Hmm, the pointer is never accessed with an integer size, it should never alias errno, so should be correct to infer NoModRef for `test_store_capture`? Though now I think we might still miss something as follows while inferring attributes (and then let AA conclude if it aliases errno or not)? ```c++ if (Loc->Size == LocationSize::precise(sizeof(int))) ME |= MemoryEffects::errnoMemOnly(MR); ``` https://github.com/llvm/llvm-project/pull/120783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/120783 >From 196421e40425290aa1296f63c8fd9fbf205ea4b9 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 20 Dec 2024 19:30:59 +0100 Subject: [PATCH] [IR][ModRef] Introduce `errno` memory location Model C/C++ `errno` macro by adding a corresponding `errno` memory location kind to the IR. Preliminary work to separate `errno` writes from other memory accesses, to the benefit of alias analyses and optimization correctness. Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972. --- .../CodeGen/sanitize-metadata-nosanitize.c| 18 ++--- clang/test/CodeGenOpenCL/convergent.cl| 2 +- llvm/include/llvm/AsmParser/LLToken.h | 5 ++ llvm/include/llvm/Bitcode/LLVMBitCodes.h | 4 ++ llvm/include/llvm/IR/Function.h | 20 ++ llvm/include/llvm/IR/InstrTypes.h | 20 ++ llvm/include/llvm/Support/ModRef.h| 68 +- llvm/lib/AsmParser/LLLexer.cpp| 5 ++ llvm/lib/AsmParser/LLParser.cpp | 16 - llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 37 ++ llvm/lib/IR/Attributes.cpp| 3 + llvm/lib/IR/Function.cpp | 39 ++ llvm/lib/IR/Instructions.cpp | 39 ++ llvm/lib/Support/ModRef.cpp | 3 + llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 14 .../test/Assembler/memory-attribute-errors.ll | 6 +- llvm/test/Assembler/memory-attribute.ll | 12 .../Transforms/FunctionAttrs/argmemonly.ll| 22 +++--- .../Transforms/FunctionAttrs/nocapture.ll | 30 .../FunctionAttrs/read-write-errnomem.ll | 71 +++ .../FunctionAttrs/read-write-scc.ll | 4 +- .../Transforms/FunctionAttrs/readattrs.ll | 2 +- .../Transforms/FunctionAttrs/writeonly.ll | 4 +- .../InferFunctionAttrs/norecurse_debug.ll | 2 +- .../cfi-nounwind-direct-call.ll | 2 +- .../Transforms/SCCP/ipscp-drop-argmemonly.ll | 12 ++-- llvm/unittests/Support/ModRefTest.cpp | 4 +- mlir/test/Target/LLVMIR/llvmir.mlir | 10 +-- 28 files changed, 413 insertions(+), 61 deletions(-) create mode 100644 llvm/test/Transforms/FunctionAttrs/read-write-errnomem.ll diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index eabcbd1409fe2b..ff98d0b21e3f11 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -10,7 +10,7 @@ // CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }] // CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }] //. -// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local void @escape // CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META2:![0-9]+]] { // CHECK-NEXT: entry: @@ -21,7 +21,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) { sink = p; } -// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @normal_function // CHECK-SAME: (ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { // CHECK-NEXT: entry: @@ -38,7 +38,7 @@ int normal_function(int *x, int *y) { return *y; } -// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation // CHECK-SAME: (ptr noundef [[X:%.*
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
@@ -82,7 +82,7 @@ define void @test_store(ptr %p) { @G = external global ptr define i8 @test_store_capture(ptr %p) { -; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none) +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none, errnomem: none) antoniofrighetto wrote: Hmm, need to take a better look at this. https://github.com/llvm/llvm-project/pull/120783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
@@ -82,7 +82,7 @@ define void @test_store(ptr %p) { @G = external global ptr define i8 @test_store_capture(ptr %p) { -; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none) +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none, errnomem: none) antoniofrighetto wrote: Mind checking that the last fixup commit is more aligned with what you thought? Can drop the check in addLocAccess if deemed unneeded. https://github.com/llvm/llvm-project/pull/120783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/120783 >From 81c1e35fc28f43c2f23df328244de0528f4bf1d0 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 20 Dec 2024 19:30:59 +0100 Subject: [PATCH 1/2] [IR][ModRef] Introduce `errno` memory location Model C/C++ `errno` macro by adding a corresponding `errno` memory location kind to the IR. Preliminary work to separate `errno` writes from other memory accesses, to the benefit of alias analyses and optimization correctness. Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972. --- llvm/include/llvm/AsmParser/LLToken.h | 2 ++ llvm/include/llvm/IR/Function.h | 4 +++ llvm/include/llvm/IR/InstrTypes.h | 4 +++ llvm/include/llvm/Support/ModRef.h| 19 +++- llvm/lib/AsmParser/LLLexer.cpp| 1 + llvm/lib/AsmParser/LLParser.cpp | 7 - llvm/lib/IR/Attributes.cpp| 3 ++ llvm/lib/IR/Function.cpp | 8 + llvm/lib/IR/Instructions.cpp | 8 + llvm/lib/Support/ModRef.cpp | 3 ++ .../test/Assembler/memory-attribute-errors.ll | 6 ++-- llvm/test/Assembler/memory-attribute.ll | 12 .../Transforms/FunctionAttrs/argmemonly.ll| 22 +++--- .../Transforms/FunctionAttrs/nocapture.ll | 30 +-- .../FunctionAttrs/read-write-scc.ll | 4 +-- .../Transforms/FunctionAttrs/readattrs.ll | 2 +- .../Transforms/FunctionAttrs/writeonly.ll | 4 +-- .../InferFunctionAttrs/norecurse_debug.ll | 2 +- .../cfi-nounwind-direct-call.ll | 2 +- .../Transforms/SCCP/ipscp-drop-argmemonly.ll | 12 llvm/unittests/Support/ModRefTest.cpp | 4 +-- 21 files changed, 113 insertions(+), 46 deletions(-) diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index 178c911120b4ce..ac0887f8e5fb52 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -201,11 +201,13 @@ enum Kind { kw_readwrite, kw_argmem, kw_inaccessiblemem, + kw_errnomem, // Legacy memory attributes: kw_argmemonly, kw_inaccessiblememonly, kw_inaccessiblemem_or_argmemonly, + kw_errnomemonly, // nofpclass attribute: kw_all, diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index e7afcbd31420c1..bb8e6d5a7e38ec 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -575,6 +575,10 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node { bool onlyAccessesInaccessibleMemory() const; void setOnlyAccessesInaccessibleMemory(); + /// Determine if the function may only access errno memory. + bool onlyAccessesErrnoMemory() const; + void setOnlyAccessesErrnoMemory(); + /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. bool onlyAccessesInaccessibleMemOrArgMem() const; diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index e6332a16df7d5f..ba9a5c21467ec4 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1907,6 +1907,10 @@ class CallBase : public Instruction { bool onlyAccessesInaccessibleMemory() const; void setOnlyAccessesInaccessibleMemory(); + /// Determine if the function may only access errno memory. + bool onlyAccessesErrnoMemory() const; + void setOnlyAccessesErrnoMemory(); + /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. bool onlyAccessesInaccessibleMemOrArgMem() const; diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h index 5a9d80c87ae27a..b5071246d36c2f 100644 --- a/llvm/include/llvm/Support/ModRef.h +++ b/llvm/include/llvm/Support/ModRef.h @@ -61,8 +61,10 @@ enum class IRMemLocation { ArgMem = 0, /// Memory that is inaccessible via LLVM IR. InaccessibleMem = 1, + /// Errno memory. + ErrnoMem = 2, /// Any other memory. - Other = 2, + Other = 3, /// Helpers to iterate all locations in the MemoryEffectsBase class. First = ArgMem, @@ -139,6 +141,11 @@ template class MemoryEffectsBase { return MemoryEffectsBase(Location::InaccessibleMem, MR); } + /// Create MemoryEffectsBase that can only access errno memory. + static MemoryEffectsBase errnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) { +return MemoryEffectsBase(Location::ErrnoMem, MR); + } + /// Create MemoryEffectsBase that can only access inaccessible or argument /// memory. static MemoryEffectsBase @@ -207,11 +214,21 @@ template class MemoryEffectsBase { return isModOrRefSet(getModRef(Location::ArgMem)); } + /// Whether this function may access errno memory. + bool doesAccessErrno
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11610,9 +11610,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()); + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()); + antoniofrighetto wrote: Space between type and pointer. ```suggestion (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()); ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11715,52 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::InvalidExplicitArguments: { assert(ParamD && "no parameter found for invalid explicit arguments"); -if (ParamD->getDeclName()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "type"; +else { + // TODO write tests for type constrained classes + if (auto *constraint = TTPD->getTypeConstraint()) +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) +<< ParamD->getDeclName() << FirstArg << SecondArg << ParamName +<< "valid type-constrained class"; + else +S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) +<< ParamD->getDeclName() << FirstArg << SecondArg << ParamName +<< "class"; +} + } else if (auto *NTTPD = dyn_cast(ParamD)) { +if (SecondArg.isNull()) { + // Expected constant of type 'int', got type 'int' + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_nsp) + << ParamD->getDeclName() << FirstArg << NTTPD->getType(); +} else { + // Could not convert A from B to C + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_nttpd_sp) + << ParamD->getDeclName() << FirstArg << SecondArg + << NTTPD->getType(); +} + } else if (auto *TTempPD = dyn_cast(ParamD)) { antoniofrighetto wrote: ```suggestion } else if (isa(ParamD)) { ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11714,13 +11715,52 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case TemplateDeductionResult::InvalidExplicitArguments: + case TemplateDeductionResult::InvalidExplicitArguments: { assert(ParamD && "no parameter found for invalid explicit arguments"); -if (ParamD->getDeclName()) - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_explicit_arg_mismatch_named) - << ParamD->getDeclName(); -else { +if (ParamD->getDeclName()) { + TemplateArgument FirstArg = *DeductionFailure.getFirstArg(); + std::string ParamName = ParamD->getNameAsString(); + TemplateArgument SecondArg = *DeductionFailure.getSecondArg(); + + if (auto *TTPD = dyn_cast(ParamD)) { +if (TTPD->wasDeclaredWithTypename()) + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_explicit_arg_mismatch_named_ttpd) + << ParamD->getDeclName() << FirstArg << SecondArg << ParamName + << "type"; +else { + // TODO write tests for type constrained classes + if (auto *constraint = TTPD->getTypeConstraint()) antoniofrighetto wrote: ```suggestion if (TTPD->getTypeConstraint()) ``` https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
@@ -11610,9 +11610,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()) || - (ParamD = Param.dyn_cast()); + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()) || + (ParamD = Param.dyn_cast()); + antoniofrighetto wrote: No strong concerns. However, since this change surrounds the code that's being added and only fixes a minor styling issue, I think it may be acceptable to address it in this commit—unless we have documentation that explicitly discourages doing so (I couldn’t find any mention of that). Should `@AidanGoldfarb` be willing to fix all related old-style issues in this file, it would make sense to have a dedicate commit. https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/120783 >From 54d3ac991abaa341dd4798bbf6aeb3ede4441d64 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 20 Dec 2024 19:30:59 +0100 Subject: [PATCH] [IR][ModRef] Introduce `errno` memory location Model C/C++ `errno` macro by adding a corresponding `errno` memory location kind to the IR. Preliminary work to separate `errno` writes from other memory accesses, to the benefit of alias analyses and optimization correctness. Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972. --- .../CodeGen/sanitize-metadata-nosanitize.c| 18 +++--- clang/test/CodeGenOpenCL/convergent.cl| 2 +- llvm/include/llvm/AsmParser/LLToken.h | 4 ++ llvm/include/llvm/Bitcode/LLVMBitCodes.h | 3 + llvm/include/llvm/IR/Function.h | 15 + llvm/include/llvm/IR/InstrTypes.h | 15 + llvm/include/llvm/Support/ModRef.h| 57 ++- llvm/lib/AsmParser/LLLexer.cpp| 4 ++ llvm/lib/AsmParser/LLParser.cpp | 13 - llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 28 + llvm/lib/IR/Attributes.cpp| 3 + llvm/lib/IR/Function.cpp | 29 ++ llvm/lib/IR/Instructions.cpp | 29 ++ llvm/lib/Support/ModRef.cpp | 3 + .../test/Assembler/memory-attribute-errors.ll | 6 +- llvm/test/Assembler/memory-attribute.ll | 12 .../Transforms/FunctionAttrs/argmemonly.ll| 22 +++ .../Transforms/FunctionAttrs/nocapture.ll | 30 +- .../FunctionAttrs/read-write-scc.ll | 4 +- .../Transforms/FunctionAttrs/readattrs.ll | 2 +- .../Transforms/FunctionAttrs/writeonly.ll | 4 +- .../InferFunctionAttrs/norecurse_debug.ll | 2 +- .../cfi-nounwind-direct-call.ll | 2 +- .../Transforms/SCCP/ipscp-drop-argmemonly.ll | 12 ++-- llvm/unittests/Support/ModRefTest.cpp | 4 +- mlir/test/Target/LLVMIR/llvmir.mlir | 10 ++-- 26 files changed, 272 insertions(+), 61 deletions(-) diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index fd2fdce31b52fb..77dc7d9d492ecc 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -10,7 +10,7 @@ // CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }] // CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }] //. -// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local void @escape // CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META2:![0-9]+]] { // CHECK-NEXT: entry: @@ -21,7 +21,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) { sink = p; } -// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @normal_function // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { // CHECK-NEXT: entry: @@ -38,7 +38,7 @@ int normal_function(int *x, int *y) { return *y; } -// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: @@ -55,7 +55,7 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
@@ -82,7 +82,7 @@ define void @test_store(ptr %p) { @G = external global ptr define i8 @test_store_capture(ptr %p) { -; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none) +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none, errnomem: none) antoniofrighetto wrote: While walking the call-graph for deducing attrs, in `checkFunctionMemoryAccess` we initialize a ME object that doesn't access/modify memory and gradually refine it (currently says ErrnoMem: NoModRef). This ME is intersected with the original ME based on AA results (which says ErrnoMem: ModRef), so we get NoModRef, as per the meet of the lattice. We miss logic to infer if the function clobbers errno, but I think it should be fine as the PR only introduces the location (it might be better to conservatively always say ModRef, but the location is currently unused, so it should be okay to address this in an upcoming PR?). Rebased to main too. https://github.com/llvm/llvm-project/pull/120783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/120783 >From 54d3ac991abaa341dd4798bbf6aeb3ede4441d64 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 20 Dec 2024 19:30:59 +0100 Subject: [PATCH 1/2] [IR][ModRef] Introduce `errno` memory location Model C/C++ `errno` macro by adding a corresponding `errno` memory location kind to the IR. Preliminary work to separate `errno` writes from other memory accesses, to the benefit of alias analyses and optimization correctness. Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972. --- .../CodeGen/sanitize-metadata-nosanitize.c| 18 +++--- clang/test/CodeGenOpenCL/convergent.cl| 2 +- llvm/include/llvm/AsmParser/LLToken.h | 4 ++ llvm/include/llvm/Bitcode/LLVMBitCodes.h | 3 + llvm/include/llvm/IR/Function.h | 15 + llvm/include/llvm/IR/InstrTypes.h | 15 + llvm/include/llvm/Support/ModRef.h| 57 ++- llvm/lib/AsmParser/LLLexer.cpp| 4 ++ llvm/lib/AsmParser/LLParser.cpp | 13 - llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 28 + llvm/lib/IR/Attributes.cpp| 3 + llvm/lib/IR/Function.cpp | 29 ++ llvm/lib/IR/Instructions.cpp | 29 ++ llvm/lib/Support/ModRef.cpp | 3 + .../test/Assembler/memory-attribute-errors.ll | 6 +- llvm/test/Assembler/memory-attribute.ll | 12 .../Transforms/FunctionAttrs/argmemonly.ll| 22 +++ .../Transforms/FunctionAttrs/nocapture.ll | 30 +- .../FunctionAttrs/read-write-scc.ll | 4 +- .../Transforms/FunctionAttrs/readattrs.ll | 2 +- .../Transforms/FunctionAttrs/writeonly.ll | 4 +- .../InferFunctionAttrs/norecurse_debug.ll | 2 +- .../cfi-nounwind-direct-call.ll | 2 +- .../Transforms/SCCP/ipscp-drop-argmemonly.ll | 12 ++-- llvm/unittests/Support/ModRefTest.cpp | 4 +- mlir/test/Target/LLVMIR/llvmir.mlir | 10 ++-- 26 files changed, 272 insertions(+), 61 deletions(-) diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index fd2fdce31b52fb..77dc7d9d492ecc 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -10,7 +10,7 @@ // CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }] // CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }] //. -// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local void @escape // CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META2:![0-9]+]] { // CHECK-NEXT: entry: @@ -21,7 +21,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) { sink = p; } -// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @normal_function // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { // CHECK-NEXT: entry: @@ -38,7 +38,7 @@ int normal_function(int *x, int *y) { return *y; } -// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: @@ -55,7 +55,7 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_
[clang] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
antoniofrighetto wrote: Kind ping for correct direction. https://github.com/llvm/llvm-project/pull/120783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Improve template argument deduction diagnostic (PR #122754)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/122754 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang][CodeGen][AA] Add `!llvm.errno.tbaa` gathering int-compatible TBAA nodes (PR #125258)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/125258 >From 25e79b19581d47924c4b1a56d954031a09600b8f Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Tue, 18 Feb 2025 16:36:12 +0100 Subject: [PATCH 1/3] [GVN] Introduce test for PR125258 (NFC) --- .../test/Transforms/GVN/does-clobber-errno.ll | 27 +++ 1 file changed, 27 insertions(+) create mode 100644 llvm/test/Transforms/GVN/does-clobber-errno.ll diff --git a/llvm/test/Transforms/GVN/does-clobber-errno.ll b/llvm/test/Transforms/GVN/does-clobber-errno.ll new file mode 100644 index 0..4c68789a09dcd --- /dev/null +++ b/llvm/test/Transforms/GVN/does-clobber-errno.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes=gvn -S < %s | FileCheck %s + +; FIXME: This is a miscompilation. +define noundef i32 @test_malloc_clobbering_errno() { +; CHECK-LABEL: define noundef i32 @test_malloc_clobbering_errno() { +; CHECK-NEXT:[[TMP1:%.*]] = alloca ptr, align 8 +; CHECK-NEXT:[[TMP2:%.*]] = call ptr @__errno_location() +; CHECK-NEXT:store i32 0, ptr [[TMP2]], align 4 +; CHECK-NEXT:[[TMP3:%.*]] = call noalias ptr @malloc(i64 1844674407370955161) +; CHECK-NEXT:store volatile ptr [[TMP3]], ptr [[TMP1]], align 8 +; CHECK-NEXT:ret i32 0 +; + %1 = alloca ptr, align 8 + %2 = call ptr @__errno_location() + store i32 0, ptr %2, align 4 + %3 = call noalias ptr @malloc(i64 1844674407370955161) + store volatile ptr %3, ptr %1, align 8 + %4 = load i32, ptr %2, align 4 + ret i32 %4 +} + +declare ptr @__errno_location() #1 +declare noalias ptr @malloc(i64) #2 + +attributes #1 = { mustprogress nofree nosync nounwind willreturn memory(none) } +attributes #2 = { mustprogress nofree nounwind willreturn memory(inaccessiblemem: readwrite) } >From b88ac9fb739ac495c31f09a57afcf240be84bab5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Tue, 18 Feb 2025 15:32:09 +0100 Subject: [PATCH 2/3] [clang][CodeGen][AA] Add `!llvm.errno.tbaa` listing int-compatible TBAA nodes Model integer accesses through an ad-hoc TBAA module-level metadata, so as to disambiguate integer accesses from non-integer ones, at TBAA level. This is purposefully as part of handling `errno` accesses, which are guaranteed to be integer-compatible. --- clang/lib/CodeGen/CodeGenModule.cpp | 7 +++ .../test/Transforms/GVN/does-clobber-errno.ll | 6 +-- .../Transforms/InstCombine/may-alias-errno.ll | 49 +++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/may-alias-errno.ll diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 7924c32fcf633..3e8917a7b587d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -83,6 +83,7 @@ static llvm::cl::opt LimitedCoverage( llvm::cl::desc("Emit limited coverage mapping information (experimental)")); static const char AnnotationSection[] = "llvm.metadata"; +static constexpr auto ErrnoTBAAMDName = "llvm.errno.tbaa"; static CGCXXABI *createCXXABI(CodeGenModule &CGM) { switch (CGM.getContext().getCXXABIKind()) { @@ -1457,6 +1458,12 @@ void CodeGenModule::Release() { } } } + + if (TBAA) { +auto *ErrnoTBAAMD = TheModule.getOrInsertNamedMetadata(ErrnoTBAAMDName); +llvm::MDNode *IntegerNode = TBAA->getTypeInfo(Context.IntTy); +ErrnoTBAAMD->addOperand(IntegerNode); + } } void CodeGenModule::EmitOpenCLMetadata() { diff --git a/llvm/test/Transforms/GVN/does-clobber-errno.ll b/llvm/test/Transforms/GVN/does-clobber-errno.ll index 4c68789a09dcd..7c625b10eac7b 100644 --- a/llvm/test/Transforms/GVN/does-clobber-errno.ll +++ b/llvm/test/Transforms/GVN/does-clobber-errno.ll @@ -1,7 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -passes=gvn -S < %s | FileCheck %s -; FIXME: This is a miscompilation. define noundef i32 @test_malloc_clobbering_errno() { ; CHECK-LABEL: define noundef i32 @test_malloc_clobbering_errno() { ; CHECK-NEXT:[[TMP1:%.*]] = alloca ptr, align 8 @@ -9,7 +8,8 @@ define noundef i32 @test_malloc_clobbering_errno() { ; CHECK-NEXT:store i32 0, ptr [[TMP2]], align 4 ; CHECK-NEXT:[[TMP3:%.*]] = call noalias ptr @malloc(i64 1844674407370955161) ; CHECK-NEXT:store volatile ptr [[TMP3]], ptr [[TMP1]], align 8 -; CHECK-NEXT:ret i32 0 +; CHECK-NEXT:[[TMP4:%.*]] = load i32, ptr [[TMP2]], align 4 +; CHECK-NEXT:ret i32 [[TMP4]] ; %1 = alloca ptr, align 8 %2 = call ptr @__errno_location() @@ -24,4 +24,4 @@ declare ptr @__errno_location() #1 declare noalias ptr @malloc(i64) #2 attributes #1 = { mustprogress nofree nosync nounwind willreturn memory(none) } -attributes #2 = { mustprogress nofree nounwind willreturn memory(inaccessiblemem: readwrite) } +attributes #2 = { mustprogress
[clang] [llvm] [clang][CodeGen][AA] Add `!llvm.errno.tbaa` gathering int-compatible TBAA nodes (PR #125258)
antoniofrighetto wrote: > > so IIUC !llvm.errno.tbaa should just be a module-level list of > > int-compatible TBAA nodes. > > Yes, exactly. It should be a module level MD node, not on individual > instructions. Thank you, I'm updating this. I've been contemplating this, and thought originally we needed to extend TBAA (like aliasErrno as per tmp commit), but TBAA seems to take care of this already (as clang propagates int TBAA correctly to the call), so I think this shouldn't be needed. Though, I *believe* there should be some additional AA handling (along the ifdef lines), is that correct? https://github.com/llvm/llvm-project/pull/125258 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate `volatile` during derived-to-base conversion (PR #127824)
@@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s antoniofrighetto wrote: Added a test in CodeGen too, thanks! https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From aebd5455e9cf583b9f5a29c68d5217f49c7a49b5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH 1/2] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 6 ++-- clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../SemaCXX/derived-to-base-cv-qualifiers.cpp | 34 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 62a64ff57599d..c96c79c8e6d6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -171,6 +171,8 @@ Bug Fixes to C++ Support - The initialization kind of elements of structured bindings direct-list-initialized from an array is corrected to direct-initialization. - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf95c415..c4d18609316ab 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3107,8 +3107,10 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + DestType = Context.getQualifiedType(DestType, FromType.getQualifiers()); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp new file mode 100644 index 0..02a5bf8f6cecf --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK: |-FunctionDecl {{.*}} test_volatile_store 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-BinaryOperator {{.*}} 'volatile int' lvalue '=' +// CHECK-NEXT: |-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK: `-FunctionDecl {{.*}} test_volatile_load 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-DeclStmt {{.*}} +// CHECK-NEXT: `-VarDecl {{.*}} Val 'int' cinit +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: | `-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} >From 6b49fd9dd1ada060385b2f07c34227602bf81655 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Sat, 22 Feb 2025 16:42:36 +0100 Subject: [PATCH 2/2] !fixup fix ci issue --- clang/lib/Sema/SemaExpr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaExpr.cp
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From aebd5455e9cf583b9f5a29c68d5217f49c7a49b5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH 1/2] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 6 ++-- clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../SemaCXX/derived-to-base-cv-qualifiers.cpp | 34 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 62a64ff57599d..c96c79c8e6d6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -171,6 +171,8 @@ Bug Fixes to C++ Support - The initialization kind of elements of structured bindings direct-list-initialized from an array is corrected to direct-initialization. - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf95c415..c4d18609316ab 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3107,8 +3107,10 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + DestType = Context.getQualifiedType(DestType, FromType.getQualifiers()); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp new file mode 100644 index 0..02a5bf8f6cecf --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK: |-FunctionDecl {{.*}} test_volatile_store 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-BinaryOperator {{.*}} 'volatile int' lvalue '=' +// CHECK-NEXT: |-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK: `-FunctionDecl {{.*}} test_volatile_load 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-DeclStmt {{.*}} +// CHECK-NEXT: `-VarDecl {{.*}} Val 'int' cinit +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: | `-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} >From da6e4602f7381946d8a0c0d0d41b89ffc951de6a Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Sat, 22 Feb 2025 16:42:36 +0100 Subject: [PATCH 2/2] !fixup fix ci issue --- clang/lib/Sema/SemaExpr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaExpr.cpp
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
@@ -3107,8 +3107,11 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + if (FromType.isVolatileQualified()) +DestType.addVolatile(); antoniofrighetto wrote: EDIT: Moving from: ```cpp DestType = Context.getQualifiedType(DestType, FromType.getQualifiers()); ``` To CVR ones for now: ```cpp DestType.withCVRQualifiers(FromType.getCVRQualifiers()); ``` Per CI failure [here](https://buildkite.com/llvm-project/github-pull-requests/builds/149797#01952e46-e199-450d-978b-2f763cd9b9c0), due to incompatibility between address spaces. Not completely sure if we should setAddressSpace of DestType AS one to the one of FromType, before getQualifiedType. https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From aebd5455e9cf583b9f5a29c68d5217f49c7a49b5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH 1/2] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 6 ++-- clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../SemaCXX/derived-to-base-cv-qualifiers.cpp | 34 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 62a64ff57599d..c96c79c8e6d6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -171,6 +171,8 @@ Bug Fixes to C++ Support - The initialization kind of elements of structured bindings direct-list-initialized from an array is corrected to direct-initialization. - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf95c415..c4d18609316ab 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3107,8 +3107,10 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + DestType = Context.getQualifiedType(DestType, FromType.getQualifiers()); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp new file mode 100644 index 0..02a5bf8f6cecf --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK: |-FunctionDecl {{.*}} test_volatile_store 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-BinaryOperator {{.*}} 'volatile int' lvalue '=' +// CHECK-NEXT: |-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK: `-FunctionDecl {{.*}} test_volatile_load 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-DeclStmt {{.*}} +// CHECK-NEXT: `-VarDecl {{.*}} Val 'int' cinit +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: | `-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} >From 8646973726cc1639794f42f696e8d8af27c4bfa0 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Sat, 22 Feb 2025 16:42:36 +0100 Subject: [PATCH 2/2] !fixup fix ci issue --- clang/lib/Sema/SemaExpr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaExpr.c
[clang] [clang][Sema] Propagate `volatile` during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From aebd5455e9cf583b9f5a29c68d5217f49c7a49b5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 6 ++-- clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../SemaCXX/derived-to-base-cv-qualifiers.cpp | 34 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 62a64ff57599d..c96c79c8e6d6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -171,6 +171,8 @@ Bug Fixes to C++ Support - The initialization kind of elements of structured bindings direct-list-initialized from an array is corrected to direct-initialization. - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf95c415..c4d18609316ab 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3107,8 +3107,10 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + DestType = Context.getQualifiedType(DestType, FromType.getQualifiers()); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp new file mode 100644 index 0..02a5bf8f6cecf --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK: |-FunctionDecl {{.*}} test_volatile_store 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-BinaryOperator {{.*}} 'volatile int' lvalue '=' +// CHECK-NEXT: |-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK: `-FunctionDecl {{.*}} test_volatile_load 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-DeclStmt {{.*}} +// CHECK-NEXT: `-VarDecl {{.*}} Val 'int' cinit +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: | `-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate `volatile` during derived-to-base conversion (PR #127824)
@@ -3107,8 +3107,11 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + if (FromType.isVolatileQualified()) +DestType.addVolatile(); antoniofrighetto wrote: >From intro.object: > Objects can contain other objects, called subobjects. A subobject can be a > member subobject a base class subobject, or an array element. So, given: ```cpp struct Base { int X; }; struct Derived : Base {}; const Derived Obj; ``` Seems outright logical that the entirety of Obj must be const. Thought this applied only for cv-qualifiers, but should indeed make sense for all qualifiers; updated, thanks! https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Propagate `volatile` qualifier in derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From 1c7357a3279322ba469c1293d49bfba67b0565b5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH] [clang][Sema] Propagate `volatile` during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure the `volatile` qualifier is propagated to the base type. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/lib/Sema/SemaExpr.cpp | 7 -- .../SemaCXX/derived-to-base-volatile-qual.cpp | 23 +++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-volatile-qual.cpp diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf95c415..f9b9a05ce3da6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3107,8 +3107,11 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + if (FromType.isVolatileQualified()) +DestType.addVolatile(); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/SemaCXX/derived-to-base-volatile-qual.cpp b/clang/test/SemaCXX/derived-to-base-volatile-qual.cpp new file mode 100644 index 0..67df441b99a2a --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-volatile-qual.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK: `-FunctionDecl {{.*}} test_volatile_store 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-BinaryOperator {{.*}} 'volatile int' lvalue '=' +// CHECK-NEXT: |-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_store() { + Obj.Val = 0; +} + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate `volatile` during derived-to-base conversion (PR #127824)
antoniofrighetto wrote: > Should the result type of the ImplicitCastExpr be volatile in the AST? Definitely, updated, thanks! https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate `volatile` during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate `volatile` during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto edited https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From aebd5455e9cf583b9f5a29c68d5217f49c7a49b5 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH 1/3] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 6 ++-- clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../SemaCXX/derived-to-base-cv-qualifiers.cpp | 34 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 62a64ff57599d..c96c79c8e6d6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -171,6 +171,8 @@ Bug Fixes to C++ Support - The initialization kind of elements of structured bindings direct-list-initialized from an array is corrected to direct-initialization. - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf95c415..c4d18609316ab 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3107,8 +3107,10 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + DestType = Context.getQualifiedType(DestType, FromType.getQualifiers()); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp new file mode 100644 index 0..02a5bf8f6cecf --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-cv-qualifiers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK: |-FunctionDecl {{.*}} test_volatile_store 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-BinaryOperator {{.*}} 'volatile int' lvalue '=' +// CHECK-NEXT: |-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK: `-FunctionDecl {{.*}} test_volatile_load 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-DeclStmt {{.*}} +// CHECK-NEXT: `-VarDecl {{.*}} Val 'int' cinit +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: | `-MemberExpr {{.*}} 'volatile int' lvalue .Val +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} >From 8646973726cc1639794f42f696e8d8af27c4bfa0 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Sat, 22 Feb 2025 16:42:36 +0100 Subject: [PATCH 2/3] !fixup fix ci issue --- clang/lib/Sema/SemaExpr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaExpr.c
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
@@ -3107,8 +3107,12 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + Qualifiers FromTypeQuals = FromType.getQualifiers(); antoniofrighetto wrote: Added, thanks! https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeGen] Propagate `volatile` qualifier in derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/127824 A miscompilation issue has been addressed with improved handling. Fixes: https://github.com/llvm/llvm-project/issues/127683. >From fd06a833ba56f812693d89e19f594ed3f238fea4 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH] [clang][CodeGen] Propagate `volatile` qualifier in derived-to-base conversion A miscompilation issue has been addressed with improved handling. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/lib/CodeGen/CGExpr.cpp | 8 ++-- clang/test/CodeGenCXX/derived-to-base.cpp | 19 +++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 191912ca7d800..3bba142f2b96e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5403,8 +5403,12 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // TODO: Support accesses to members of base classes in TBAA. For now, we // conservatively pretend that the complete object is of the base class // type. -return MakeAddrLValue(Base, E->getType(), LV.getBaseInfo(), - CGM.getTBAAInfoForSubobject(LV, E->getType())); +LValue CastedLV = +MakeAddrLValue(Base, E->getType(), LV.getBaseInfo(), + CGM.getTBAAInfoForSubobject(LV, E->getType())); +if (LV.isVolatile()) + CastedLV.getQuals().addVolatile(); +return CastedLV; } case CK_ToUnion: return EmitAggExprToLValue(E); diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..37a8e6f7ea6b6 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,23 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() #0 +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From 47fc0c9fb963cef24a32078bc52232e69a93c211 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Feb 2025 16:47:18 +0100 Subject: [PATCH] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 + clang/lib/Sema/SemaExpr.cpp | 11 - clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../derived-to-base-propagate-qualifiers.cpp | 46 +++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 01b018857a7fc..034e6c691e05e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -299,6 +299,8 @@ Bug Fixes to C++ Support - Correctly diagnoses template template paramters which have a pack parameter not in the last position. - Clang now correctly parses ``if constexpr`` expressions in immediate function context. (#GH123524) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a36a2f563739e..ce3e726e560b2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3113,8 +3113,15 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + // Propagate qualifiers to base subobjects as per: + // C++ [basic.type.qualifier]p1.2: + // A volatile object is [...] a subobject of a volatile object. + Qualifiers FromTypeQuals = FromType.getQualifiers(); + FromTypeQuals.setAddressSpace(DestType.getAddressSpace()); + DestType = Context.getQualifiedType(DestType, FromTypeQuals); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp new file mode 100644 index 0..8a3b944ab1cb6 --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump -verify %s | FileCheck %s + +// Ensure qualifiers are preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +// Value-initialize base class subobjects with type qualifiers. +volatile Derived VObj; +const Derived CObj{}; // expected-note{{variable 'CObj' declared const here}} +const volatile Derived CVObj{}; // expected-note{{variable 'CVObj' declared const here}} +__attribute__((address_space(1))) Derived AddrSpaceObj{}; + +void test_store() { + // CHECK: `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue + VObj.Val = 0; + + // CHECK: `-ImplicitCastExpr {{.*}} 'const PR127683::Base' lvalue + CObj.Val = 1; // expected-error {{cannot assign to variable 'CObj' with const-qualified type 'const Derived'}} + + // CHECK: `-ImplicitCastExpr {{.*}} 'const volatile PR127683::Base' lvalue + CVObj.Val = 1; // expected-error {{cannot assign to variable 'CVObj' with const-qualified type 'const volatile Derived'}} + + // CHECK: `-ImplicitCastExpr {{.*}} '__attribute__((address_space(1))) PR127683::Base' lvalue
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
@@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump %s | FileCheck %s + +// Ensure volatile is preserved during derived-to-base conversion. antoniofrighetto wrote: Added, thanks! `__ptrauth` is in the process of being upstreamed, whereas `_Atomic` seems to have its own semantics (not part of Qualifiers, but rather QualifiersAndAtomic), and I'm not completely sure it would fit here (also accessing members of an atomic struct is UB). Concerning `__restrict`, shouldn't it be property of the pointer, not the object's type? I tried something like: ```cpp void test_restrict(Derived *__restrict D) { Base *B = D; } ``` Yet, in DerivedToBase, `__restrict` seems to be not included in Derived qualifiers (so contextually DestType has not it either, and in any case it should be orthogonal?). Rebased to main too. https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e9988c3 - [clang][Sema] Propagate qualifiers during derived-to-base conversion
Author: Antonio Frighetto Date: 2025-03-19T09:04:29+01:00 New Revision: e9988c36ed788b2d1ce00b028bed51169bd8b02c URL: https://github.com/llvm/llvm-project/commit/e9988c36ed788b2d1ce00b028bed51169bd8b02c DIFF: https://github.com/llvm/llvm-project/commit/e9988c36ed788b2d1ce00b028bed51169bd8b02c.diff LOG: [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. Added: clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaExpr.cpp clang/test/CodeGenCXX/derived-to-base.cpp Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ce4336acb806a..1c0504d831e3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -340,6 +340,8 @@ Bug Fixes to C++ Support - Fixed an assertion failure affecting code that uses C++23 "deducing this". (#GH130272) - Clang now properly instantiates destructors for initialized members within non-delegating constructors. (#GH93251) - Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3ff372bdc9d0c..a03acb5fbd273 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3113,8 +3113,15 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + // Propagate qualifiers to base subobjects as per: + // C++ [basic.type.qualifier]p1.2: + // A volatile object is [...] a subobject of a volatile object. + Qualifiers FromTypeQuals = FromType.getQualifiers(); + FromTypeQuals.setAddressSpace(DestType.getAddressSpace()); + DestType = Context.getQualifiedType(DestType, FromTypeQuals); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp new file mode 100644 index 0..8a3b944ab1cb6 --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump -verify %s | FileCheck %s + +// Ensure qualifiers are preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +// Value-initialize base class subobjects with type qualifiers. +volatile Derived VObj; +const Derived CObj{}; // expected-note{{variable 'CObj' declared const here}} +const volatile Derived CVObj{}; // expected-note{{variable 'CVObj' declared const here}} +__attribute__((address_space(1))) Derived AddrSpaceObj{}; + +void test_store() { + // CHECK: `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue + VObj.Val = 0; + + // CHECK: `-ImplicitCastExpr {{.*}} 'const PR127683::Base' lvalue + CObj.Val = 1; // expected-error {{cannot assign to variable 'CObj' with const-qualified type 'const Derived'}} + + // CHECK: `-ImplicitCastExpr {{.*}} 'const volatile PR127683::Base' lvalue + CVObj.Val = 1; // expected-error {{cannot assign to variable 'CVObj' with const-qualified type 'const volatile Derived'}} + + // CHECK: `-ImplicitCas
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto closed https://github.com/llvm/llvm-project/pull/127824 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Propagate qualifiers during derived-to-base conversion (PR #127824)
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/127824 >From e9988c36ed788b2d1ce00b028bed51169bd8b02c Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 19 Mar 2025 09:04:29 +0100 Subject: [PATCH] [clang][Sema] Propagate qualifiers during derived-to-base conversion When accessing a field member through a derived-to-base conversion, ensure qualifiers are propagated to the base class subobject. Fixes: https://github.com/llvm/llvm-project/issues/127683. --- clang/docs/ReleaseNotes.rst | 2 + clang/lib/Sema/SemaExpr.cpp | 11 - clang/test/CodeGenCXX/derived-to-base.cpp | 25 ++ .../derived-to-base-propagate-qualifiers.cpp | 46 +++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ce4336acb806a..1c0504d831e3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -340,6 +340,8 @@ Bug Fixes to C++ Support - Fixed an assertion failure affecting code that uses C++23 "deducing this". (#GH130272) - Clang now properly instantiates destructors for initialized members within non-delegating constructors. (#GH93251) - Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411) +- Clang was previously coalescing volatile writes to members of volatile base class subobjects. + The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3ff372bdc9d0c..a03acb5fbd273 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3113,8 +3113,15 @@ Sema::PerformObjectMemberConversion(Expr *From, /*IgnoreAccess=*/true)) return ExprError(); - return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); + // Propagate qualifiers to base subobjects as per: + // C++ [basic.type.qualifier]p1.2: + // A volatile object is [...] a subobject of a volatile object. + Qualifiers FromTypeQuals = FromType.getQualifiers(); + FromTypeQuals.setAddressSpace(DestType.getAddressSpace()); + DestType = Context.getQualifiedType(DestType, FromTypeQuals); + + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, VK, + &BasePath); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, diff --git a/clang/test/CodeGenCXX/derived-to-base.cpp b/clang/test/CodeGenCXX/derived-to-base.cpp index c8dbd5bf5cb05..c09a12b728bbb 100644 --- a/clang/test/CodeGenCXX/derived-to-base.cpp +++ b/clang/test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,29 @@ namespace test3 { } } +// Ensure volatile is preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +volatile Derived Obj; + +// CHECK-LABEL: define void @_ZN8PR12768319test_volatile_storeEv() +// CHECK: store volatile i32 0, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_store() { + Obj.Val = 0; +} + +// CHECK-LABEL: define void @_ZN8PR12768318test_volatile_loadEv() +// CHECK: %0 = load volatile i32, ptr @_ZN8PR1276833ObjE, align 4 +void test_volatile_load() { + [[maybe_unused]] int Val = Obj.Val; +} + +} + // CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} } diff --git a/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp b/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp new file mode 100644 index 0..8a3b944ab1cb6 --- /dev/null +++ b/clang/test/SemaCXX/derived-to-base-propagate-qualifiers.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump -verify %s | FileCheck %s + +// Ensure qualifiers are preserved during derived-to-base conversion. +namespace PR127683 { + +struct Base { + int Val; +}; + +struct Derived : Base { }; + +// Value-initialize base class subobjects with type qualifiers. +volatile Derived VObj; +const Derived CObj{}; // expected-note{{variable 'CObj' declared const here}} +const volatile Derived CVObj{}; // expected-note{{variable 'CVObj' declared const here}} +__attribute__((address_space(1))) Derived AddrSpaceObj{}; + +void test_store() { + // CHECK: `-ImplicitCastExpr {{.*}} 'volatile PR127683::Base' lvalue + VObj.Val = 0; + + // CHECK: `-ImplicitCastExpr {{.*}} 'const PR127683::Base' lvalue + CObj.Val = 1; // expected-error {{cannot assign to variable 'CObj' with const-qualified type 'const Derived'}} + + // CHECK: `-ImplicitCastExpr {{.*}} 'const volatile PR127683::Base' lvalue + CVObj.Val = 1; // expected-error {{cannot assign to variable 'CVObj' with const-qualified type 'const volatile Derived'}} + + /