diff options
author | Richard Guenther <rguenther@suse.de> | 2010-02-10 11:54:14 +0000 |
---|---|---|
committer | Richard Guenther <rguenther@suse.de> | 2010-02-10 11:54:14 +0000 |
commit | 8eb8358165c45e3c8d8493aafa2c61ced3afb52c (patch) | |
tree | 6113ddc6064eef820caaf65171d7e8681efc3368 /gcc/convert.c | |
parent | f0ebcc9be7bece602cd1ef531017f01d4aab2be5 (diff) |
2010-02-10 Richard Guenther <rguenther@suse.de>
PR c/43007
* tree.c (get_unwidened): Handle constants.
* convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR.
* gcc.c-torture/execute/20100209-1.c: New testcase.
* gcc.dg/fold-div-3.c: Likewise.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@156653 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/convert.c')
-rw-r--r-- | gcc/convert.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/convert.c b/gcc/convert.c index 4fe95ced915..39fbd4d4fa5 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -673,6 +673,31 @@ convert_to_integer (tree type, tree expr) } break; + case TRUNC_DIV_EXPR: + { + tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); + tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); + + /* Don't distribute unless the output precision is at least as big + as the actual inputs and it has the same signedness. */ + if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0)) + && outprec >= TYPE_PRECISION (TREE_TYPE (arg1)) + /* If signedness of arg0 and arg1 don't match, + we can't necessarily find a type to compare them in. */ + && (TYPE_UNSIGNED (TREE_TYPE (arg0)) + == TYPE_UNSIGNED (TREE_TYPE (arg1))) + /* Do not change the sign of the division. */ + && (TYPE_UNSIGNED (TREE_TYPE (expr)) + == TYPE_UNSIGNED (TREE_TYPE (arg0))) + /* Either require unsigned division or a division by + a constant that is not -1. */ + && (TYPE_UNSIGNED (TREE_TYPE (arg0)) + || (TREE_CODE (arg1) == INTEGER_CST + && !integer_all_onesp (arg1)))) + goto trunc1; + break; + } + case MAX_EXPR: case MIN_EXPR: case MULT_EXPR: |