This is an archive of the discontinued LLVM Phabricator instance.

[AArch64] Add an IR type for the LS64 extension.
AbandonedPublic

Authored by labrinea on Jan 5 2021, 8:34 AM.

Details

Summary

As explained in the RFC [1], I think we need a new IR type to support the Armv8.7-A LD64B/ST64B instructions in inline assembly. Or, at least, this approach requires the least amount of work. This patch adds a new LLVM IR type named aarch64_ls64 for representing data512_t, which is the C type that ACLE suggests for the corresponding instrinsics.

An obvious alternative would be i512, but there is no Machine Value type for it. The integer types in LLVM's enumeration of 'simple value types' only go up to i128, which means both i512 and i256 need to be added because most of the legalization / lowering machinery for integer types assumes that you can find an integer type half the size. But can we legalize those types? The i256 value type doesn't even have a register class to begin with. Even if we manage to just legalize i512 for loads and stores it's not enough. Legitimate IR, which performs arithmetic on i512, would make the compiler crash during instruction selection in the absence of i256:

define void @foo(i512* %ptr) {
entry:
    %val = load i512, i512* %ptr, align 8
    %square = mul i512 %val, %val
    store i512 %square, i512* %ptr, align 8
    ret void
}

Normally you expect that to get automatically broken down into i64 or i32 or whatever the target can cope with.

To give a bit more context about what I've tried with i512: I made it a legal type with a valid register class, setting all the operations to 'expand', except for the trivial ones (bitcast and undef), and also load and store. This didn't work well, for most operations, because the in-built code for expanding overlarge integer operations expects to be able to break them into two smaller halves. In the above example that doesn't work, because we've made i512 a legal type but not i256. So the compiler crashes during isel lowering.

Another problem I came across with i512 was in GlobalISel. It crashes at -O0 in relation to the new GPR64x8 register class. The most immediate problem seems to be that AArch64RegisterBankInfo::getRegBankFromRegClass doesn't know what register bank that class corresponds to. But even if I workaround it, then further assertions fail beyond it.

[1] http://lists.llvm.org/pipermail/llvm-dev/2020-November/146860.html

Diff Detail