mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
tree-optimization/110243 - IVOPTs introducing undefined overflow
The following addresses IVOPTs rewriting expressions in its strip_offset without caring for definedness of overflow. Rather than the earlier attempt of just using the proper split_constant_offset from data-ref analysis the following adjusts IVOPTs helper trying to minimize changes from this fix, possibly easing backports. PR tree-optimization/110243 PR tree-optimization/111336 * tree-ssa-loop-ivopts.cc (strip_offset_1): Rewrite operations with undefined behavior on overflow to unsigned arithmetic. * gcc.dg/torture/pr110243.c: New testcase. * gcc.dg/torture/pr111336.c: Likewise.
This commit is contained in:
22
gcc/testsuite/gcc.dg/torture/pr110243.c
Normal file
22
gcc/testsuite/gcc.dg/torture/pr110243.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target lp64 } */
|
||||
|
||||
#define X 1100000000
|
||||
unsigned char a;
|
||||
long b = X;
|
||||
int c[9][1];
|
||||
unsigned d;
|
||||
static long *e = &b, *f = &b;
|
||||
int g() {
|
||||
if (a && a <= '9')
|
||||
return '0';
|
||||
if (a)
|
||||
return 10;
|
||||
return -1;
|
||||
}
|
||||
int main() {
|
||||
d = 0;
|
||||
for (; (int)*f -(X-1) + d < 9; d++)
|
||||
c[g() + (int)*f + ((int)*e - X) -(X-1) + d]
|
||||
[0] = 0;
|
||||
}
|
||||
25
gcc/testsuite/gcc.dg/torture/pr111336.c
Normal file
25
gcc/testsuite/gcc.dg/torture/pr111336.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target lp64 } */
|
||||
|
||||
extern void abort (void);
|
||||
int a, b;
|
||||
long c = 3521733542;
|
||||
int d[2];
|
||||
int e(int f, int g) {
|
||||
if (f == 0)
|
||||
return 0;
|
||||
if (f > 200)
|
||||
return 0;
|
||||
if (g)
|
||||
return 5 * f;
|
||||
return 0;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int h = 0;
|
||||
for (; e((int)c + 773233762, c + 60) + 773163185 + h < 2; h++)
|
||||
d[h] = b;
|
||||
if (a != 0)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
@@ -2829,12 +2829,29 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
|
||||
else if (integer_zerop (op0))
|
||||
{
|
||||
if (code == MINUS_EXPR)
|
||||
expr = fold_build1 (NEGATE_EXPR, type, op1);
|
||||
{
|
||||
if (TYPE_OVERFLOW_UNDEFINED (type))
|
||||
{
|
||||
type = unsigned_type_for (type);
|
||||
op1 = fold_convert (type, op1);
|
||||
}
|
||||
expr = fold_build1 (NEGATE_EXPR, type, op1);
|
||||
}
|
||||
else
|
||||
expr = op1;
|
||||
}
|
||||
else
|
||||
expr = fold_build2 (code, type, op0, op1);
|
||||
{
|
||||
if (TYPE_OVERFLOW_UNDEFINED (type))
|
||||
{
|
||||
type = unsigned_type_for (type);
|
||||
if (code == POINTER_PLUS_EXPR)
|
||||
code = PLUS_EXPR;
|
||||
op0 = fold_convert (type, op0);
|
||||
op1 = fold_convert (type, op1);
|
||||
}
|
||||
expr = fold_build2 (code, type, op0, op1);
|
||||
}
|
||||
|
||||
return fold_convert (orig_type, expr);
|
||||
|
||||
@@ -2852,7 +2869,15 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
|
||||
if (integer_zerop (op0))
|
||||
expr = op0;
|
||||
else
|
||||
expr = fold_build2 (MULT_EXPR, type, op0, op1);
|
||||
{
|
||||
if (TYPE_OVERFLOW_UNDEFINED (type))
|
||||
{
|
||||
type = unsigned_type_for (type);
|
||||
op0 = fold_convert (type, op0);
|
||||
op1 = fold_convert (type, op1);
|
||||
}
|
||||
expr = fold_build2 (MULT_EXPR, type, op0, op1);
|
||||
}
|
||||
|
||||
return fold_convert (orig_type, expr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user