From 8b9cd6490ce507a8e3612044137bd2024e8658c4 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 23 Oct 2025 17:19:02 -0400 Subject: [PATCH] Split signed bitwise AND operations. The algorithm for bitwise AND struggles with complex signed operations which cross the signed/unsigned barrier. When this happens, process it as 2 seperate ranges [LB, -1] and [0, UB], and combine the results. PR tree-optimization/114725.c gcc/ * range-op.cc (operator_bitwise_and::wi_fold): Split signed operations crossing zero into 2 operations. gcc/testsuite/ * gcc.dg/pr114725.c: New. --- gcc/range-op.cc | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/pr114725.c | 15 +++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr114725.c diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 762fd349e5f..6b6bf78cb2f 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -3522,6 +3522,22 @@ operator_bitwise_and::wi_fold (irange &r, tree type, const wide_int &rh_lb, const wide_int &rh_ub) const { + // The AND algorithm does not handle complex signed operations well. + // If a signed range crosses the boundry between signed and unsigned + // proces sit as 2 ranges and union the results. + if (TYPE_SIGN (type) == SIGNED + && wi::neg_p (lh_lb, SIGNED) != wi::neg_p (lh_ub, SIGNED)) + { + int prec = TYPE_PRECISION (type); + int_range_max tmp; + // Process [lh_lb, -1] + wi_fold (tmp, type, lh_lb, wi::minus_one (prec), rh_lb, rh_ub); + // Now Process [0, rh_ub] + wi_fold (r, type, wi::zero (prec), lh_ub, rh_lb, rh_ub); + r.union_ (tmp); + return; + } + if (wi_optimize_and_or (r, BIT_AND_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub)) return; diff --git a/gcc/testsuite/gcc.dg/pr114725.c b/gcc/testsuite/gcc.dg/pr114725.c new file mode 100644 index 00000000000..01c31399ba8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114725.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +//* This should fold to return 0 +bool +src(int offset) +{ + if (offset > 128) + return 0; + else + return (offset & -9) == 258; +} + +/* { dg-final { scan-tree-dump "return 0" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "PHI" "optimized" } } */ -- 2.47.3