From: Eric Botcazou Date: Tue, 20 Nov 2018 09:04:12 +0000 (+0000) Subject: re PR rtl-optimization/85925 (compilation of masking with 257 goes wrong in combine... X-Git-Tag: releases/gcc-7.4.0~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d0d194c74f341a81e1b120c8eb659c65e7cc770;p=thirdparty%2Fgcc.git re PR rtl-optimization/85925 (compilation of masking with 257 goes wrong in combine at -02) 2018-11-20 Eric Botcazou PR rtl-optimization/85925 * rtl.h (word_register_operation_p): New predicate. * combine.c (record_dead_and_set_regs_1): Only apply specific handling for WORD_REGISTER_OPERATIONS targets to word_register_operation_p RTX. * rtlanal.c (nonzero_bits1): Likewise. Adjust couple of comments. (num_sign_bit_copies1): Likewise. From-SVN: r266304 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d07ddf9d440..091748a6bad6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-11-20 Eric Botcazou + + PR rtl-optimization/85925 + * rtl.h (word_register_operation_p): New predicate. + * combine.c (record_dead_and_set_regs_1): Only apply specific handling + for WORD_REGISTER_OPERATIONS targets to word_register_operation_p RTX. + * rtlanal.c (nonzero_bits1): Likewise. Adjust couple of comments. + (num_sign_bit_copies1): Likewise. + 2018-11-18 Uros Bizjak Backport from mainline diff --git a/gcc/combine.c b/gcc/combine.c index 8da96d23cc8d..bc023d2f994a 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13117,6 +13117,7 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data) && subreg_lowpart_p (SET_DEST (setter))) record_value_for_reg (dest, record_dead_insn, WORD_REGISTER_OPERATIONS + && word_register_operation_p (SET_SRC (setter)) && paradoxical_subreg_p (SET_DEST (setter)) ? SET_SRC (setter) : gen_lowpart (GET_MODE (dest), diff --git a/gcc/rtl.h b/gcc/rtl.h index 93330425c00f..05372cf8c95b 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3832,6 +3832,25 @@ load_extend_op (machine_mode mode) return UNKNOWN; } +/* Return true if X is an operation that always operates on the full + registers for WORD_REGISTER_OPERATIONS architectures. */ + +inline bool +word_register_operation_p (const_rtx x) +{ + switch (GET_CODE (x)) + { + case ROTATE: + case ROTATERT: + case SIGN_EXTRACT: + case ZERO_EXTRACT: + return false; + + default: + return true; + } +} + /* gtype-desc.c. */ extern void gt_ggc_mx (rtx &); extern void gt_pch_nx (rtx &); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 772a6a993bb0..5df0e5d6fdd0 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4339,14 +4339,14 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, might be nonzero in its own mode, taking into account the fact that, on CISC machines, accessing an object in a wider mode generally causes the high-order bits to become undefined, so they are not known to be zero. - We extend this reasoning to RISC machines for rotate operations since the - semantics of the operations in the larger mode is not well defined. */ + We extend this reasoning to RISC machines for operations that might not + operate on the full registers. */ if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode && GET_MODE_PRECISION (GET_MODE (x)) <= BITS_PER_WORD && GET_MODE_PRECISION (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT && GET_MODE_PRECISION (mode) > GET_MODE_PRECISION (GET_MODE (x)) - && (!WORD_REGISTER_OPERATIONS || code == ROTATE)) + && !(WORD_REGISTER_OPERATIONS && word_register_operation_p (x))) { nonzero &= cached_nonzero_bits (x, GET_MODE (x), known_x, known_mode, known_ret); @@ -4623,13 +4623,16 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode, known_x, known_mode, known_ret); - /* On many CISC machines, accessing an object in a wider mode + /* On a typical CISC machine, accessing an object in a wider mode causes the high-order bits to become undefined. So they are - not known to be zero. */ + not known to be zero. + + On a typical RISC machine, we only have to worry about the way + loads are extended. Otherwise, if we get a reload for the inner + part, it may be loaded from the stack, and then we may lose all + the zero bits that existed before the store to the stack. */ rtx_code extend_op; if ((!WORD_REGISTER_OPERATIONS - /* If this is a typical RISC machine, we only have to worry - about the way loads are extended. */ || ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND ? val_signbit_known_set_p (inner_mode, nonzero) : extend_op != ZERO_EXTEND) @@ -4872,10 +4875,9 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, { /* If this machine does not do all register operations on the entire register and MODE is wider than the mode of X, we can say nothing - at all about the high-order bits. We extend this reasoning to every - machine for rotate operations since the semantics of the operations - in the larger mode is not well defined. */ - if (!WORD_REGISTER_OPERATIONS || code == ROTATE || code == ROTATERT) + at all about the high-order bits. We extend this reasoning to RISC + machines for operations that might not operate on full registers. */ + if (!(WORD_REGISTER_OPERATIONS && word_register_operation_p (x))) return 1; /* Likewise on machines that do, if the mode of the object is smaller @@ -4965,10 +4967,10 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, /* For paradoxical SUBREGs on machines where all register operations affect the entire register, just look inside. Note that we are - passing MODE to the recursive call, so the number of sign bit copies - will remain relative to that mode, not the inner mode. */ + passing MODE to the recursive call, so the number of sign bit + copies will remain relative to that mode, not the inner mode. - /* This works only if loads sign extend. Otherwise, if we get a + This works only if loads sign extend. Otherwise, if we get a reload for the inner part, it may be loaded from the stack, and then we lose all sign bit copies that existed before the store to the stack. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37ef7160cc19..c8dabcce523b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-11-20 Eric Botcazou + + * gcc.c-torture/execute/20181120-1.c: New test. + 2018-11-18 Uros Bizjak Backport from mainline diff --git a/gcc/testsuite/gcc.c-torture/execute/20181120-1.c b/gcc/testsuite/gcc.c-torture/execute/20181120-1.c new file mode 100644 index 000000000000..21e5f7a71fe3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20181120-1.c @@ -0,0 +1,26 @@ +/* PR rtl-optimization/85925 */ +/* Testcase by */ + +int a, c, d; +volatile int b; +int *e = &d; + +union U1 { + unsigned f0; + unsigned f1 : 15; +}; + +int main (void) +{ + for (c = 0; c <= 1; c++) { + union U1 f = {0x10101}; + if (c == 1) + b; + *e = f.f1; + } + + if (d != 0x101) + __builtin_abort (); + + return 0; +}