From: Jakub Jelinek Date: Mon, 25 Jun 2018 16:45:10 +0000 (+0200) Subject: backport: re PR rtl-optimization/82192 (gcc produces incorrect code with -O2 and... X-Git-Tag: releases/gcc-6.5.0~254 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2eec8c581c7146616cc23af98ba941e33c75be52;p=thirdparty%2Fgcc.git backport: re PR rtl-optimization/82192 (gcc produces incorrect code with -O2 and bit-field) Backported from mainline 2017-09-15 Jakub Jelinek PR rtl-optimization/82192 * combine.c (make_extraction): Don't look through non-paradoxical SUBREGs or TRUNCATE if pos + len is or might be bigger than inner's mode. * gcc.c-torture/execute/pr82192.c: New test. From-SVN: r262028 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 62309f352e26..e0da88cd08c7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -7,6 +7,13 @@ * gimplify.c (gimplify_modify_expr): Don't optimize away zero sized lhs from calls if the lhs has addressable type. + 2017-09-15 Jakub Jelinek + + PR rtl-optimization/82192 + * combine.c (make_extraction): Don't look through non-paradoxical + SUBREGs or TRUNCATE if pos + len is or might be bigger than + inner's mode. + 2018-06-23 Richard Sandiford PR tree-optimization/85989 diff --git a/gcc/combine.c b/gcc/combine.c index 9b0386c99e77..c38b57dd38e2 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7336,7 +7336,14 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, if (pos_rtx && CONST_INT_P (pos_rtx)) pos = INTVAL (pos_rtx), pos_rtx = 0; - if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) + if (GET_CODE (inner) == SUBREG + && subreg_lowpart_p (inner) + && (paradoxical_subreg_p (inner) + /* If trying or potentionally trying to extract + bits outside of is_mode, don't look through + non-paradoxical SUBREGs. See PR82192. */ + || (pos_rtx == NULL_RTX + && pos + len <= GET_MODE_PRECISION (is_mode)))) { /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), consider just the QI as the memory to extract from. @@ -7362,7 +7369,12 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, if (new_rtx != 0) return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1)); } - else if (GET_CODE (inner) == TRUNCATE) + else if (GET_CODE (inner) == TRUNCATE + /* If trying or potentionally trying to extract + bits outside of is_mode, don't look through + TRUNCATE. See PR82192. */ + && pos_rtx == NULL_RTX + && pos + len <= GET_MODE_PRECISION (is_mode)) inner = XEXP (inner, 0); inner_mode = GET_MODE (inner); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b382215ba550..65ee8dae05e1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -11,6 +11,11 @@ PR c++/82159 * g++.dg/opt/pr82159.C: New test. + 2017-09-15 Jakub Jelinek + + PR rtl-optimization/82192 + * gcc.c-torture/execute/pr82192.c: New test. + 2018-06-23 Richard Sandiford PR tree-optimization/85989 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr82192.c b/gcc/testsuite/gcc.c-torture/execute/pr82192.c new file mode 100644 index 000000000000..9e56e203c840 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr82192.c @@ -0,0 +1,22 @@ +/* PR rtl-optimization/82192 */ + +unsigned long long int a = 0x95dd3d896f7422e2ULL; +struct S { unsigned int m : 13; } b; + +__attribute__((noinline, noclone)) void +foo (void) +{ + b.m = ((unsigned) a) >> (0x644eee9667723bf7LL + | a & ~0xdee27af8U) - 0x644eee9667763bd8LL; +} + +int +main () +{ + if (__INT_MAX__ != 0x7fffffffULL) + return 0; + foo (); + if (b.m != 0) + __builtin_abort (); + return 0; +}