Background ---------- An overview email, describing the UPC-related changes is here: https://gcc.gnu.org/ml/gcc-patches/2015-12/msg00005.html
The GUPC branch is described here: http://gcc.gnu.org/projects/gupc.html The UPC-related source code differences are summarized here: http://gccupc.org/gupc-changes All languages (c, c++, fortran, go, lto, objc, obj-c++) have been bootstrapped; no test suite regressions were introduced, relative to the GCC trunk. If you are on the cc-list, your name was chosen either because you are listed as a maintainer for the area that applies to the patches described in this email, or you were a frequent contributor of patches made to files listed in this email. In the change log entries included in each patch, the directory containing the affected files is listed, followed by the files. When the patches are applied, the change log entries will be distributed to the appropriate ChangeLog file. Overview -------- UPC pointers-to-shared (aka shared pointers) are not interchangeable with integers as they are in regular "C". Therefore, additions and subtraction operations which involve UPC shared pointers should not be further simplified. 2015-11-30 Gary Funck <g...@intrepid.com> gcc/ * fold-const.c (fold_unary_loc): Do not perform this simplification if either of the types are UPC pointer-to-shared types. (fold_binary_loc): Disable optimizations involving UPC pointers-to-shared because integers are not interoperable with UPC pointers-to-shared. * match.pd: Do not simplify POINTER_PLUS operations which involve UPC pointers-to-shared. Do not simplify integral conversions involving UPC pointers-to-shared. For a chain of two conversions, do not simplify conversions involving UPC pointers-to-shared unless they meet specific criteria. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (.../trunk) (revision 231059) +++ gcc/fold-const.c (.../branches/gupc) (revision 231080) @@ -7805,10 +7805,16 @@ fold_unary_loc (location_t loc, enum tre /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type, when the new cast (T1)X will fold away. We assume that this happens when X itself - is a cast. */ + is a cast. + + Do not perform this simplification if either of the types + are UPC pointer-to-shared types. */ if (POINTER_TYPE_P (type) && TREE_CODE (arg0) == POINTER_PLUS_EXPR - && CONVERT_EXPR_P (TREE_OPERAND (arg0, 0))) + && CONVERT_EXPR_P (TREE_OPERAND (arg0, 0)) + && !SHARED_TYPE_P (TREE_TYPE (type)) + && !SHARED_TYPE_P (TREE_TYPE ( + TREE_TYPE (TREE_OPERAND (arg0, 0))))) { tree arg00 = TREE_OPERAND (arg0, 0); tree arg01 = TREE_OPERAND (arg0, 1); @@ -9271,6 +9277,14 @@ fold_binary_loc (location_t loc, return NULL_TREE; case PLUS_EXPR: + /* Disable further optimizations involving UPC shared pointers, + because integers are not interoperable with shared pointers. */ + if ((TREE_TYPE (arg0) && POINTER_TYPE_P (TREE_TYPE (arg0)) + && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))) + || (TREE_TYPE (arg1) && POINTER_TYPE_P (TREE_TYPE (arg1)) + && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))) + return NULL_TREE; + if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) { /* X + (X / CST) * -CST is X % CST. */ @@ -9679,6 +9693,16 @@ fold_binary_loc (location_t loc, return NULL_TREE; case MINUS_EXPR: + + /* Disable further optimizations involving UPC shared pointers, + because integers are not interoperable with shared pointers. + (The test below also detects pointer difference between + shared pointers, which cannot be folded. */ + + if (TREE_TYPE (arg0) && POINTER_TYPE_P (TREE_TYPE (arg0)) + && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))) + return NULL_TREE; + /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (op1) Index: gcc/match.pd =================================================================== --- gcc/match.pd (.../trunk) (revision 231059) +++ gcc/match.pd (.../branches/gupc) (revision 231080) @@ -931,10 +931,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (!fail && wi::bit_and (@1, zero_mask_not) == 0) (inner_op @2 { wide_int_to_tree (type, cst_emit); })))))) -/* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */ -(simplify - (pointer_plus (pointer_plus:s @0 @1) @3) - (pointer_plus @0 (plus @1 @3))) +/* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). + (Do not apply this simplification to UPC pointers-to-shared + because they are not directly convertible to integers.) */ +(simplify + (pointer_plus (pointer_plus:s@2 @0 @1) @3) + (if (!SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@2)))) + (pointer_plus @0 (plus @1 @3)))) /* Pattern match tem1 = (long) ptr1; @@ -1428,19 +1431,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (view_convert @0)) /* For integral conversions with the same precision or pointer - conversions use a NOP_EXPR instead. */ + conversions use a NOP_EXPR instead. + (Do not apply this simplification to UPC pointers-to-shared + because they are not directly convertible to integers.) */ (simplify (view_convert @0) - (if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) - && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + (if ((INTEGRAL_TYPE_P (type) + || (POINTER_TYPE_P (type) + && !SHARED_TYPE_P (TREE_TYPE (type)))) + && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || (POINTER_TYPE_P (TREE_TYPE (@0)) + && !SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@0))))) && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0))) (convert @0))) -/* Strip inner integral conversions that do not change precision or size. */ +/* Strip inner integral conversions that do not change precision or size. + (Do not apply this simplification to UPC pointers-to-shared + because they are not directly convertible to integers.) */ (simplify (view_convert (convert@0 @1)) - (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) - && (INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) + (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || (POINTER_TYPE_P (TREE_TYPE (@0)) + && !SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@0))))) + && (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || (POINTER_TYPE_P (TREE_TYPE (@1)) + && !SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@1))))) && (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))) && (TYPE_SIZE (TREE_TYPE (@0)) == TYPE_SIZE (TREE_TYPE (@1)))) (view_convert @1))) @@ -1481,6 +1496,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) int final_vec = VECTOR_TYPE_P (type); unsigned int final_prec = TYPE_PRECISION (type); int final_unsignedp = TYPE_UNSIGNED (type); + int final_pts = final_ptr + && SHARED_TYPE_P (TREE_TYPE (type)); + int inter_pts = inter_ptr + && SHARED_TYPE_P (TREE_TYPE (inter_type)); + int inside_pts = inside_ptr + && SHARED_TYPE_P (TREE_TYPE (inside_type)); } (switch /* In addition to the cases of two conversions in a row @@ -1529,7 +1550,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) - the initial type is a pointer type and the precisions of the intermediate and final types differ, or - the final type is a pointer type and the precisions of the - initial and intermediate types differ. */ + initial and intermediate types differ, or + - the final type, intermediate type, and initial type are not either + all regular C pointer types or all UPC pointer-to-shared types, or + - the final type is a UPC pointer-to-shared and the intermediate type + is a UPC-pointer-to-shared and their target types differ, or + - the final type is a UPC pointer-to-shared and the intermediate type + is a UPC-pointer-to-shared and their target types differ. */ (if (! inside_float && ! inter_float && ! final_float && ! inside_vec && ! inter_vec && ! final_vec && (inter_prec >= inside_prec || inter_prec >= final_prec) @@ -1541,7 +1568,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && ! (inside_ptr && inter_prec != final_prec) && ! (final_ptr && inside_prec != inter_prec) && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type))) + && TYPE_MODE (type) == TYPE_MODE (inter_type)) + && (final_pts == inter_pts) && (inter_pts == inside_pts) + && ! (inter_pts + && (TREE_TYPE (inter_type) != TREE_TYPE (inside_type))) + && ! (final_pts && (TREE_TYPE (type) != TREE_TYPE (inter_type)))) (ocvt @0)) /* A truncation to an unsigned type (a zero-extension) should be