Bug 115036 - division is not shortened based on value range
Summary: division is not shortened based on value range
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: VRP
  Show dependency treegraph
 
Reported: 2024-05-10 15:10 UTC by Jan Hubicka
Modified: 2024-05-13 09:35 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Hubicka 2024-05-10 15:10:35 UTC
For
long test(long a, long b)
{
        if (a > 65535 || a < 0)
                __builtin_unreachable ();
        if (b > 65535 || b < 0)
                __builtin_unreachable ();
        return a/b;
}

we produce
test:
.LFB0:
        .cfi_startproc
        movq    %rdi, %rax
        cqto
        idivq   %rsi
        ret

while clang does:

test:                                   # @test
        .cfi_startproc
# %bb.0:
        movq    %rdi, %rax
                                        # kill: def $ax killed $ax killed $rax
        xorl    %edx, %edx
        divw    %si
        movzwl  %ax, %eax
        retq

clang also by default adds 32bit divide path even when value range is not known

long test(long a, long b)
{
        return a/b;
}

compiles as

test:                                   # @test
        .cfi_startproc
# %bb.0:
        movq    %rdi, %rax
        movq    %rdi, %rcx
        orq     %rsi, %rcx
        shrq    $32, %rcx
        je      .LBB0_1
# %bb.2:
        cqto
        idivq   %rsi
        retq
Comment 1 Richard Biener 2024-05-13 09:35:02 UTC
former fold_stmt_using_ranges has code to narrow ops.