re PR c++/49039 (LLVM StringRef miscompilation with -O2)
PR tree-optimization/49039 * tree-vrp.c (extract_range_from_binary_expr): For MIN_EXPR <~[a, b], ~[c, d]> and MAX_EXPR <~[a, b], ~[c, d]> return ~[MAX_EXPR <a, c>, MIN_EXPR <b, d>]. * gcc.c-torture/execute/pr49039.c: New test. * gcc.dg/tree-ssa/pr49039.c: New test. * g++.dg/torture/pr49039.C: New test. From-SVN: r173876
This commit is contained in:
parent
8199eea14f
commit
681056ae64
|
@ -1,3 +1,10 @@
|
|||
2011-05-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/49039
|
||||
* tree-vrp.c (extract_range_from_binary_expr): For
|
||||
MIN_EXPR <~[a, b], ~[c, d]> and MAX_EXPR <~[a, b], ~[c, d]>
|
||||
return ~[MAX_EXPR <a, c>, MIN_EXPR <b, d>].
|
||||
|
||||
2011-05-18 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
PR target/45098
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2011-05-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/49039
|
||||
* gcc.c-torture/execute/pr49039.c: New test.
|
||||
* gcc.dg/tree-ssa/pr49039.c: New test.
|
||||
* g++.dg/torture/pr49039.C: New test.
|
||||
|
||||
2011-05-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/constexpr-incomplete3.C: New.
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
// PR tree-optimization/49039
|
||||
// { dg-do run }
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair (const T1 & a, const T2 & b):first (a), second (b) {}
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
inline pair <T1, T2>
|
||||
make_pair (T1 x, T2 y)
|
||||
{
|
||||
return pair <T1, T2> (x, y);
|
||||
}
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
struct S
|
||||
{
|
||||
const char *Data;
|
||||
size_t Length;
|
||||
static size_t min (size_t a, size_t b) { return a < b ? a : b; }
|
||||
static size_t max (size_t a, size_t b) { return a > b ? a : b; }
|
||||
S () :Data (0), Length (0) { }
|
||||
S (const char *Str) : Data (Str), Length (__builtin_strlen (Str)) {}
|
||||
S (const char *data, size_t length) : Data (data), Length (length) {}
|
||||
bool empty () const { return Length == 0; }
|
||||
size_t size () const { return Length; }
|
||||
S slice (size_t Start, size_t End) const
|
||||
{
|
||||
Start = min (Start, Length);
|
||||
End = min (max (Start, End), Length);
|
||||
return S (Data + Start, End - Start);
|
||||
}
|
||||
pair <S, S> split (char Separator) const
|
||||
{
|
||||
size_t Idx = find (Separator);
|
||||
if (Idx == ~size_t (0))
|
||||
return make_pair (*this, S ());
|
||||
return make_pair (slice (0, Idx), slice (Idx + 1, ~size_t (0)));
|
||||
}
|
||||
size_t find (char C, size_t From = 0) const
|
||||
{
|
||||
for (size_t i = min (From, Length), e = Length; i != e; ++i)
|
||||
if (Data[i] == C)
|
||||
return i;
|
||||
return ~size_t (0);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
Test (const char *arg)
|
||||
{
|
||||
S Desc (arg);
|
||||
while (!Desc.empty ())
|
||||
{
|
||||
pair <S, S> Split = Desc.split ('-');
|
||||
S Token = Split.first;
|
||||
Desc = Split.second;
|
||||
if (Token.empty ())
|
||||
continue;
|
||||
Split = Token.split (':');
|
||||
S Specifier = Split.first;
|
||||
if (Specifier.empty ())
|
||||
__builtin_abort ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
Test ("-");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* PR tree-optimization/49039 */
|
||||
extern void abort (void);
|
||||
int cnt;
|
||||
|
||||
__attribute__((noinline, noclone)) void
|
||||
foo (unsigned int x, unsigned int y)
|
||||
{
|
||||
unsigned int minv, maxv;
|
||||
if (x == 1 || y == -2U)
|
||||
return;
|
||||
minv = x < y ? x : y;
|
||||
maxv = x > y ? x : y;
|
||||
if (minv == 1)
|
||||
++cnt;
|
||||
if (maxv == -2U)
|
||||
++cnt;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
foo (-2U, 1);
|
||||
if (cnt != 2)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* PR tree-optimization/49039 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-vrp1" } */
|
||||
|
||||
extern void bar (void);
|
||||
|
||||
void
|
||||
foo (unsigned int x, unsigned int y)
|
||||
{
|
||||
unsigned int minv, maxv;
|
||||
if (x >= 3 && x <= 6)
|
||||
return;
|
||||
if (y >= 5 && y <= 8)
|
||||
return;
|
||||
minv = x < y ? x : y;
|
||||
maxv = x > y ? x : y;
|
||||
if (minv == 5)
|
||||
bar ();
|
||||
if (minv == 6)
|
||||
bar ();
|
||||
if (maxv == 5)
|
||||
bar ();
|
||||
if (maxv == 6)
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "Folding predicate minv_\[0-9\]* == 5 to 0" "vrp1" } } */
|
||||
/* { dg-final { scan-tree-dump "Folding predicate minv_\[0-9\]* == 6 to 0" "vrp1" } } */
|
||||
/* { dg-final { scan-tree-dump "Folding predicate maxv_\[0-9\]* == 5 to 0" "vrp1" } } */
|
||||
/* { dg-final { scan-tree-dump "Folding predicate maxv_\[0-9\]* == 6 to 0" "vrp1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vrp1" } } */
|
|
@ -1,5 +1,5 @@
|
|||
/* Support routines for Value Range Propagation (VRP).
|
||||
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Diego Novillo <dnovillo@redhat.com>.
|
||||
|
||||
|
@ -2358,17 +2358,27 @@ extract_range_from_binary_expr (value_range_t *vr,
|
|||
op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
|
||||
Note that we are guaranteed to have vr0.type == vr1.type at
|
||||
this point. */
|
||||
if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
|
||||
if (vr0.type == VR_ANTI_RANGE)
|
||||
{
|
||||
set_value_range_to_varying (vr);
|
||||
return;
|
||||
if (code == PLUS_EXPR)
|
||||
{
|
||||
set_value_range_to_varying (vr);
|
||||
return;
|
||||
}
|
||||
/* For MIN_EXPR and MAX_EXPR with two VR_ANTI_RANGEs,
|
||||
the resulting VR_ANTI_RANGE is the same - intersection
|
||||
of the two ranges. */
|
||||
min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min);
|
||||
max = vrp_int_const_binop (MIN_EXPR, vr0.max, vr1.max);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For operations that make the resulting range directly
|
||||
proportional to the original ranges, apply the operation to
|
||||
the same end of each range. */
|
||||
min = vrp_int_const_binop (code, vr0.min, vr1.min);
|
||||
max = vrp_int_const_binop (code, vr0.max, vr1.max);
|
||||
}
|
||||
|
||||
/* For operations that make the resulting range directly
|
||||
proportional to the original ranges, apply the operation to
|
||||
the same end of each range. */
|
||||
min = vrp_int_const_binop (code, vr0.min, vr1.min);
|
||||
max = vrp_int_const_binop (code, vr0.max, vr1.max);
|
||||
|
||||
/* If both additions overflowed the range kind is still correct.
|
||||
This happens regularly with subtracting something in unsigned
|
||||
|
|
Loading…
Reference in New Issue