[llvm-bugs] [Bug 45431] New: PPC64 vector load and store, offsets, integer math versus pointer math

via llvm-bugs llvm-bugs at lists.llvm.org
Sat Apr 4 14:08:10 PDT 2020


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

            Bug ID: 45431
           Summary: PPC64 vector load and store, offsets, integer math
                    versus pointer math
           Product: clang
           Version: 7.0
          Hardware: Other
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: noloader at gmail.com
                CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
                    richard-llvm at metafoo.co.uk

Hi Everyone,

This is an informational bug report.

We support back to early PowerPC, including old PowerMacs. Loads and stores can
be tricky to get right from early Altivec to modern Power8 and Power9. We
recently cleaned up the code for our loads and stores and encountered a sharp
edge.

Previously we were casting the non-vector type used in vec_xl and vec_xst to a
byte array, and then calling load. We switched to using the native non-vector
type. I.e., if a 32-bit word array was used, then we called vec_xl and vec_xst
using the word array.

We found GCC and XLC uses integer math when calculating effective address using
an offset. We found Clang uses pointer math when calculating effective address
using an offset.

An example:

// PP64 ABI says src and dest arrays are non-const
#define CONST_V8_CAST(x)  ((unsigned char*)(x))
#define CONST_V32_CAST(x) ((unsigned int*)(x))

typedef __vector unsigned char uint8x16_p;
typedef __vector unsigned int  uint32x4_p;

inline uint32x4_p VecLoad(int off, const word32 src[4])
{
    // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit
    // word pointers. The ISA lacks loads for short* and char*.
    // Power9/ISA 3.0 provides vec_xl for all datatypes.
#if (defined(_ARCH_PWR7) && defined(__VSX__)) || defined(_ARCH_PWR8)
    const uintptr_t eff = reinterpret_cast<uintptr_t>(src)+off;
    ASSERT(eff % GetAlignmentOf<word32>() == 0);
# if defined(__clang__)
    // GCC and XLC use integer math for the effective address.
    // LLVM uses pointer math for the effective address.
    return (uint32x4_p)vec_xl(0, CONST_V32_CAST(eff));
# else
    return (uint32x4_p)vec_xl(off, CONST_V32_CAST(src));
# endif
#else
    return (uint32x4_p)VecLoad_ALTIVEC(off, CONST_V8_CAST(src));
#endif
}

VecLoad_ALTIVEC is that early vec_ld that uses vec_lvsl. It is the same code
provided in NXP's Programming Environment Manual (PEM).

This is definitely a sharp edge when using Clang.

-- 
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/20200404/2a110760/attachment.html>


More information about the llvm-bugs mailing list