Re: [PATCH 1/1 v2] PR100281 C++: Fix SImode pointer handling
On 5/17/21 4:48 AM, Richard Biener wrote: On Thu, May 13, 2021 at 8:28 AM Andreas Krebbel via Gcc-patches wrote: v1 -> v2: build_reference_type_for_mode and build_pointer_type_for_mode now pick pointer mode if MODE argument is VOIDmode. Bootstrapped and regression tested on x86_64 and s390x. Ok for mainline and GCC 11? The middle-end parts are fine with me. The C++ parts are OK as well. Richard. Andreas gcc/cp/ChangeLog: PR c++/100281 * cvt.c (cp_convert_to_pointer): Use the size of the target pointer type. * tree.c (cp_build_reference_type): Call cp_build_reference_type_for_mode with VOIDmode. (cp_build_reference_type_for_mode): Rename from cp_build_reference_type. Add MODE argument and invoke build_reference_type_for_mode. (strip_typedefs): Use build_pointer_type_for_mode and cp_build_reference_type_for_mode for pointers and references. gcc/ChangeLog: PR c++/100281 * tree.c (build_reference_type_for_mode) (build_pointer_type_for_mode): Pick pointer mode if MODE argument is VOIDmode. (build_reference_type, build_pointer_type): Invoke build_*_type_for_mode with VOIDmode. gcc/testsuite/ChangeLog: PR c++/100281 * g++.target/s390/pr100281-1.C: New test. * g++.target/s390/pr100281-2.C: New test. --- gcc/cp/cvt.c | 2 +- gcc/cp/tree.c | 25 ++- gcc/testsuite/g++.target/s390/pr100281-1.C | 10 gcc/testsuite/g++.target/s390/pr100281-2.C | 9 +++ gcc/tree.c | 29 ++ 5 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/g++.target/s390/pr100281-1.C create mode 100644 gcc/testsuite/g++.target/s390/pr100281-2.C diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index f1687e804d1..7fa6e8df52b 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold, { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); - expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr, + expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), expr, complain); /* Modes may be different but sizes should be the same. There is supposed to be some integral type that is the same width diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7f148b4b158..35faeff065a 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1206,12 +1206,14 @@ vla_type_p (tree t) return false; } -/* Return a reference type node referring to TO_TYPE. If RVAL is + +/* Return a reference type node of MODE referring to TO_TYPE. If MODE + is VOIDmode the standard pointer mode will be picked. If RVAL is true, return an rvalue reference type, otherwise return an lvalue reference type. If a type node exists, reuse it, otherwise create a new one. */ tree -cp_build_reference_type (tree to_type, bool rval) +cp_build_reference_type_for_mode (tree to_type, machine_mode mode, bool rval) { tree lvalue_ref, t; @@ -1224,7 +1226,8 @@ cp_build_reference_type (tree to_type, bool rval) to_type = TREE_TYPE (to_type); } - lvalue_ref = build_reference_type (to_type); + lvalue_ref = build_reference_type_for_mode (to_type, mode, false); + if (!rval) return lvalue_ref; @@ -1250,7 +1253,7 @@ cp_build_reference_type (tree to_type, bool rval) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (to_type) != to_type) TYPE_CANONICAL (t) - = cp_build_reference_type (TYPE_CANONICAL (to_type), rval); + = cp_build_reference_type_for_mode (TYPE_CANONICAL (to_type), mode, rval); else TYPE_CANONICAL (t) = t; @@ -1260,6 +1263,16 @@ cp_build_reference_type (tree to_type, bool rval) } +/* Return a reference type node referring to TO_TYPE. If RVAL is + true, return an rvalue reference type, otherwise return an lvalue + reference type. If a type node exists, reuse it, otherwise create + a new one. */ +tree +cp_build_reference_type (tree to_type, bool rval) +{ + return cp_build_reference_type_for_mode (to_type, VOIDmode, rval); +} + /* Returns EXPR cast to rvalue reference type, like std::move. */ tree @@ -1561,11 +1574,11 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) { case POINTER_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); - result = build_pointer_type (type); + result = build_pointer_type_for_mode (type, TYPE_MODE (t), false); break; case REFERENCE_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); - result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t)); + result =
Re: [PATCH 1/1 v2] PR100281 C++: Fix SImode pointer handling
On Thu, May 13, 2021 at 8:28 AM Andreas Krebbel via Gcc-patches wrote: > > v1 -> v2: build_reference_type_for_mode and build_pointer_type_for_mode now > pick pointer mode if > MODE argument is VOIDmode. > > Bootstrapped and regression tested on x86_64 and s390x. > > Ok for mainline and GCC 11? The middle-end parts are fine with me. Richard. > Andreas > > > gcc/cp/ChangeLog: > > PR c++/100281 > * cvt.c (cp_convert_to_pointer): Use the size of the target > pointer type. > * tree.c (cp_build_reference_type): Call > cp_build_reference_type_for_mode with VOIDmode. > (cp_build_reference_type_for_mode): Rename from > cp_build_reference_type. Add MODE argument and invoke > build_reference_type_for_mode. > (strip_typedefs): Use build_pointer_type_for_mode and > cp_build_reference_type_for_mode for pointers and references. > > gcc/ChangeLog: > > PR c++/100281 > * tree.c (build_reference_type_for_mode) > (build_pointer_type_for_mode): Pick pointer mode if MODE argument > is VOIDmode. > (build_reference_type, build_pointer_type): Invoke > build_*_type_for_mode with VOIDmode. > > gcc/testsuite/ChangeLog: > > PR c++/100281 > * g++.target/s390/pr100281-1.C: New test. > * g++.target/s390/pr100281-2.C: New test. > --- > gcc/cp/cvt.c | 2 +- > gcc/cp/tree.c | 25 ++- > gcc/testsuite/g++.target/s390/pr100281-1.C | 10 > gcc/testsuite/g++.target/s390/pr100281-2.C | 9 +++ > gcc/tree.c | 29 ++ > 5 files changed, 57 insertions(+), 18 deletions(-) > create mode 100644 gcc/testsuite/g++.target/s390/pr100281-1.C > create mode 100644 gcc/testsuite/g++.target/s390/pr100281-2.C > > diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c > index f1687e804d1..7fa6e8df52b 100644 > --- a/gcc/cp/cvt.c > +++ b/gcc/cp/cvt.c > @@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold, > { >if (TYPE_PRECISION (intype) == POINTER_SIZE) > return build1 (CONVERT_EXPR, type, expr); > - expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr, > + expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), > expr, > complain); >/* Modes may be different but sizes should be the same. There > is supposed to be some integral type that is the same width > diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c > index 7f148b4b158..35faeff065a 100644 > --- a/gcc/cp/tree.c > +++ b/gcc/cp/tree.c > @@ -1206,12 +1206,14 @@ vla_type_p (tree t) >return false; > } > > -/* Return a reference type node referring to TO_TYPE. If RVAL is > + > +/* Return a reference type node of MODE referring to TO_TYPE. If MODE > + is VOIDmode the standard pointer mode will be picked. If RVAL is > true, return an rvalue reference type, otherwise return an lvalue > reference type. If a type node exists, reuse it, otherwise create > a new one. */ > tree > -cp_build_reference_type (tree to_type, bool rval) > +cp_build_reference_type_for_mode (tree to_type, machine_mode mode, bool rval) > { >tree lvalue_ref, t; > > @@ -1224,7 +1226,8 @@ cp_build_reference_type (tree to_type, bool rval) >to_type = TREE_TYPE (to_type); > } > > - lvalue_ref = build_reference_type (to_type); > + lvalue_ref = build_reference_type_for_mode (to_type, mode, false); > + >if (!rval) > return lvalue_ref; > > @@ -1250,7 +1253,7 @@ cp_build_reference_type (tree to_type, bool rval) > SET_TYPE_STRUCTURAL_EQUALITY (t); >else if (TYPE_CANONICAL (to_type) != to_type) > TYPE_CANONICAL (t) > - = cp_build_reference_type (TYPE_CANONICAL (to_type), rval); > + = cp_build_reference_type_for_mode (TYPE_CANONICAL (to_type), mode, > rval); >else > TYPE_CANONICAL (t) = t; > > @@ -1260,6 +1263,16 @@ cp_build_reference_type (tree to_type, bool rval) > > } > > +/* Return a reference type node referring to TO_TYPE. If RVAL is > + true, return an rvalue reference type, otherwise return an lvalue > + reference type. If a type node exists, reuse it, otherwise create > + a new one. */ > +tree > +cp_build_reference_type (tree to_type, bool rval) > +{ > + return cp_build_reference_type_for_mode (to_type, VOIDmode, rval); > +} > + > /* Returns EXPR cast to rvalue reference type, like std::move. */ > > tree > @@ -1561,11 +1574,11 @@ strip_typedefs (tree t, bool *remove_attributes, > unsigned int flags) > { > case POINTER_TYPE: >type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); > - result = build_pointer_type (type); > + result = build_pointer_type_for_mode (type, TYPE_MODE (t), false); >break; > case REFERENCE_TYPE: >type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); > -
Re: [PATCH 1/1 v2] PR100281 C++: Fix SImode pointer handling
v1 -> v2: build_reference_type_for_mode and build_pointer_type_for_mode now pick pointer mode if MODE argument is VOIDmode. Bootstrapped and regression tested on x86_64 and s390x. Ok for mainline and GCC 11? Andreas gcc/cp/ChangeLog: PR c++/100281 * cvt.c (cp_convert_to_pointer): Use the size of the target pointer type. * tree.c (cp_build_reference_type): Call cp_build_reference_type_for_mode with VOIDmode. (cp_build_reference_type_for_mode): Rename from cp_build_reference_type. Add MODE argument and invoke build_reference_type_for_mode. (strip_typedefs): Use build_pointer_type_for_mode and cp_build_reference_type_for_mode for pointers and references. gcc/ChangeLog: PR c++/100281 * tree.c (build_reference_type_for_mode) (build_pointer_type_for_mode): Pick pointer mode if MODE argument is VOIDmode. (build_reference_type, build_pointer_type): Invoke build_*_type_for_mode with VOIDmode. gcc/testsuite/ChangeLog: PR c++/100281 * g++.target/s390/pr100281-1.C: New test. * g++.target/s390/pr100281-2.C: New test. --- gcc/cp/cvt.c | 2 +- gcc/cp/tree.c | 25 ++- gcc/testsuite/g++.target/s390/pr100281-1.C | 10 gcc/testsuite/g++.target/s390/pr100281-2.C | 9 +++ gcc/tree.c | 29 ++ 5 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/g++.target/s390/pr100281-1.C create mode 100644 gcc/testsuite/g++.target/s390/pr100281-2.C diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index f1687e804d1..7fa6e8df52b 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold, { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); - expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr, + expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), expr, complain); /* Modes may be different but sizes should be the same. There is supposed to be some integral type that is the same width diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7f148b4b158..35faeff065a 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1206,12 +1206,14 @@ vla_type_p (tree t) return false; } -/* Return a reference type node referring to TO_TYPE. If RVAL is + +/* Return a reference type node of MODE referring to TO_TYPE. If MODE + is VOIDmode the standard pointer mode will be picked. If RVAL is true, return an rvalue reference type, otherwise return an lvalue reference type. If a type node exists, reuse it, otherwise create a new one. */ tree -cp_build_reference_type (tree to_type, bool rval) +cp_build_reference_type_for_mode (tree to_type, machine_mode mode, bool rval) { tree lvalue_ref, t; @@ -1224,7 +1226,8 @@ cp_build_reference_type (tree to_type, bool rval) to_type = TREE_TYPE (to_type); } - lvalue_ref = build_reference_type (to_type); + lvalue_ref = build_reference_type_for_mode (to_type, mode, false); + if (!rval) return lvalue_ref; @@ -1250,7 +1253,7 @@ cp_build_reference_type (tree to_type, bool rval) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (to_type) != to_type) TYPE_CANONICAL (t) - = cp_build_reference_type (TYPE_CANONICAL (to_type), rval); + = cp_build_reference_type_for_mode (TYPE_CANONICAL (to_type), mode, rval); else TYPE_CANONICAL (t) = t; @@ -1260,6 +1263,16 @@ cp_build_reference_type (tree to_type, bool rval) } +/* Return a reference type node referring to TO_TYPE. If RVAL is + true, return an rvalue reference type, otherwise return an lvalue + reference type. If a type node exists, reuse it, otherwise create + a new one. */ +tree +cp_build_reference_type (tree to_type, bool rval) +{ + return cp_build_reference_type_for_mode (to_type, VOIDmode, rval); +} + /* Returns EXPR cast to rvalue reference type, like std::move. */ tree @@ -1561,11 +1574,11 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) { case POINTER_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); - result = build_pointer_type (type); + result = build_pointer_type_for_mode (type, TYPE_MODE (t), false); break; case REFERENCE_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); - result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t)); + result = cp_build_reference_type_for_mode (type, TYPE_MODE (t), TYPE_REF_IS_RVALUE (t)); break; case OFFSET_TYPE: t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t), remove_attributes, flags); diff --git a/gcc/testsuite/g++.target/s390/pr100281-1.C