public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] middle-end: Fix bogus folding of REPLACE_ADDRESS_VALUE
@ 2022-06-01 13:16 Alex Coplan
0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2022-06-01 13:16 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e0ffb332e6fccabe8acb1806511262ae43da2ca3
commit e0ffb332e6fccabe8acb1806511262ae43da2ca3
Author: Alex Coplan <alex.coplan@arm.com>
Date: Thu May 26 10:59:24 2022 +0100
middle-end: Fix bogus folding of REPLACE_ADDRESS_VALUE
fold_build_replace_address_value_loc did the following transformation:
RAV (RAV (c, cv1), cv2) -> cv2
which is incorrect in the case where cv1 has side effects. It also
(incorrectly) attempted to handle a similar case where the inner RAV was
inside a NOP_EXPR.
In the general case, both of these folds really seem to be optimizations
that should be handled by the gimple optimizers rather than
transformations that are necessary for constant folding in the FE.
The folds we do in fold_build_replace_address_value_loc should really be
the minimum necessary for constant folding in the FE. Any further
optimization can be done on GIMPLE using match.pd rules.
We adjust the nested RAV fold in fold_build_replace_address_value_loc to
only handle the case where the inner RAV and the new capability value
are both TREE_CONSTANT.
This should be sufficient for FE constant folding (e.g. for the new test
added with the patch), but without implementing any further
optimization. This should also ensure we fix the issue where cv1 has
side effects, since in this case the inner RAV would not be marked
TREE_CONSTANT.
This revealed that we weren't marking IFN CALL_EXPR nodes as
TREE_CONSTANT even if both operands were TREE_CONSTANT, so we fix this
by adjusting tree.c:process_call_operands. Here we mark IFN calls as
TREE_CONSTANT if they are flagged ICF_CONST and ICF_NOTHROW, and all of
their operands are also TREE_CONSTANT. This further revealed that we
hadn't given REPLACE_ADDRESS_VALUE IFNs the ECF_NOTHROW flag, so we add
this flag in internal-fn.def.
We add a match.pd rule to pick up the general optimization of nested
REPLACE_ADDRESS_VALUE calls at the GIMPLE level. This prevents
regressing now that we have restricted the generic folding to do the
bare minimum for constant folding.
We remove an overzealous assert from
varasm.c:initializer_constant_valid_p_1. Here we attempted to enforce
the invariant that we never see nested REPLACE_ADDRESS_VALUE calls, but
it simply isn't possible to maintain this invariant in the general case,
since these can't always be folded, so we simply reject these instead.
gcc/ChangeLog:
* fold-const.c (fold_build_replace_address_value_loc): Only do
bare minimum needed for constant folding, thereby avoiding a
correctness problem where we lose side effects.
* internal-fn.def (REPLACE_ADDRESS_VALUE): Add ECF_NOTHROW.
* match.pd (RAV (RAV (c, cv1), cv2) -> RAV(c, cv2)): New.
* tree.c (process_call_operands): Propagate TREE_CONSTANT for
IFNs marked ECF_CONST and ECF_NOTHROW.
* varasm.c (initializer_constant_valid_p_1): Don't assert on
nested REPLACE_ADDRESS_VALUE.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/morello/intcap-global-const.c: New test.
Diff:
---
gcc/fold-const.c | 16 +++-------------
gcc/internal-fn.def | 2 +-
gcc/match.pd | 6 ++++++
.../gcc.target/aarch64/morello/intcap-global-const.c | 3 +++
gcc/tree.c | 11 +++++++++++
gcc/varasm.c | 3 ---
6 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 07c54a87bba..384d3c149eb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -13603,25 +13603,15 @@ fold_build_replace_address_value_loc (location_t loc, tree c, tree cv)
!POINTER_TYPE_P (cap_type),
TREE_OVERFLOW (cv));
}
+
if (TREE_CODE (c) == CALL_EXPR && CALL_EXPR_FN (c) == NULL_TREE
- && CALL_EXPR_IFN (c) == IFN_REPLACE_ADDRESS_VALUE)
+ && CALL_EXPR_IFN (c) == IFN_REPLACE_ADDRESS_VALUE
+ && TREE_CONSTANT (c) && TREE_CONSTANT (cv))
{
gcc_assert (TREE_TYPE (c) == TREE_TYPE (CALL_EXPR_ARG (c, 0)));
return fold_build_replace_address_value_loc (loc,
CALL_EXPR_ARG (c, 0), orig_cv);
}
- /* If the capability C is an INTEGER_CST or a REPLACE_ADDRESS_VALUE inside
- a NOP conversion, allow this function to recurse and re-apply the
- conversion on the result. */
- if (TREE_CODE (c) == NOP_EXPR
- && ((TREE_CODE (TREE_OPERAND (c, 0)) == CALL_EXPR
- && CALL_EXPR_IFN (TREE_OPERAND (c, 0)) == IFN_REPLACE_ADDRESS_VALUE
- && CALL_EXPR_FN (TREE_OPERAND (c, 0)) == NULL_TREE)
- || TREE_CODE (TREE_OPERAND (c, 0)) == INTEGER_CST)
- && types_compatible_p (noncapability_type (TREE_TYPE (TREE_OPERAND (c, 0))),
- TREE_TYPE (cv)))
- return convert (TREE_TYPE (c), fold_build_replace_address_value_loc (loc,
- TREE_OPERAND (c, 0), orig_cv));
return build_replace_address_value_loc (loc, orig_c, orig_cv);
}
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index f27c0a16750..a7a280894fb 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -394,7 +394,7 @@ DEF_INTERNAL_FN (CO_FRAME, ECF_PURE | ECF_NOTHROW | ECF_LEAF, NULL)
actually have to be properly passed to the function (which is *not* valid)
-- but it would be worth checking if it only means that the argument is not
dereferenced. */
-DEF_INTERNAL_FN (REPLACE_ADDRESS_VALUE, ECF_CONST | ECF_LEAF, ".RR")
+DEF_INTERNAL_FN (REPLACE_ADDRESS_VALUE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, ".RR")
DEF_INTERNAL_FN (CAP_GLOBAL_DATA_GET, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
diff --git a/gcc/match.pd b/gcc/match.pd
index 34eb9d2a92e..d959763ef8c 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6582,4 +6582,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@1)))
(convert @1)))
+/* RAV (RAV (c, cv1), cv2) -> RAV (c, cv2). */
+(simplify
+ (IFN_REPLACE_ADDRESS_VALUE
+ (IFN_REPLACE_ADDRESS_VALUE @0 @1) @2)
+ (IFN_REPLACE_ADDRESS_VALUE @0 @2))
+
#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/intcap-global-const.c b/gcc/testsuite/gcc.target/aarch64/morello/intcap-global-const.c
new file mode 100644
index 00000000000..ce1d17d67ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/intcap-global-const.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+int x;
+__intcap c = (__intcap)&x + 1 + 1;
diff --git a/gcc/tree.c b/gcc/tree.c
index dcd85eedb41..75b177cbb99 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3806,6 +3806,7 @@ process_call_operands (tree t)
{
bool side_effects = TREE_SIDE_EFFECTS (t);
bool read_only = false;
+ bool constant = false;
int i = call_expr_flags (t);
/* Calls have side-effects, except those to const or pure functions. */
@@ -3815,6 +3816,10 @@ process_call_operands (tree t)
if (i & ECF_CONST)
read_only = true;
+ /* Only internal function calls can be TREE_CONSTANT. */
+ if (!CALL_EXPR_FN (t) && (i & ECF_CONST) && (i & ECF_NOTHROW))
+ constant = true;
+
if (!side_effects || read_only)
for (i = 1; i < TREE_OPERAND_LENGTH (t); i++)
{
@@ -3823,10 +3828,16 @@ process_call_operands (tree t)
side_effects = true;
if (op && !TREE_READONLY (op) && !CONSTANT_CLASS_P (op))
read_only = false;
+ if (op && !TREE_CONSTANT (op))
+ constant = false;
}
+ /* constant => !side_effects. */
+ gcc_assert (!constant || !side_effects);
+
TREE_SIDE_EFFECTS (t) = side_effects;
TREE_READONLY (t) = read_only;
+ TREE_CONSTANT (t) = constant;
}
\f
/* Return true if EXP contains a PLACEHOLDER_EXPR, i.e. if it represents a
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a35048676d2..2e76f0f725b 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -4665,9 +4665,6 @@ initializer_constant_valid_p_1 (tree value, tree endtype, tree *cache)
break;
tree ptr = CALL_EXPR_ARG (value, 0);
tree addr_value = CALL_EXPR_ARG (value, 1);
- /* Assume VALUE has been folded as much as possible. */
- gcc_assert (TREE_CODE (ptr) != CALL_EXPR
- || CALL_EXPR_IFN (ptr) != IFN_REPLACE_ADDRESS_VALUE);
if (TREE_CODE (ptr) == CALL_EXPR)
break;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-01 13:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-01 13:16 [gcc(refs/vendors/ARM/heads/morello)] middle-end: Fix bogus folding of REPLACE_ADDRESS_VALUE Alex Coplan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).