diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-05-31 17:01:17 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-05-31 17:01:17 +0000 |
commit | 1f7a8dccd4056be197e8f79fe7bbf2b8bd89c53b (patch) | |
tree | eac927b74d933af84e28ee45cd568925d8de1411 | |
parent | 1027314a211e7b0e2b05b6bd8f179c12f784517e (diff) | |
download | gcc-1f7a8dccd4056be197e8f79fe7bbf2b8bd89c53b.zip gcc-1f7a8dccd4056be197e8f79fe7bbf2b8bd89c53b.tar.gz gcc-1f7a8dccd4056be197e8f79fe7bbf2b8bd89c53b.tar.bz2 |
re PR c++/15069 (a bit test on a variable of enum type is miscompiled)
PR middle-end/15069
* fold-const.c (fold_single_bit_test): Only perform "(X & C) != 0"
into "X < 0" (where C is the signbit) if X's type is a full mode.
* g++.dg/opt/fold3.C: New test case.
From-SVN: r82490
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/fold3.C | 21 |
4 files changed, 37 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c639b56..cea33d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-05-31 Roger Sayle <roger@eyesopen.com> + + PR middle-end/15069 + * fold-const.c (fold_single_bit_test): Only perform "(X & C) != 0" + into "X < 0" (where C is the signbit) if X's type is a full mode. + 2004-05-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> * pa.md: Disable the peephole2 patterns that generate indexed diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d2e333e..b0d1db2 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5413,7 +5413,11 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, /* If we have (A & C) != 0 where C is the sign bit of A, convert this into A < 0. Similarly for (A & C) == 0 into A >= 0. */ arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1)); - if (arg00 != NULL_TREE) + if (arg00 != NULL_TREE + /* This is only a win if casting to a signed type is cheap, + i.e. when arg00's type is not a partial mode. */ + && TYPE_PRECISION (TREE_TYPE (arg00)) + == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00)))) { tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00)); return fold (build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR, @@ -5421,10 +5425,6 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1, fold_convert (stype, integer_zero_node))); } - /* At this point, we know that arg0 is not testing the sign bit. */ - if (TYPE_PRECISION (type) - 1 == bitnum) - abort (); - /* Otherwise we have (A & C) != 0 where C is a single bit, convert that into ((A >> C2) & 1). Where C2 = log2(C). Similarly for (A & C) == 0. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d5e0a5..47ed126 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-05-31 Roger Sayle <roger@eyesopen.com> + + PR middle-end/15069 + * g++.dg/opt/fold3.C: New test case. + 2004-05-30 Graham Stott <graham.stott@btinternet.com> * lib/target-supports.exp (check_iconv_available): Fix fallout diff --git a/gcc/testsuite/g++.dg/opt/fold3.C b/gcc/testsuite/g++.dg/opt/fold3.C new file mode 100644 index 0000000..87a36b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/fold3.C @@ -0,0 +1,21 @@ +// PR middle-end/15069 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); + +typedef enum { + FOUR = 4, + FIVE = 5 +} direction_t; + +int main () +{ + direction_t four = FOUR; + int flags = (four & 4L) ? (32L | 128L) : 0; + flags &= 32L; + + if (flags == 0) + abort (); +} + |