diff options
Diffstat (limited to 'gcc/tree-chrec.c')
| -rw-r--r-- | gcc/tree-chrec.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index b48813c8daf..1a229225f80 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -1110,9 +1110,24 @@ chrec_convert (tree type, tree chrec, tree at_stmt) if (evolution_function_is_affine_p (chrec)) { - tree step = convert_step (current_loops->parray[CHREC_VARIABLE (chrec)], - type, CHREC_LEFT (chrec), CHREC_RIGHT (chrec), - at_stmt); + tree step; + bool dummy; + + /* Avoid conversion of (signed char) {(uchar)1, +, (uchar)1}_x + when it is not possible to prove that the scev does not wrap. + See PR22236, where a sequence 1, 2, ..., 255 has to be + converted to signed char, but this would wrap: + 1, 2, ..., 127, -128, ... The result should not be + {(schar)1, +, (schar)1}_x, but instead, we should keep the + conversion: (schar) {(uchar)1, +, (uchar)1}_x. */ + if (scev_probably_wraps_p (type, CHREC_LEFT (chrec), CHREC_RIGHT (chrec), + at_stmt, + current_loops->parray[CHREC_VARIABLE (chrec)], + &dummy, &dummy)) + return fold_convert (type, chrec); + + step = convert_step (current_loops->parray[CHREC_VARIABLE (chrec)], type, + CHREC_LEFT (chrec), CHREC_RIGHT (chrec), at_stmt); if (!step) return fold_convert (type, chrec); |

