From 88081d38bd82562b6e2d6a4a275e7f6f2aac3422 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Thu, 18 Mar 2021 16:05:27 +0100 Subject: [PATCH] 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. --- gcc/testsuite/gcc.dg/pr99296.c | 7 +++++++ gcc/value-range.cc | 31 +++++++++++++++++++++++++++++++ gcc/value-range.h | 2 ++ 3 files changed, 40 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr99296.c diff --git a/gcc/testsuite/gcc.dg/pr99296.c b/gcc/testsuite/gcc.dg/pr99296.c new file mode 100644 index 00000000000..4a0b3f0c366 --- /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 9c42f82a105..cd21f75909b 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -184,12 +184,43 @@ irange::irange_set (tree min, tree max) verify_range (); } +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 8a4d8ec4207..bfc54a2473f 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;