From 5edab54b6c5de8ae5fca7b4ce08ddcd31948997d Mon Sep 17 00:00:00 2001 From: Steve Ellcey Date: Fri, 23 Oct 2015 15:58:33 +0000 Subject: [PATCH] re PR rtl-optimization/67736 (Wrong optimization with -fexpensive-optimizations on mips64el) 2015-10-23 Steve Ellcey Andrew Pinski PR rtl-optimization/67736 * gcc.dg/torture/pr67736.c: New test. * gcc.dg/combine-subregs.c: New test. Co-Authored-By: Andrew Pinski From-SVN: r229260 --- gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/gcc.dg/combine-subregs.c | 36 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr67736.c | 32 +++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/combine-subregs.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr67736.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f13e8dcfbf7..1d214359bcd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-10-23 Steve Ellcey + Andrew Pinski + + PR rtl-optimization/67736 + * combine.c (simplify_comparison): Use gen_lowpart_or_truncate instead + of gen_lowpart. + 2015-10-23 Alan Hayward PR tree-optimization/65947 diff --git a/gcc/testsuite/gcc.dg/combine-subregs.c b/gcc/testsuite/gcc.dg/combine-subregs.c new file mode 100644 index 00000000000..ccace233cf8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/combine-subregs.c @@ -0,0 +1,36 @@ +/* { dg-do run { target { stdint_types } } } */ +/* { dg-options "-O2" } */ + +#include +#include + +void __attribute__ ((noinline)) +foo (uint64_t state, uint32_t last) +{ + if (state == last) abort (); +} + +/* This function may do a bad comparision by trying to + use SUBREGS during the compare on machines where comparing + two registers always compares the entire register regardless + of mode. */ + +int __attribute__ ((noinline)) +compare (uint64_t state, uint32_t *last, uint8_t buf) +{ + if (*last == ((state | buf) & 0xFFFFFFFF)) { + foo (state, *last); + return 0; + } + return 1; +} + +int +main(int argc, char **argv) { + uint64_t state = 0xF00000100U; + uint32_t last = 0x101U; + int ret = compare(state, &last, 0x01); + if (ret != 0) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr67736.c b/gcc/testsuite/gcc.dg/torture/pr67736.c new file mode 100644 index 00000000000..024bb207ad3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr67736.c @@ -0,0 +1,32 @@ +/* { dg-do run { target { stdint_types } } } */ + +#include +#include + +void f(uint64_t *a, uint64_t aa) __attribute__((noinline)); +void f(uint64_t *a, uint64_t aa) +{ + uint64_t new_value = aa; + uint64_t old_value = *a; + int bit_size = 32; + uint64_t mask = (uint64_t)(unsigned)(-1); + uint64_t tmp = old_value & mask; + new_value &= mask; + /* On overflow we need to add 1 in the upper bits */ + if (tmp > new_value) + new_value += 1ull<