[llvm-bugs] [Bug 43973] New: Unnecessary conversion/simplification of vector constants can lead to duplication of constants

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Nov 12 02:40:20 PST 2019


https://bugs.llvm.org/show_bug.cgi?id=43973

            Bug ID: 43973
           Summary: Unnecessary conversion/simplification of vector
                    constants can lead to duplication of constants
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Register Allocator
          Assignee: unassignedbugs at nondot.org
          Reporter: zingaburga+llvm at hotmail.com
                CC: llvm-bugs at lists.llvm.org, quentin.colombet at gmail.com

Firstly, not sure if this is the right place to post this missed optimization -
sorry if I got it wrong.

With the optimizer enabled, it seems that a number of vector constants get
simplified where it results in worse codegen.  Have no clue where this happens,
so I'll use C -> x86 AVX as examples.

First example is an integer subtract with constant which always gets changed to
an add.  For a target like x86 SSE, I suppose this may make sense, as the
commutative property of addition gives more flexibility around register
placement, but it isn't always beneficial - for example, if the constant could
be re-used elsewhere.

Example:

        _mm_or_si128(
                _mm_sub_epi8(a, _mm_set1_epi8(99)),
                _mm_set1_epi8(99)
        );

In this case, the '99' constant can be used in both the subtract and or, but
Clang/LLVM will always convert the first use to a '-99' constant, meaning that
it now has to deal with two constants: https://godbolt.org/z/b_B8yC

Perhaps a different issue, but reversing the arguments to the subtract,
Clang/LLVM performs an unnecessary reload of the constant:
https://godbolt.org/z/8kus5_



Another example would be truncated vector constants, e.g:

        const __m256i stuff = _mm256_set1_epi32(0x01020304);
        a = _mm256_permutexvar_epi16(a, stuff);
        return _mm_or_si128(
                _mm256_extracti128_si256(a, 1),
                _mm256_castsi256_si128(stuff)
        );

Vector for `stuff` can be re-used for both cases, but the second case doesn't
get recognised: https://godbolt.org/z/rZQqTf

Perhaps a different issue, but interestingly in the previous link, even if the
vector isn't truncated, it still gets thought of as different somehow.



Another example, the constant for pshufb is reduced, resulting in duplication
of a constant:

        const __m128i shuf = _mm_set1_epi8(65);
        return _mm_or_si128(
                _mm_shuffle_epi8(a, shuf),
                shuf
        );

https://godbolt.org/z/vEs_S2

If the `65` vector was kept instead of simplifying to a vector of `1`, only one
constant would be needed.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20191112/f241d196/attachment.html>


More information about the llvm-bugs mailing list