aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-01-31 14:40:24 +0100
committerRichard Biener <rguenther@suse.de>2024-06-21 11:21:29 +0200
commit0d0f181dedb928a6dbb9af040a09cda3f4d5da64 (patch)
tree9491068b3bc80c96d2367cdfbdec4e3c7fc2a6e8
parent8d7ff01933c18532c82c864bd9182db619fcab43 (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.pd12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110176.c46
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;
+}