diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2021-03-18 16:05:27 +0100 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2021-03-23 02:57:41 -0400 |
commit | 88081d38bd82562b6e2d6a4a275e7f6f2aac3422 (patch) | |
tree | aaa780bc5eedd443151939c953fff9d6047b2858 /gcc | |
parent | 441e1980cea7265c340868468cd63ea8c046ddec (diff) | |
download | gcc-88081d38bd82562b6e2d6a4a275e7f6f2aac3422.zip gcc-88081d38bd82562b6e2d6a4a275e7f6f2aac3422.tar.gz gcc-88081d38bd82562b6e2d6a4a275e7f6f2aac3422.tar.bz2 |
Handle setting of 1-bit anti-ranges uniformly.
PR tree-optimization/99296
* value-range.cc (irange::irange_set_1bit_anti_range): New.
(irange::irange_set_anti_range): Call irange_set_1bit_anti_range
* value-range.h (irange::irange_set_1bit_anti_range): New.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/pr99296.c | 7 | ||||
-rw-r--r-- | gcc/value-range.cc | 31 | ||||
-rw-r--r-- | gcc/value-range.h | 2 |
3 files changed, 40 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/pr99296.c b/gcc/testsuite/gcc.dg/pr99296.c new file mode 100644 index 0000000..4a0b3f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99296.c @@ -0,0 +1,7 @@ +// { dg-do compile } +// { dg-options "-O2 -fno-tree-bit-ccp" } + +struct { + signed a : 1; +} b, c; +void d() { b.a |= c.a |= 0 != 2; } diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 9c42f82..cd21f75 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -185,11 +185,42 @@ irange::irange_set (tree min, tree max) } void +irange::irange_set_1bit_anti_range (tree min, tree max) +{ + tree type = TREE_TYPE (min); + gcc_checking_assert (TYPE_PRECISION (type) == 1); + + if (operand_equal_p (min, max)) + { + // Since these are 1-bit quantities, they can only be [MIN,MIN] + // or [MAX,MAX]. + if (vrp_val_is_min (min)) + min = max = vrp_val_max (type); + else + min = max = vrp_val_min (type); + set (min, max); + } + else + { + // The only alternative is [MIN,MAX], which is the empty range. + set_undefined (); + } + if (flag_checking) + verify_range (); +} + +void irange::irange_set_anti_range (tree min, tree max) { gcc_checking_assert (!POLY_INT_CST_P (min)); gcc_checking_assert (!POLY_INT_CST_P (max)); + if (TYPE_PRECISION (TREE_TYPE (min)) == 1) + { + irange_set_1bit_anti_range (min, max); + return; + } + // set an anti-range tree type = TREE_TYPE (min); signop sign = TYPE_SIGN (type); diff --git a/gcc/value-range.h b/gcc/value-range.h index 8a4d8ec..bfc54a24 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -127,6 +127,8 @@ protected: void copy_legacy_to_multi_range (const irange &); private: + void irange_set_1bit_anti_range (tree, tree); + unsigned char m_num_ranges; unsigned char m_max_ranges; ENUM_BITFIELD(value_range_kind) m_kind : 8; |