diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-03-15 17:11:48 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-03-15 17:11:48 +0100 |
commit | c39858bdb8b7abe0ef235039c69c429e666d5e63 (patch) | |
tree | 780aea325a716ecc198a88cd3bc011cf8ea2e921 /gcc | |
parent | 511e5c4889a3d6fc41547031a8c1d8ac7915508a (diff) | |
download | gcc-c39858bdb8b7abe0ef235039c69c429e666d5e63.zip gcc-c39858bdb8b7abe0ef235039c69c429e666d5e63.tar.gz gcc-c39858bdb8b7abe0ef235039c69c429e666d5e63.tar.bz2 |
re PR rtl-optimization/70222 (Test miscompiled with -O1)
PR rtl-optimization/70222
* combine.c (simplify_shift_const_1): For A >> B >> C LSHIFTRT
optimization if mode is different from result_mode, queue up masking
of the result in outer_op. Formatting fix.
* gcc.c-torture/execute/pr70222-1.c: New test.
* gcc.c-torture/execute/pr70222-2.c: New test.
From-SVN: r234222
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/combine.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr70222-1.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr70222-2.c | 20 |
5 files changed, 73 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9aa11be..ad9e13f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2016-03-15 Jakub Jelinek <jakub@redhat.com> + PR rtl-optimization/70222 + * combine.c (simplify_shift_const_1): For A >> B >> C LSHIFTRT + optimization if mode is different from result_mode, queue up masking + of the result in outer_op. Formatting fix. + PR middle-end/70239 * tree-ssa-sccvn.c (VN_INFO_GET): Use safe_grow_cleared instead of safe_grow. diff --git a/gcc/combine.c b/gcc/combine.c index 24dcefa..f701f28 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -10524,9 +10524,19 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode, && CONST_INT_P (XEXP (varop, 0)) && !CONST_INT_P (XEXP (varop, 1))) { + /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make + sure the result will be masked. See PR70222. */ + if (code == LSHIFTRT + && mode != result_mode + && !merge_outer_ops (&outer_op, &outer_const, AND, + GET_MODE_MASK (result_mode) + >> orig_count, result_mode, + &complement_p)) + break; + rtx new_rtx = simplify_const_binary_operation (code, mode, - XEXP (varop, 0), - GEN_INT (count)); + XEXP (varop, 0), + GEN_INT (count)); varop = gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (varop, 1)); count = 0; continue; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c18e116..732cb33 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-03-15 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/70222 + * gcc.c-torture/execute/pr70222-1.c: New test. + * gcc.c-torture/execute/pr70222-2.c: New test. + 2016-03-15 Richard Henderson <rth@redhat.com> * gcc.dg/tree-ssa/pr68714.c: Test during reassoc1 pass. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70222-1.c b/gcc/testsuite/gcc.c-torture/execute/pr70222-1.c new file mode 100644 index 0000000..d79672e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr70222-1.c @@ -0,0 +1,30 @@ +/* PR rtl-optimization/70222 */ + +int a = 1; +unsigned int b = 2; +int c = 0; +int d = 0; + +void +foo () +{ + int e = ((-(c >= c)) < b) > ((int) (-1ULL >> ((a / a) * 15))); + d = -e; +} + +__attribute__((noinline, noclone)) void +bar (int x) +{ + if (x != -1) + __builtin_abort (); +} + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + foo (); + bar (d); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70222-2.c b/gcc/testsuite/gcc.c-torture/execute/pr70222-2.c new file mode 100644 index 0000000..7611c98 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr70222-2.c @@ -0,0 +1,20 @@ +/* PR rtl-optimization/70222 */ + +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 +__attribute__((noinline, noclone)) unsigned int +foo (int x) +{ + unsigned long long y = -1ULL >> x; + return (unsigned int) y >> 31; +} +#endif + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + if (foo (15) != 1 || foo (32) != 1 || foo (33) != 0) + __builtin_abort (); +#endif + return 0; +} |