commit: 9ca1911ae9a17a81f743d84fa8eb705a89338419 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Tue Nov 18 11:24:12 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Tue Nov 18 11:24:30 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=9ca1911a
16.0.0: fix pattern Bug: https://gcc.gnu.org/PR122733 Signed-off-by: Sam James <sam <AT> gentoo.org> 16.0.0/gentoo/88_all_PR122733.patch | 198 ++++++++++++++++++++++++++++++++++++ 16.0.0/gentoo/README.history | 4 + 2 files changed, 202 insertions(+) diff --git a/16.0.0/gentoo/88_all_PR122733.patch b/16.0.0/gentoo/88_all_PR122733.patch new file mode 100644 index 0000000..4d5604c --- /dev/null +++ b/16.0.0/gentoo/88_all_PR122733.patch @@ -0,0 +1,198 @@ +From 48b2a124ed29231125fa2d048bf48f3ca5f4ebbf Mon Sep 17 00:00:00 2001 +Message-ID: <48b2a124ed29231125fa2d048bf48f3ca5f4ebbf.1763465020.git....@gentoo.org> +From: Dhruv Chawla <[email protected]> +Date: Tue, 18 Nov 2025 14:48:38 +0530 +Subject: [PATCH] PR tree-optimization/122733: Fix overflowing unsigned shift + for (y << x) {<,<=,>,>=} x + +The patch previously committed as r16-5161-gc4ca512358be7c would +miscompile the cases where the LHS was unsigned and overflowed, as the +comparison would then give a different result. For example: + +__attribute__ ((noipa)) bool +lshift_lt(unsigned x, unsigned y) +{ + if (y <= 0) + __builtin_unreachable (); + return (y << x) < x; +} + +int main() +{ + if (!lshift_lt(1, 0x80000000)) + __builtin_abort(); +} + +Here 0x80000000 << 1 evaluates to 0 which is < 1 hence the comparison +evaluates to true. However this currently gets optimized to false, and +similar cases are there for the other operators as well. Therefore this +is only valid to do in the cases where overflow is undefined. + +Bootstrapped and regtested on aarch64-linux-gnu. + +Signed-off-by: Dhruv Chawla <[email protected]> + + PR tree-optimization/122733 + +gcc/ChangeLog: + + * match.pd: Add TYPE_OVERFLOW_UNDEFINED check to patterns. Also + replace build_one_cst/build_zero_cst with + constant_boolean_node. + +gcc/testsuite/ChangeLog: + +* gcc.dg/match-shift-cmp-1.c: Update counts to match changes. + * gcc.dg/match-shift-cmp-4.c: Likewise. + * gcc.dg/match-shift-cmp-5.c: New test. +--- + gcc/match.pd | 18 ++++---- + gcc/testsuite/gcc.dg/match-shift-cmp-1.c | 3 +- + gcc/testsuite/gcc.dg/match-shift-cmp-4.c | 7 +++- + gcc/testsuite/gcc.dg/match-shift-cmp-5.c | 53 ++++++++++++++++++++++++ + 4 files changed, 70 insertions(+), 11 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/match-shift-cmp-5.c + +diff --git a/gcc/match.pd b/gcc/match.pd +index 63d56b081925..1f5c7a34613a 100644 +--- a/gcc/match.pd ++++ b/gcc/match.pd +@@ -1339,37 +1339,39 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) + (if (INTEGRAL_TYPE_P (type)) + (rshift (op @0 @2) @1)))) + +-/* (y << x) == x -> 0 when y != 0. */ ++/* (y << x) == x -> false when y != 0. */ + (simplify + (eq:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && tree_expr_nonzero_p (@0)) +- { build_zero_cst (type); })) ++ { constant_boolean_node (false, type); })) + +-/* (y << x) {<,<=} x -> 0 when y > 0. */ ++/* (y << x) {<,<=} x -> false when y > 0 (unless y wraps around). */ + (for cmp (lt le) + (simplify + (cmp:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) ++ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1)) + && tree_expr_nonzero_p (@0) + && tree_expr_nonnegative_p (@0)) +- { build_zero_cst (type); }))) ++ { constant_boolean_node (false, type); }))) + +-/* (y << x) != x -> 1 when y != 0. */ ++/* (y << x) != x -> true when y != 0. */ + (simplify + (ne:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && tree_expr_nonzero_p (@0)) +- { build_one_cst (type); })) ++ { constant_boolean_node (true, type); })) + +-/* (y << x) {>,>=} x -> 1 when y > 0. */ ++/* (y << x) {>,>=} x -> true when y > 0 (unless y wraps around). */ + (for cmp (gt ge) + (simplify + (cmp:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) ++ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1)) + && tree_expr_nonzero_p (@0) + && tree_expr_nonnegative_p (@0)) +- { build_one_cst (type); }))) ++ { constant_boolean_node (true, type); }))) + + /* Fold (1 << (C - x)) where C = precision(type) - 1 + into ((1 << C) >> x). */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-1.c b/gcc/testsuite/gcc.dg/match-shift-cmp-1.c +index b22d57d370f1..6439c5255d85 100644 +--- a/gcc/testsuite/gcc.dg/match-shift-cmp-1.c ++++ b/gcc/testsuite/gcc.dg/match-shift-cmp-1.c +@@ -46,5 +46,6 @@ TEST_OP (gt, >) + TEST_OP (le, <=) + TEST_OP (ge, >=) + ++/* The unsigned cases for lt, le, gt and ge are not optimized. */ + /* FIXME: The lt, le, gt and ge cases for int and enum don't get optimized. */ +-/* { dg-final { scan-tree-dump-times "<<" 8 optimized } } */ ++/* { dg-final { scan-tree-dump-times "<<" 16 optimized } } */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-4.c b/gcc/testsuite/gcc.dg/match-shift-cmp-4.c +index 629e2a376d11..7eddd80f8b59 100644 +--- a/gcc/testsuite/gcc.dg/match-shift-cmp-4.c ++++ b/gcc/testsuite/gcc.dg/match-shift-cmp-4.c +@@ -47,5 +47,8 @@ TEST_OP (gt, >) + TEST_OP (le, <=) + TEST_OP (ge, >=) + +-/* { dg-final { scan-tree-dump-times "return 0;" 18 optimized } } */ +-/* { dg-final { scan-tree-dump-times "return 1;" 18 optimized } } */ ++/* { dg-final { scan-tree-dump-times "return 0;" 14 optimized } } */ ++/* { dg-final { scan-tree-dump-times "return 1;" 14 optimized } } */ ++ ++/* The unsigned cases for lt, le, gt and ge are not optimized. */ ++/* { dg-final { scan-tree-dump-times "<<" 8 optimized } } */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-5.c b/gcc/testsuite/gcc.dg/match-shift-cmp-5.c +new file mode 100644 +index 000000000000..4e3f8722ad3d +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/match-shift-cmp-5.c +@@ -0,0 +1,53 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 -fdump-tree-optimized" } */ ++ ++/* PR tree-optimization/122733 */ ++ ++__attribute__ ((noipa)) bool ++lshift_lt(unsigned x, unsigned y) ++{ ++ if (y <= 0) ++ __builtin_unreachable (); ++ return (y << x) < x; ++} ++ ++__attribute__ ((noipa)) bool ++lshift_le(unsigned x, unsigned y) ++{ ++ if (y <= 0) ++ __builtin_unreachable (); ++ return (y << x) <= x; ++} ++ ++__attribute__ ((noipa)) bool ++lshift_gt(unsigned x, unsigned y) ++{ ++ if (y <= 0) ++ __builtin_unreachable (); ++ return (y << x) > x; ++} ++ ++__attribute__ ((noipa)) bool ++lshift_ge(unsigned x, unsigned y) ++{ ++ if (y <= 0) ++ __builtin_unreachable (); ++ return (y << x) >= x; ++} ++ ++int main() ++{ ++ if (!lshift_lt(1, 0x80000000)) ++ __builtin_abort(); ++ ++ if (!lshift_le(1, 0x80000000)) ++ __builtin_abort(); ++ ++ if (lshift_gt(1, 0x80000000)) ++ __builtin_abort(); ++ ++ if (lshift_ge(1, 0x80000000)) ++ __builtin_abort(); ++} ++ ++/* { dg-final { scan-tree-dump-times "<<" 4 optimized } } */ + +base-commit: ac45382d0c06bc1a90ce74e0379e52496ab3bffe +-- +2.51.2 + diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history index fbe9c7c..f8b4030 100644 --- a/16.0.0/gentoo/README.history +++ b/16.0.0/gentoo/README.history @@ -1,3 +1,7 @@ +24 ???? + + + 88_all_PR122733.patch + 23 17 November 2025 - 88_all_PR122620-firefox.patch
