Add -fipa-strict-aliasing
Commit Message
Hi,
ipa-modref is using TBAA to disambiguate memory accesses inter-procedurally.
This sometimes breaks programs with TBAA violations including clang with LTO.
To workaround that one can use -fno-strict-aliasing or -fno-ipa-modref which
are both quite big hammers. So I added -fipa-strict-aliasing patch that
controls only the TBAA based analysis in ipa-modref while keeping all other
optimizations.
Bootstrapped/regtested x86_64-linux, will commit it shortly.
gcc/ChangeLog:
2021-12-12 Jan Hubicka <hubicka@ucw.cz>
* common.opt: Add -fipa-strict-aliasing.
* doc/invoke.texi: Document -fipa-strict-aliasing.
* ipa-modref.c (modref_access_analysis::record_access): Honor
-fipa-strict-aliasing.
(modref_access_analysis::record_access_lto): Likewise.
Comments
On December 12, 2021 1:22:09 PM GMT+01:00, Jan Hubicka via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>Hi,
>ipa-modref is using TBAA to disambiguate memory accesses inter-procedurally.
>This sometimes breaks programs with TBAA violations including clang with LTO.
>To workaround that one can use -fno-strict-aliasing or -fno-ipa-modref which
>are both quite big hammers. So I added -fipa-strict-aliasing patch that
>controls only the TBAA based analysis in ipa-modref while keeping all other
>optimizations.
>
>Bootstrapped/regtested x86_64-linux, will commit it shortly.
I think at the documentation level we need to clarify that TBAA exposed by inlining is not considered IPA. The current wording is confusing in this regard. Or we need to somehow preserve a TBAA barrier at inline instances (like drop all inlined refs to alias set zero)
>gcc/ChangeLog:
>
>2021-12-12 Jan Hubicka <hubicka@ucw.cz>
>
> * common.opt: Add -fipa-strict-aliasing.
> * doc/invoke.texi: Document -fipa-strict-aliasing.
> * ipa-modref.c (modref_access_analysis::record_access): Honor
> -fipa-strict-aliasing.
> (modref_access_analysis::record_access_lto): Likewise.
>
>diff --git a/gcc/common.opt b/gcc/common.opt
>index 445a53a265c..673813f34ab 100644
>--- a/gcc/common.opt
>+++ b/gcc/common.opt
>@@ -1945,6 +1945,10 @@ fira-algorithm=
> Common Joined RejectNegative Enum(ira_algorithm) Var(flag_ira_algorithm) Init(IRA_ALGORITHM_CB) Optimization
> -fira-algorithm=[CB|priority] Set the used IRA algorithm.
>
>+fipa-strict-aliasing
>+Common Var(flag_ipa_strict_aliasing) Init(1) Optimization
>+Assume strict aliasing rules apply across function boundaries.
>+
> Enum
> Name(ira_algorithm) Type(enum ira_algorithm) UnknownError(unknown IRA algorithm %qs)
>
>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>index 9b4371b9213..afd85afe476 100644
>--- a/gcc/doc/invoke.texi
>+++ b/gcc/doc/invoke.texi
>@@ -570,7 +570,7 @@ Objective-C and Objective-C++ Dialects}.
> -fsingle-precision-constant -fsplit-ivs-in-unroller -fsplit-loops@gol
> -fsplit-paths @gol
> -fsplit-wide-types -fsplit-wide-types-early -fssa-backprop -fssa-phiopt @gol
>--fstdarg-opt -fstore-merging -fstrict-aliasing @gol
>+-fstdarg-opt -fstore-merging -fstrict-aliasing -fipa-strict-aliasing @gol
> -fthread-jumps -ftracer -ftree-bit-ccp @gol
> -ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
> -ftree-coalesce-vars -ftree-copy-prop -ftree-dce -ftree-dominator-opts @gol
>@@ -12423,6 +12423,15 @@ int f() @{
> The @option{-fstrict-aliasing} option is enabled at levels
> @option{-O2}, @option{-O3}, @option{-Os}.
>
>+@item -fipa-strict-aliasing
>+@opindex fipa-strict-aliasing
>+Constrols whether rules of @option{-fstrict-aliasing} can be applied across
>+function boundaries. This option is effective only in combination with
>+@option{-fstrict-aliasing} and does not prevent optimization across function
>+boundry in case function has been inlined.
>+
>+The @option{-fipa-strict-aliasing} option is enabled by default.
>+
> @item -falign-functions
> @itemx -falign-functions=@var{n}
> @itemx -falign-functions=@var{n}:@var{m}
>diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
>index 2c89c63baf6..d6bd9d33278 100644
>--- a/gcc/ipa-modref.c
>+++ b/gcc/ipa-modref.c
>@@ -999,9 +999,11 @@ modref_access_analysis::record_access (modref_records *tt,
> ao_ref *ref,
> modref_access_node &a)
> {
>- alias_set_type base_set = !flag_strict_aliasing ? 0
>+ alias_set_type base_set = !flag_strict_aliasing
>+ || !flag_ipa_strict_aliasing ? 0
> : ao_ref_base_alias_set (ref);
>- alias_set_type ref_set = !flag_strict_aliasing ? 0
>+ alias_set_type ref_set = !flag_strict_aliasing
>+ || !flag_ipa_strict_aliasing ? 0
> : (ao_ref_alias_set (ref));
> if (dump_file)
> {
>@@ -1021,7 +1023,7 @@ modref_access_analysis::record_access_lto (modref_records_lto *tt, ao_ref *ref,
> /* get_alias_set sometimes use different type to compute the alias set
> than TREE_TYPE (base). Do same adjustments. */
> tree base_type = NULL_TREE, ref_type = NULL_TREE;
>- if (flag_strict_aliasing)
>+ if (flag_strict_aliasing && flag_ipa_strict_aliasing)
> {
> tree base;
>
> On December 12, 2021 1:22:09 PM GMT+01:00, Jan Hubicka via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
> >Hi,
> >ipa-modref is using TBAA to disambiguate memory accesses inter-procedurally.
> >This sometimes breaks programs with TBAA violations including clang with LTO.
> >To workaround that one can use -fno-strict-aliasing or -fno-ipa-modref which
> >are both quite big hammers. So I added -fipa-strict-aliasing patch that
> >controls only the TBAA based analysis in ipa-modref while keeping all other
> >optimizations.
> >
> >Bootstrapped/regtested x86_64-linux, will commit it shortly.
>
> I think at the documentation level we need to clarify that TBAA exposed by inlining is not considered IPA. The current wording is confusing in this regard. Or we need to somehow preserve a TBAA barrier at inline instances (like drop all inlined refs to alias set zero)
It is what I meant by:
"... and does not prevent optimization across function boundary in case function has been inlined."
Perhaps I should not have packed it into single sentence
"This option does not affect strict aliasing rules when optimizing
memory locations originating from different functions that has been
inlined together"
I do not think it is practical to extend representation to handle
function boundaries, but I still find this flag useful (I have it in a
tree for a while)
Honza
Hi,
this is a variant I comitted (with updated documentation as Richard
requested).
Honza
gcc/ChangeLog:
2021-12-13 Jan Hubicka <hubicka@ucw.cz>
* common.opt: Add -fipa-strict-aliasing.
* doc/invoke.texi: Document -fipa-strict-aliasing.
* ipa-modref.c (modref_access_analysis::record_access): Honor
-fipa-strict-aliasing.
(modref_access_analysis::record_access_lto): Likewise.
diff --git a/gcc/common.opt b/gcc/common.opt
index 445a53a265c..8f8fc2f9ee7 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1945,6 +1945,10 @@ fira-algorithm=
Common Joined RejectNegative Enum(ira_algorithm) Var(flag_ira_algorithm) Init(IRA_ALGORITHM_CB) Optimization
-fira-algorithm=[CB|priority] Set the used IRA algorithm.
+fipa-strict-aliasing
+Common Var(flag_ipa_strict_aliasing) Init(1) Optimization
+Assume strict aliasing rules apply across (uninlined) function boundaries.
+
Enum
Name(ira_algorithm) Type(enum ira_algorithm) UnknownError(unknown IRA algorithm %qs)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 9b4371b9213..e9f66287098 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -570,7 +570,7 @@ Objective-C and Objective-C++ Dialects}.
-fsingle-precision-constant -fsplit-ivs-in-unroller -fsplit-loops@gol
-fsplit-paths @gol
-fsplit-wide-types -fsplit-wide-types-early -fssa-backprop -fssa-phiopt @gol
--fstdarg-opt -fstore-merging -fstrict-aliasing @gol
+-fstdarg-opt -fstore-merging -fstrict-aliasing -fipa-strict-aliasing @gol
-fthread-jumps -ftracer -ftree-bit-ccp @gol
-ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
-ftree-coalesce-vars -ftree-copy-prop -ftree-dce -ftree-dominator-opts @gol
@@ -12423,6 +12423,16 @@ int f() @{
The @option{-fstrict-aliasing} option is enabled at levels
@option{-O2}, @option{-O3}, @option{-Os}.
+@item -fipa-strict-aliasing
+@opindex fipa-strict-aliasing
+Constrols whether rules of @option{-fstrict-aliasing} are applied across
+function boundaries. Note that if multiple functions gets inlined into a
+signle function the memory accesses are no longer considred to be crossing a
+function bounday.
+
+The @option{-fipa-strict-aliasing} option is enabled by default and is
+effective only in combination with @option{-fstrict-aliasing}.
+
@item -falign-functions
@itemx -falign-functions=@var{n}
@itemx -falign-functions=@var{n}:@var{m}
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 2c89c63baf6..d6bd9d33278 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -999,9 +999,11 @@ modref_access_analysis::record_access (modref_records *tt,
ao_ref *ref,
modref_access_node &a)
{
- alias_set_type base_set = !flag_strict_aliasing ? 0
+ alias_set_type base_set = !flag_strict_aliasing
+ || !flag_ipa_strict_aliasing ? 0
: ao_ref_base_alias_set (ref);
- alias_set_type ref_set = !flag_strict_aliasing ? 0
+ alias_set_type ref_set = !flag_strict_aliasing
+ || !flag_ipa_strict_aliasing ? 0
: (ao_ref_alias_set (ref));
if (dump_file)
{
@@ -1021,7 +1023,7 @@ modref_access_analysis::record_access_lto (modref_records_lto *tt, ao_ref *ref,
/* get_alias_set sometimes use different type to compute the alias set
than TREE_TYPE (base). Do same adjustments. */
tree base_type = NULL_TREE, ref_type = NULL_TREE;
- if (flag_strict_aliasing)
+ if (flag_strict_aliasing && flag_ipa_strict_aliasing)
{
tree base;
On Mon, Dec 13, 2021 at 05:31:22PM +0100, Jan Hubicka via Gcc-patches wrote:
> +@item -fipa-strict-aliasing
> +@opindex fipa-strict-aliasing
> +Constrols whether rules of @option{-fstrict-aliasing} are applied across
s/Constrols/Controls/
> +function boundaries. Note that if multiple functions gets inlined into a
s/gets/get/
> +signle function the memory accesses are no longer considred to be crossing a
s/signle/single/
s/considred/considered/
> +function bounday.
s/bounday/boundary/
Jakub
@@ -1945,6 +1945,10 @@ fira-algorithm=
Common Joined RejectNegative Enum(ira_algorithm) Var(flag_ira_algorithm) Init(IRA_ALGORITHM_CB) Optimization
-fira-algorithm=[CB|priority] Set the used IRA algorithm.
+fipa-strict-aliasing
+Common Var(flag_ipa_strict_aliasing) Init(1) Optimization
+Assume strict aliasing rules apply across function boundaries.
+
Enum
Name(ira_algorithm) Type(enum ira_algorithm) UnknownError(unknown IRA algorithm %qs)
@@ -570,7 +570,7 @@ Objective-C and Objective-C++ Dialects}.
-fsingle-precision-constant -fsplit-ivs-in-unroller -fsplit-loops@gol
-fsplit-paths @gol
-fsplit-wide-types -fsplit-wide-types-early -fssa-backprop -fssa-phiopt @gol
--fstdarg-opt -fstore-merging -fstrict-aliasing @gol
+-fstdarg-opt -fstore-merging -fstrict-aliasing -fipa-strict-aliasing @gol
-fthread-jumps -ftracer -ftree-bit-ccp @gol
-ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
-ftree-coalesce-vars -ftree-copy-prop -ftree-dce -ftree-dominator-opts @gol
@@ -12423,6 +12423,15 @@ int f() @{
The @option{-fstrict-aliasing} option is enabled at levels
@option{-O2}, @option{-O3}, @option{-Os}.
+@item -fipa-strict-aliasing
+@opindex fipa-strict-aliasing
+Constrols whether rules of @option{-fstrict-aliasing} can be applied across
+function boundaries. This option is effective only in combination with
+@option{-fstrict-aliasing} and does not prevent optimization across function
+boundry in case function has been inlined.
+
+The @option{-fipa-strict-aliasing} option is enabled by default.
+
@item -falign-functions
@itemx -falign-functions=@var{n}
@itemx -falign-functions=@var{n}:@var{m}
@@ -999,9 +999,11 @@ modref_access_analysis::record_access (modref_records *tt,
ao_ref *ref,
modref_access_node &a)
{
- alias_set_type base_set = !flag_strict_aliasing ? 0
+ alias_set_type base_set = !flag_strict_aliasing
+ || !flag_ipa_strict_aliasing ? 0
: ao_ref_base_alias_set (ref);
- alias_set_type ref_set = !flag_strict_aliasing ? 0
+ alias_set_type ref_set = !flag_strict_aliasing
+ || !flag_ipa_strict_aliasing ? 0
: (ao_ref_alias_set (ref));
if (dump_file)
{
@@ -1021,7 +1023,7 @@ modref_access_analysis::record_access_lto (modref_records_lto *tt, ao_ref *ref,
/* get_alias_set sometimes use different type to compute the alias set
than TREE_TYPE (base). Do same adjustments. */
tree base_type = NULL_TREE, ref_type = NULL_TREE;
- if (flag_strict_aliasing)
+ if (flag_strict_aliasing && flag_ipa_strict_aliasing)
{
tree base;