diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-05-18 22:39:05 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-05-18 22:39:05 +0200 |
commit | 681056ae64c6f8bd4cc67e00cb87b4c7272eec5e (patch) | |
tree | affa7b875eb03cf2f2c87a940a527e1252d31696 /gcc/tree-vrp.c | |
parent | 8199eea14f1ab32d805cc4be98ecfb5424a78671 (diff) | |
download | gcc-681056ae64c6f8bd4cc67e00cb87b4c7272eec5e.tar.gz |
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
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index d940336b40d..2d3a6fcad70 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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 |