From: Eric Botcazou Date: Wed, 31 Jan 2018 10:03:06 +0000 (+0000) Subject: re PR rtl-optimization/84071 (wrong elimination of zero-extension after sign-extended... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ae20d760b1ed69f631c3bf9351bf7e5005d52297;p=gcc.git re PR rtl-optimization/84071 (wrong elimination of zero-extension after sign-extended load) PR rtl-optimization/84071 * combine.c (record_dead_and_set_regs_1): Record the source unmodified for a paradoxical SUBREG on a WORD_REGISTER_OPERATIONS target. From-SVN: r257224 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index db2c33536ce..5c1977907f1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-01-31 Eric Botcazou + + PR rtl-optimization/84071 + * combine.c (record_dead_and_set_regs_1): Record the source unmodified + for a paradoxical SUBREG on a WORD_REGISTER_OPERATIONS target. + 2018-01-31 Claudiu Zissulescu * config/arc/arc.c (arc_handle_aux_attribute): New function. diff --git a/gcc/combine.c b/gcc/combine.c index 6adc0a7d6f8..b14b248800e 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13245,18 +13245,25 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data) if (REG_P (dest)) { /* If we are setting the whole register, we know its value. Otherwise - show that we don't know the value. We can handle SUBREG in - some cases. */ + show that we don't know the value. We can handle a SUBREG if it's + the low part, but we must be careful with paradoxical SUBREGs on + RISC architectures because we cannot strip e.g. an extension around + a load and record the naked load since the RTL middle-end considers + that the upper bits are defined according to LOAD_EXTEND_OP. */ if (GET_CODE (setter) == SET && dest == SET_DEST (setter)) record_value_for_reg (dest, record_dead_insn, SET_SRC (setter)); else if (GET_CODE (setter) == SET && GET_CODE (SET_DEST (setter)) == SUBREG && SUBREG_REG (SET_DEST (setter)) == dest - && known_le (GET_MODE_PRECISION (GET_MODE (dest)), BITS_PER_WORD) + && known_le (GET_MODE_PRECISION (GET_MODE (dest)), + BITS_PER_WORD) && subreg_lowpart_p (SET_DEST (setter))) record_value_for_reg (dest, record_dead_insn, - gen_lowpart (GET_MODE (dest), - SET_SRC (setter))); + WORD_REGISTER_OPERATIONS + && paradoxical_subreg_p (SET_DEST (setter)) + ? SET_SRC (setter) + : gen_lowpart (GET_MODE (dest), + SET_SRC (setter))); else record_value_for_reg (dest, record_dead_insn, NULL_RTX); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6bca328096..13d8e643c57 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-01-31 Eric Botcazou + + * gcc.c-torture/execute/20180131-1.c: New test. + 2018-01-31 Claudiu Zissulescu * gcc.target/arc/taux-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/20180131-1.c b/gcc/testsuite/gcc.c-torture/execute/20180131-1.c new file mode 100644 index 00000000000..76e264bf967 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20180131-1.c @@ -0,0 +1,28 @@ +/* PR rtl-optimization/84071 */ +/* Reported by Wilco */ + +extern void abort (void); + +typedef union +{ + signed short ss; + unsigned short us; + int x; +} U; + +int f(int x, int y, int z, int a, U u) __attribute__((noclone, noinline)); + +int f(int x, int y, int z, int a, U u) +{ + return (u.ss <= 0) + u.us; +} + +int main (void) +{ + U u = { .ss = -1 }; + + if (f (0, 0, 0, 0, u) != (1 << sizeof (short) * 8)) + abort (); + + return 0; +}