aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2021-03-18 16:05:27 +0100
committerAldy Hernandez <aldyh@redhat.com>2021-03-23 02:57:41 -0400
commit88081d38bd82562b6e2d6a4a275e7f6f2aac3422 (patch)
treeaaa780bc5eedd443151939c953fff9d6047b2858
parent441e1980cea7265c340868468cd63ea8c046ddec (diff)
downloadgcc-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.
-rw-r--r--gcc/testsuite/gcc.dg/pr99296.c7
-rw-r--r--gcc/value-range.cc31
-rw-r--r--gcc/value-range.h2
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;