From 84f7bab89279ca1234fef88929c74caeda8cb55e Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 30 Jun 2021 14:15:53 -0400 Subject: [PATCH] Fix build_gt and build_lt for signed 1 bit values. Signed 1 bit values have a range of [-1, 0] but neither (0 - 1) nor (-1 + 1) can be represented. For signed values, add or subtract -1 as appropriate. PR tree-optimization/101223 gcc/ * range-op.cc (build_lt): Add -1 for signed values. (built_gt): Subtract -1 for signed values. gcc/testsuite/ * gcc.dg/pr101223.c: New. --- gcc/range-op.cc | 18 +++++++++++++++-- gcc/testsuite/gcc.dg/pr101223.c | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr101223.c diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 97b9843..f8e4c6d 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -687,7 +687,14 @@ static void build_lt (irange &r, tree type, const wide_int &val) { wi::overflow_type ov; - wide_int lim = wi::sub (val, 1, TYPE_SIGN (type), &ov); + wide_int lim; + signop sgn = TYPE_SIGN (type); + + // Signed 1 bit cannot represent 1 for subtraction. + if (sgn == SIGNED) + lim = wi::add (val, -1, sgn, &ov); + else + lim = wi::sub (val, 1, sgn, &ov); // If val - 1 underflows, check if X < MIN, which is an empty range. if (ov) @@ -710,7 +717,14 @@ static void build_gt (irange &r, tree type, const wide_int &val) { wi::overflow_type ov; - wide_int lim = wi::add (val, 1, TYPE_SIGN (type), &ov); + wide_int lim; + signop sgn = TYPE_SIGN (type); + + // Signed 1 bit cannot represent 1 for addition. + if (sgn == SIGNED) + lim = wi::sub (val, -1, sgn, &ov); + else + lim = wi::add (val, 1, sgn, &ov); // If val + 1 overflows, check is for X > MAX, which is an empty range. if (ov) r.set_undefined (); diff --git a/gcc/testsuite/gcc.dg/pr101223.c b/gcc/testsuite/gcc.dg/pr101223.c new file mode 100644 index 0000000..6d5a247 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101223.c @@ -0,0 +1,44 @@ +/* PR tree-optimization/101223 */ +/* { dg-do run } */ +/* { dg-options "-O2 " } */ + +struct { + int a : 1; +} b; +int c = 1, d; +int foo1() { + for (; d < 2; d++) { + int e = ~c, f = 0, g; + if (e) { + f = c; + g = b.a; + b.a = f; + if (b.a >= g) + __builtin_abort(); + } + c = f; + b.a = g; + } + return 0; +} + +int foo2() { + for (; d < 2; d++) { + int e = ~c, f = 0, g; + if (e) { + f = c; + g = b.a; + b.a = f; + if (g <= b.a) + __builtin_abort(); + } + c = f; + b.a = g; + } + return 0; +} +int main () +{ + return foo1() + foo2(); +} + -- 2.7.4