On 7/7/2026 8:02 PM, liuhongt wrote:
Update in V2:
Move the optimization to gimple->RTL expansion phase, query costs
before optimization.
Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
Ok for trunk?
When range info proves that a TRUNC_DIV_EXPR divisor is either N or N
+ 1, and one value is a positive power of two, expand the operation as
two constant divisions selected by a conditional move.
Only do this for speed, when conditional moves are available. Cost
the split sequence against a plain DIV/UDIV and keep the original
expansion unless the split is cheaper.
PR middle-end/125708
gcc/ChangeLog:
* expr.cc: Include gimple-range.h.
(near_pow2_divisor_range_p): New function.
(expand_expr_divmod): Split eligible TRUNC_DIV_EXPRs into two
constant divisions selected by a conditional move.
gcc/testsuite/ChangeLog:
* gcc.c-torture/execute/pr125708-1.c: New test.
* gcc.target/i386/pr125708-2.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr125708-1.c
b/gcc/testsuite/gcc.c-torture/execute/pr125708-1.c
new file mode 100644
index 00000000000..a5f372fee98
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr125708-1.c
I believe this probably belongs in gcc.dg/torture. I think we're (in
general) supposed to be using that instead of the older c-torture
framework. The tests probably need to gate on int32plus given the
constants won't fit in an int for a 16 bit int target. It'll require
some dg-do directives to be effective for what you're trying to test.
+
+/* { dg-final { scan-assembler-not "idiv" } } */
+/* { dg-final { scan-assembler-not "\tdiv" } } */
+/* { dg-final { scan-assembler "cmov" } } */
Any particular reason why only the idiv uses \t? There's some
inconsistency here.
The core of the patch looks good. We just need to resolve the minor
testsuite issues.
jeff