Commit 681056ae by Jakub Jelinek Committed by Jakub Jelinek

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
parent 8199eea1
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
......
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.
......
// 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;
}
/* 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;
}
/* 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" } } */
/* 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment