From 145bc41dae7c7bfa093d61e77346f98e6a595a0e Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 29 Jul 2021 11:22:28 -0400 Subject: [PATCH] Handle constants in wi_fold for trunc_mod. Handle const % const, as wi_fold_in_parts may now provide this. Before this [10, 10] % [4, 4] would produce [0, 3] instead of [2, 2]. gcc/ * range-op.cc (operator_trunc_mod::wi_fold): Fold constants. gcc/testsuite/ * gcc.dg/tree-ssa/pr61839_2.c: Adjust. Add new const fold test. --- gcc/range-op.cc | 12 +++++++ gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c | 39 ++++++++++++++++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 69228882930b..eb66e12677fe 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -3240,6 +3240,18 @@ operator_trunc_mod::wi_fold (irange &r, tree type, return; } + // Check for constant and try to fold. + if (lh_lb == lh_ub && rh_lb == rh_ub) + { + wi::overflow_type ov = wi::OVF_NONE; + tmp = wi::mod_trunc (lh_lb, rh_lb, sign, &ov); + if (ov == wi::OVF_NONE) + { + r = int_range<2> (type, tmp, tmp); + return; + } + } + // ABS (A % B) < ABS (B) and either 0 <= A % B <= A or A <= A % B <= 0. new_ub = rh_ub - 1; if (sign == SIGNED) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c index f1b8feb4e9d3..0e0f4c021131 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c @@ -45,9 +45,40 @@ int bar2 () return 0; } -/* Dont optimize 972195717 / 0 in function foo. */ +/* Ensure we are folding modulus sub-ranges properly. */ +__attribute__ ((noinline)) +int mod (int a, int b) +{ + int v1, v2; + v1 = (a < 10) ? 12 : 24; + v2 = (b > 20) ? 3 : 6; + + if (a > 20) + v1 = v1 * 2; + if (b > 20) + v2 = v2 * 2; + + if (a == b) + v2 = 0; + + /* v1 == 12, 24, or 48. v2 == 0, 3, 6, or 12. */ + int c = v1 % v2; + if (c == 0) + ; + else + __builtin_abort (); + return 0; +} + +/* EVRP now makes transformations in all functions, leaving a single + * builtin_abort call in bar2. */ +/* { dg-final { scan-tree-dump-times "__builtin_abort" 1 "evrp" } } */ + +/* Make sure to optimize 972195717 / 0 in function foo. */ /* { dg-final { scan-tree-dump-times "972195717 / " 0 "evrp" } } */ -/* Dont optimize 972195717 % 0 in function bar. */ -/* { dg-final { scan-tree-dump-times "972195717 % " 1 "evrp" } } */ -/* May optimize in function bar2, but EVRP doesn't perform this yet. */ +/* Make sure to optimize 972195717 % 0 in function bar. */ +/* { dg-final { scan-tree-dump-times "972195717 % " 0 "evrp" } } */ +/* Make sure to optimize 972195717 % [1,2] function bar2. */ /* { dg-final { scan-tree-dump-times "972195715 % " 0 "evrp" } } */ +/* [12,12][24,24][48,48] % [0,0][3,3][6,6][12,12] == [0,0] */ +/* { dg-final { scan-tree-dump-times "%" 0 "evrp" } } */ -- 2.47.2