Special case -TYPE_MIN_VALUE for flag_wrapv in operator_abs::op1_range.

With flag_wrapv, -TYPE_MIN_VALUE = TYPE_MIN_VALUE which is
unrepresentable.  We currently special case this in the ABS folding
routine, but are missing similar treatment in operator_abs::op1_range.

Tested on x86-64 Linux.

	PR tree-optimization/101938

gcc/ChangeLog:

	* range-op.cc (operator_abs::op1_range): Special case
	-TYPE_MIN_VALUE for flag_wrapv.

gcc/testsuite/ChangeLog:

	* gcc.dg/pr101938.c: New test.
This commit is contained in:
Andrew MacLeod 2021-08-17 10:50:56 +02:00 committed by Aldy Hernandez
parent 3ed7796896
commit 891bdbf2b0
2 changed files with 34 additions and 0 deletions

View file

@ -3642,6 +3642,12 @@ operator_abs::op1_range (irange &r, tree type,
r.union_ (int_range<1> (type,
-positives.upper_bound (i),
-positives.lower_bound (i)));
// With flag_wrapv, -TYPE_MIN_VALUE = TYPE_MIN_VALUE which is
// unrepresentable. Add -TYPE_MIN_VALUE in this case.
wide_int min_value = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
wide_int lb = lhs.lower_bound ();
if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lb, min_value))
r.union_ (int_range<2> (type, lb, lb));
return true;
}

View file

@ -0,0 +1,28 @@
// { dg-do run }
// { dg-require-effective-target lp64 }
// { dg-options "-O2 -fwrapv" }
typedef long long int int64;
#define INT64CONST(x) (x##LL)
/* -9223372036854775808ULL */
#define INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
static void __attribute__((noipa)) foo(int64 arg1, int64 arg2) {
int64 a1 = -arg1;
int64 a2 = (arg2 < 0) ? arg2 : -arg2;
if (a1 > a2) {
int64 swap = arg1;
arg1 = arg2;
arg2 = swap;
}
if (arg1 == INT64_MIN && arg2 == -1) return;
__builtin_abort();
}
int main() {
foo(-1, INT64_MIN);
return 0;
}