diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-04-18 21:17:32 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-04-18 21:17:32 +0200 |
commit | 0155ed56af293eac25c3eda84b0977c82659d2d9 (patch) | |
tree | bd98f09658d83ba8af9235cf1a7c8425added391 /gcc/tree-vrp.c | |
parent | f380f6082268c9e88fe635b198d9e6e735f07c5f (diff) | |
download | gcc-0155ed56af293eac25c3eda84b0977c82659d2d9.zip gcc-0155ed56af293eac25c3eda84b0977c82659d2d9.tar.gz gcc-0155ed56af293eac25c3eda84b0977c82659d2d9.tar.bz2 |
re PR tree-optimization/80443 (ICE on valid code at -O2 on x86_64-linux-gnu: in set_value_range, at tree-vrp.c:367)
PR tree-optimization/80443
* tree-vrp.c (intersect_ranges): For signed 1-bit precision type,
instead of adding 1, subtract -1 and similarly instead of subtracting
1 add -1.
* gcc.c-torture/compile/pr80443.c: New test.
From-SVN: r246981
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 28d9c17..6d802de 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -8756,20 +8756,32 @@ intersect_ranges (enum value_range_type *vr0type, /* Choose the right gap if the left one is empty. */ if (mineq) { - if (TREE_CODE (vr1max) == INTEGER_CST) - *vr0min = int_const_binop (PLUS_EXPR, vr1max, - build_int_cst (TREE_TYPE (vr1max), 1)); - else + if (TREE_CODE (vr1max) != INTEGER_CST) *vr0min = vr1max; + else if (TYPE_PRECISION (TREE_TYPE (vr1max)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (vr1max))) + *vr0min + = int_const_binop (MINUS_EXPR, vr1max, + build_int_cst (TREE_TYPE (vr1max), -1)); + else + *vr0min + = int_const_binop (PLUS_EXPR, vr1max, + build_int_cst (TREE_TYPE (vr1max), 1)); } /* Choose the left gap if the right one is empty. */ else if (maxeq) { - if (TREE_CODE (vr1min) == INTEGER_CST) - *vr0max = int_const_binop (MINUS_EXPR, vr1min, - build_int_cst (TREE_TYPE (vr1min), 1)); - else + if (TREE_CODE (vr1min) != INTEGER_CST) *vr0max = vr1min; + else if (TYPE_PRECISION (TREE_TYPE (vr1min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (vr1min))) + *vr0max + = int_const_binop (PLUS_EXPR, vr1min, + build_int_cst (TREE_TYPE (vr1min), -1)); + else + *vr0max + = int_const_binop (MINUS_EXPR, vr1min, + build_int_cst (TREE_TYPE (vr1min), 1)); } /* Choose the anti-range if the range is effectively varying. */ else if (vrp_val_is_min (*vr0min) @@ -8811,22 +8823,34 @@ intersect_ranges (enum value_range_type *vr0type, if (mineq) { *vr0type = VR_RANGE; - if (TREE_CODE (*vr0max) == INTEGER_CST) - *vr0min = int_const_binop (PLUS_EXPR, *vr0max, - build_int_cst (TREE_TYPE (*vr0max), 1)); - else + if (TREE_CODE (*vr0max) != INTEGER_CST) *vr0min = *vr0max; + else if (TYPE_PRECISION (TREE_TYPE (*vr0max)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (*vr0max))) + *vr0min + = int_const_binop (MINUS_EXPR, *vr0max, + build_int_cst (TREE_TYPE (*vr0max), -1)); + else + *vr0min + = int_const_binop (PLUS_EXPR, *vr0max, + build_int_cst (TREE_TYPE (*vr0max), 1)); *vr0max = vr1max; } /* Choose the left gap if the right is empty. */ else if (maxeq) { *vr0type = VR_RANGE; - if (TREE_CODE (*vr0min) == INTEGER_CST) - *vr0max = int_const_binop (MINUS_EXPR, *vr0min, - build_int_cst (TREE_TYPE (*vr0min), 1)); - else + if (TREE_CODE (*vr0min) != INTEGER_CST) *vr0max = *vr0min; + else if (TYPE_PRECISION (TREE_TYPE (*vr0min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (*vr0min))) + *vr0max + = int_const_binop (PLUS_EXPR, *vr0min, + build_int_cst (TREE_TYPE (*vr0min), -1)); + else + *vr0max + = int_const_binop (MINUS_EXPR, *vr0min, + build_int_cst (TREE_TYPE (*vr0min), 1)); *vr0min = vr1min; } /* Choose the anti-range if the range is effectively varying. */ |