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

Reply via email to