diff options
author | Richard Biener <rguenther@suse.de> | 2024-01-31 14:40:24 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2024-06-21 11:21:29 +0200 |
commit | 0d0f181dedb928a6dbb9af040a09cda3f4d5da64 (patch) | |
tree | 9491068b3bc80c96d2367cdfbdec4e3c7fc2a6e8 | |
parent | 8d7ff01933c18532c82c864bd9182db619fcab43 (diff) |
middle-end/110176 - wrong zext (bool) <= (int) 4294967295u folding
The following fixes a wrong pattern that didn't match the behavior
of the original fold_widened_comparison in that get_unwidened
returned a constant always in the wider type. But here we're
using (int) 4294967295u without the conversion applied. Fixed
by doing as earlier in the pattern - matching constants only
if the conversion was actually applied.
PR middle-end/110176
* match.pd (zext (bool) <= (int) 4294967295u): Make sure
to match INTEGER_CST only without outstanding conversion.
* gcc.dg/torture/pr110176.c: New testcase.
(cherry picked from commit 22dbfbe8767ff4c1d93e39f68ec7c2d5b1358beb)
-rw-r--r-- | gcc/match.pd | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr110176.c | 46 |
2 files changed, 52 insertions, 6 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index d040c853942..7f59b1dac8a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4712,19 +4712,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) >= TYPE_PRECISION (TREE_TYPE (@10))) && (TYPE_UNSIGNED (TREE_TYPE (@00)) == TYPE_UNSIGNED (TREE_TYPE (@10)))) - || (TREE_CODE (@10) == INTEGER_CST + || (TREE_CODE (@1) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (@00)) - && int_fits_type_p (@10, TREE_TYPE (@00))))) + && int_fits_type_p (@1, TREE_TYPE (@00))))) (cmp @00 (convert @10)) - (if (TREE_CODE (@10) == INTEGER_CST + (if (TREE_CODE (@1) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (@00)) - && !int_fits_type_p (@10, TREE_TYPE (@00))) + && !int_fits_type_p (@1, TREE_TYPE (@00))) (with { tree min = lower_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00)); tree max = upper_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00)); - bool above = integer_nonzerop (const_binop (LT_EXPR, type, max, @10)); - bool below = integer_nonzerop (const_binop (LT_EXPR, type, @10, min)); + bool above = integer_nonzerop (const_binop (LT_EXPR, type, max, @1)); + bool below = integer_nonzerop (const_binop (LT_EXPR, type, @1, min)); } (if (above || below) (if (cmp == EQ_EXPR || cmp == NE_EXPR) diff --git a/gcc/testsuite/gcc.dg/torture/pr110176.c b/gcc/testsuite/gcc.dg/torture/pr110176.c new file mode 100644 index 00000000000..e41e3a0c3a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110176.c @@ -0,0 +1,46 @@ +/* { dg-do run } */ + +int f(_Bool t) +{ + int tt = t; + unsigned x = -1; + int xx = x; + return xx <= tt; +} + +int a, b; +void c() {} +__attribute__((noipa)) +void h() {__builtin_abort();} +int d() { + unsigned f[1]; + int i; + if (a) + goto h; + f[0] = -1; + while (1) { + c(); + for (; a < 1; a++) { + if (0) { + j: + continue; + } + i = f[0]; + if (a) + break; + b = i >= (b == 0); + } + if (!b) { + if (0) { + h: + goto j; + } + return 0; + } + h(); + } +} +int main() { + d(); + return 0; +} |