slyfox 18/01/13 11:29:11 Modified: README.history Added: 97_all_shift-codegen-PR83565.patch Log: gcc-7: fix openssl miscompilation at least on ia64 (RTL mishandles shifts and rotates) Backport from gcc-7 branch. Bug: https://gcc.gnu.org/PR83565
Revision Changes Path 1.4 src/patchsets/gcc/7.2.0/gentoo/README.history file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/gcc/7.2.0/gentoo/README.history?rev=1.4&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/gcc/7.2.0/gentoo/README.history?rev=1.4&content-type=text/plain diff : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/gcc/7.2.0/gentoo/README.history?r1=1.3&r2=1.4 Index: README.history =================================================================== RCS file: /var/cvsroot/gentoo/src/patchsets/gcc/7.2.0/gentoo/README.history,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- README.history 6 Jan 2018 19:34:57 -0000 1.3 +++ README.history 13 Jan 2018 11:29:11 -0000 1.4 @@ -1,3 +1,5 @@ +1.2 TODO + + 97_all_shift-codegen-PR83565.patch 1.1 06 Jan 2018 + 95_all_static_override_pie.patch + 96_all_powerpc_pie.patch 1.1 src/patchsets/gcc/7.2.0/gentoo/97_all_shift-codegen-PR83565.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/gcc/7.2.0/gentoo/97_all_shift-codegen-PR83565.patch?rev=1.1&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/gcc/7.2.0/gentoo/97_all_shift-codegen-PR83565.patch?rev=1.1&content-type=text/plain Index: 97_all_shift-codegen-PR83565.patch =================================================================== Fixes openssl miscompilation at least on ia64. https://gcc.gnu.org/PR83565 >From 86ae8eb8e5ae4b6a5d485fdef4adf818847d0112 Mon Sep 17 00:00:00 2001 From: ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 12 Jan 2018 10:20:42 +0000 Subject: [PATCH] PR rtl-optimization/83565 * rtlanal.c (nonzero_bits1): On WORD_REGISTER_OPERATIONS machines, do not extend the result to a larger mode for rotate operations. (num_sign_bit_copies1): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256573 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/rtlanal.c | 27 ++++++++++---------- gcc/testsuite/gcc.c-torture/execute/20180112-1.c | 32 ++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20180112-1.c diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index acb4230aac8..b93d19537bb 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4312,7 +4312,7 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, { unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode); unsigned HOST_WIDE_INT inner_nz; - enum rtx_code code; + enum rtx_code code = GET_CODE (x); machine_mode inner_mode; unsigned int mode_width = GET_MODE_PRECISION (mode); @@ -4335,18 +4335,18 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, return nonzero; /* If MODE is wider than X, but both are a single word for both the host - and target machines, we can compute this from which bits of the - object might be nonzero in its own mode, taking into account the fact - that on many CISC machines, accessing an object in a wider mode - causes the high-order bits to become undefined. So they are - not known to be zero. */ - - if (!WORD_REGISTER_OPERATIONS - && GET_MODE (x) != VOIDmode + and target machines, we can compute this from which bits of the object + 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. */ + 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))) + && GET_MODE_PRECISION (mode) > GET_MODE_PRECISION (GET_MODE (x)) + && (!WORD_REGISTER_OPERATIONS || code == ROTATE)) { nonzero &= cached_nonzero_bits (x, GET_MODE (x), known_x, known_mode, known_ret); @@ -4356,7 +4356,6 @@ nonzero_bits1 (const_rtx x, machine_mode mode, const_rtx known_x, /* Please keep nonzero_bits_binary_arith_p above in sync with the code in the switch below. */ - code = GET_CODE (x); switch (code) { case REG: @@ -4873,8 +4872,10 @@ 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. */ - if (!WORD_REGISTER_OPERATIONS) + 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) return 1; /* Likewise on machines that do, if the mode of the object is smaller diff --git a/gcc/testsuite/gcc.c-torture/execute/20180112-1.c b/gcc/testsuite/gcc.c-torture/execute/20180112-1.c new file mode 100644 index 00000000000..6752661ecb6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20180112-1.c @@ -0,0 +1,32 @@ +/* PR rtl-optimization/83565 */ +/* Testcase by Sergei Trofimovich <[email protected]> */ + +extern void abort (void); + +typedef unsigned int u32; + +u32 bug (u32 * result) __attribute__((noinline)); +u32 bug (u32 * result) +{ + volatile u32 ss = 0xFFFFffff; + volatile u32 d = 0xEEEEeeee; + u32 tt = d & 0x00800000; + u32 r = tt << 8; + + r = (r >> 31) | (r << 1); + + u32 u = r^ss; + u32 off = u >> 1; + + *result = tt; + return off; +} + +int main(void) +{ + u32 l; + u32 off = bug(&l); + if (off != 0x7fffffff) + abort (); + return 0; +} -- 2.15.1
