Skip to content

[MIPS] Missing ANDI optimization #42826

Closed
@arichardson

Description

@arichardson
Bugzilla Link 43481
Version trunk
OS All

Extended Description

We noticed that clang generates unnecessary SLL instructions in one of our benchmark hot paths (and apparently GCC does not): https://godbolt.org/z/xKcCqT

Consider

#include <stdint.h>

uint64_t foo(uint64_t a)
{
    uint64_t b = a / 16;
    uint64_t c = b & 0x7UL;
    return ((uint64_t)1UL << c);
}

At present, the MIPS backend produces:

foo(unsigned long):                                # @&#8203;foo(unsigned long)
        sll     $1, $4, 0
        srl     $1, $1, 4
        andi    $1, $1, 7
        daddiu  $2, $zero, 1
        jr      $ra
        dsllv   $2, $2, $1

The sll is introduced because the srl requires that its input be zero extended (which, well, seems silly, but so it goes). In any case, because andi has a 16-bit immediate, some arithmetic and lookahead could find that 0x7 << 4 fits and so make this be

        andi    $1, $4, 0x70
        srl     $1, $1, 4
        daddiu  $2, $zero, 1
        jr      $ra
        dsllv   $2, $2, $1

Alternatively, whatever's concluding that it can use 32-bit values internally could stop doing that and this could instead just be

        dsrl    $1, $4, 4
        andi    $1, $1, 7
        daddiu  $2, $zero, 1
        jr      $ra
        dsllv   $2, $2, $1

This problem was found by Nathaniel Wesley Filardo and reported as CTSRD-CHERI/llvm-project#343

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions