diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/expr.c | 10 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 13 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr66178.c | 17 |
7 files changed, 56 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab7dc3a..124708b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-01-21 Bernd Schmidt <bschmidt@redhat.com> + + PR middle-end/66178 + * expr.c (expand_expr_real_2) [PLUS_EXPR, MINUS_EXPR]: Don't + drop EXPAND_INITIALIZER. + * rtl.h (contains_symbolic_reference_p): Declare. + * rtlanal.c (contains_symbolic_reference_p): New function. + * simplify-rtx.c (simplify_binary_operation_1): Don't turn + a subtraction into a NOT if symbolic constants are involved. + 2016-01-21 Anton Blanchard <anton@samba.org> Bill Schmidt <wschmidt@linux.vnet.ibm.com> @@ -8381,11 +8381,11 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, if it's all in the wrong mode to form part of an address. And force_operand won't know whether to sign-extend or zero-extend. */ - if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) - || mode != ptr_mode) + if (modifier != EXPAND_INITIALIZER + && (modifier != EXPAND_SUM || mode != ptr_mode)) { expand_operands (treeop0, treeop1, - subtarget, &op0, &op1, EXPAND_NORMAL); + subtarget, &op0, &op1, modifier); if (op0 == const0_rtx) return op1; if (op1 == const0_rtx) @@ -8424,8 +8424,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, if it's all in the wrong mode to form part of an address. And force_operand won't know whether to sign-extend or zero-extend. */ - if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) - || mode != ptr_mode) + if (modifier != EXPAND_INITIALIZER + && (modifier != EXPAND_SUM || mode != ptr_mode)) goto binop; expand_operands (treeop0, treeop1, @@ -2931,6 +2931,7 @@ extern void set_insn_deleted (rtx); extern rtx single_set_2 (const rtx_insn *, const_rtx); extern bool contains_symbol_ref_p (const_rtx); +extern bool contains_symbolic_reference_p (const_rtx); /* Handle the cheap and common cases inline for performance. */ diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 0e0d097..71dfd33 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -6243,6 +6243,19 @@ contains_symbol_ref_p (const_rtx x) return false; } +/* Return true if RTL X contains a SYMBOL_REF or LABEL_REF. */ + +bool +contains_symbolic_reference_p (const_rtx x) +{ + subrtx_iterator::array_type array; + FOR_EACH_SUBRTX (iter, array, x, ALL) + if (SYMBOL_REF_P (*iter) || GET_CODE (*iter) == LABEL_REF) + return true; + + return false; +} + /* Return true if X contains a thread-local symbol. */ bool diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 1e6e46d..39049e5 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2277,8 +2277,11 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode)) return simplify_gen_unary (NEG, mode, op1, mode); - /* (-1 - a) is ~a. */ - if (trueop0 == constm1_rtx) + /* (-1 - a) is ~a, unless the expression avoids symbolic constants, + in which case not retaining additions and subtractions could + cause invalid assembly to be produced. */ + if (trueop0 == constm1_rtx + && !contains_symbolic_reference_p (op1)) return simplify_gen_unary (NOT, mode, op1, mode); /* Subtracting 0 has no effect unless the mode has signed zeros diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 35fb4fc..4ec1b30 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-21 Bernd Schmidt <bschmidt@redhat.com> + + PR middle-end/66178 + * gcc.dg/torture/pr66178.c: New test. + 2016-01-21 Anton Blanchard <anton@samba.org> Bill Schmidt <wschmidt@linux.vnet.ibm.com> diff --git a/gcc/testsuite/gcc.dg/torture/pr66178.c b/gcc/testsuite/gcc.dg/torture/pr66178.c new file mode 100644 index 0000000..ebc626c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr66178.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +int test(void) +{ + static int a = ((char *)&&l1-(char *)&&l2)-1; +l1: +l2: + return a; +} + +int test2(void) +{ + static int a = ((char *)&&l2-(char *)&&l3)+((char *)&&l1-(char *)&&l2); +l1: +l2: +l3: + return a; +} |