Arm64: Optimize SVE VInsElement

This can be done without storing any data to memory and also
compressing the amount of instructions being used.

Thanks to @dougallj for the optimization suggestions.
This commit is contained in:
Lioncache committed 2023-08-22 20:36:29 -04:00
1 parent ed7f1b017d
commit 398a70312e
5 files changed
+1091 -2563

No files matched your search

@@ -2555,59 +2555,33 @@ DEF_OP(VInsElement) {
ElementSize == 4 ? ARMEmitter::SubRegSize::i32Bit :
ElementSize == 8 ? ARMEmitter::SubRegSize::i64Bit : ARMEmitter::SubRegSize::i128Bit;
// We're going to use this to create our predicate register literal.
// On an SVE 256-bit capable system, the predicate register will be
// 32-bit in size. We want to set up only the element corresponding
// to the destination index, since we're going to copy over the equivalent
// indexed element from the source vector.
const auto Data = [ElementSize, DestIdx]() -> uint32_t {
const auto Log2ElementSize = FEXCore::ilog2(ElementSize);
[[maybe_unused]] const auto MaxIndex = (32U >> Log2ElementSize) - 1;
LOGMAN_THROW_AA_FMT(DestIdx <= MaxIndex, "DestIdx ({}) out of range. Must be within [0, {}]",
DestIdx, MaxIndex);
const auto ShiftAmount = DestIdx << Log2ElementSize;
switch (ElementSize) {
case 1:
case 2:
case 4:
case 8:
return 1U << ShiftAmount;
case 16:
// Predicates can't be subdivided into the Q format, so we can just set up
// the predicate to select the two adjacent doublewords.
return 0x101U << ShiftAmount;
default:
FEX_UNREACHABLE;
return UINT32_MAX;
}
}();
// Load our predicate register.
const auto Predicate = ARMEmitter::PReg::p0;
ARMEmitter::ForwardLabel DataLocation;
adr(TMP1, &DataLocation);
ldr(Predicate, TMP1);
// Broadcast our source value across a temporary,
// then combine with the destination.
dup(SubRegSize, VTMP2.Z(), SrcVector.Z(), SrcIdx);
mov(Dst.Z(), Reg.Z());
if (ElementSize == 16) {
mov(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Predicate.Merging(), VTMP2.Z());
}
else {
mov(SubRegSize, Dst.Z(), Predicate.Merging(), VTMP2.Z());
// We don't need to move the data unnecessarily if
// DestVector just so happens to also be the IR op
// destination.
if (Dst != Reg) {
mov(Dst.Z(), Reg.Z());
}
// Set up a label to jump over the data we inserted, so we don't try and execute it.
ARMEmitter::ForwardLabel PastConstant;
b(&PastConstant);
Bind(&DataLocation);
dc32(Data);
Bind(&PastConstant);
constexpr auto Predicate = ARMEmitter::PReg::p0;
if (ElementSize == 16) {
if (DestIdx == 0) {
mov(ARMEmitter::SubRegSize::i8Bit, Dst.Z(), PRED_TMP_16B.Merging(), VTMP2.Z());
} else {
not_(Predicate, PRED_TMP_32B.Zeroing(), PRED_TMP_16B);
mov(ARMEmitter::SubRegSize::i8Bit, Dst.Z(), Predicate.Merging(), VTMP2.Z());
}
} else {
const auto UpperBound = 16 >> FEXCore::ilog2(ElementSize);
const auto TargetElement = static_cast<int>(DestIdx) - UpperBound;
index(SubRegSize, VTMP1.Z(), -UpperBound, 1);
cmpeq(SubRegSize, Predicate, PRED_TMP_32B.Zeroing(), VTMP1.Z(), TargetElement);
mov(SubRegSize, Dst.Z(), Predicate.Merging(), VTMP2.Z());
}
}
else {
LOGMAN_THROW_AA_FMT(ElementSize == 1 || ElementSize == 2 || ElementSize == 4 || ElementSize == 8, "Invalid size");
File diff suppressed because it is too large. Load diff
+45 -89
View File
@@ -24,7 +24,7 @@
]
},
"vpshufb ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 13,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x00 256-bit"
@@ -35,21 +35,13 @@
"mov z6.b, #-113",
"and z5.d, z5.d, z6.d",
"tbl v6.16b, {v4.16b}, v5.16b",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.q, z4.q[1]",
"mov z4.d, z4.d",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"udf #0x101",
"mov z4.b, p6/m, z1.b",
"tbl v4.16b, {v4.16b}, v5.16b",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.q, q4",
"mov z4.d, z6.d",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"not p0.b, p7/z, p6.b",
"mov z4.b, p0/m, z1.b",
"mov z16.d, p7/m, z4.d"
]
},
@@ -69,7 +61,7 @@
]
},
"vphaddw ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 22,
"ExpectedInstructionCount": 18,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x01 256-bit"
@@ -82,20 +74,16 @@
"uzp1 z4.h, z0.h, z0.h",
"uzp2 z1.h, z0.h, z0.h",
"splice z4.d, p6, z4.d, z1.d",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"mov z16.d, p7/m, z4.d"
]
},
@@ -115,7 +103,7 @@
]
},
"vphaddd ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 22,
"ExpectedInstructionCount": 18,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x02 256-bit"
@@ -128,20 +116,16 @@
"uzp1 z4.s, z0.s, z0.s",
"uzp2 z1.s, z0.s, z0.s",
"splice z4.d, p6, z4.d, z1.d",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"mov z16.d, p7/m, z4.d"
]
},
@@ -162,7 +146,7 @@
]
},
"vphaddsw ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 20,
"ExpectedInstructionCount": 16,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x03 256-bit"
@@ -173,20 +157,16 @@
"uzp1 z6.h, z4.h, z5.h",
"uzp2 z4.h, z4.h, z5.h",
"sqadd z4.h, z6.h, z4.h",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"mov z16.d, p7/m, z4.d"
]
},
@@ -251,7 +231,7 @@
]
},
"vphsubw ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 20,
"ExpectedInstructionCount": 16,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x05 256-bit"
@@ -262,20 +242,16 @@
"uzp1 z6.h, z4.h, z5.h",
"uzp2 z4.h, z4.h, z5.h",
"sub z4.h, z6.h, z4.h",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"mov z16.d, p7/m, z4.d"
]
},
@@ -297,7 +273,7 @@
]
},
"vphsubd ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 20,
"ExpectedInstructionCount": 16,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x06 256-bit"
@@ -308,20 +284,16 @@
"uzp1 z6.s, z4.s, z5.s",
"uzp2 z4.s, z4.s, z5.s",
"sub z4.s, z6.s, z4.s",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"mov z16.d, p7/m, z4.d"
]
},
@@ -342,7 +314,7 @@
]
},
"vphsubsw ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 20,
"ExpectedInstructionCount": 16,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x07 256-bit"
@@ -353,20 +325,16 @@
"uzp1 z6.h, z4.h, z5.h",
"uzp2 z4.h, z4.h, z5.h",
"sqsub z4.h, z6.h, z4.h",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"mov z16.d, p7/m, z4.d"
]
},
@@ -549,7 +517,7 @@
]
},
"vpermilps ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 24,
"ExpectedInstructionCount": 20,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x0c 256-bit"
@@ -568,13 +536,9 @@
"mov z6.s, w20",
"mov z7.d, #0",
"mov z8.b, #16",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.q, q8",
"mov z7.d, z7.d",
"mov z7.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"not p0.b, p7/z, p6.b",
"mov z7.b, p0/m, z1.b",
"add z6.b, z6.b, z7.b",
"add z5.b, z6.b, z5.b",
"tbl z4.b, {z4.b}, z5.b",
@@ -610,7 +574,7 @@
]
},
"vpermilpd ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 29,
"ExpectedInstructionCount": 25,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x0d 256-bit"
@@ -634,13 +598,9 @@
"mov z6.d, x20",
"mov z7.d, #0",
"mov z8.b, #16",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.q, q8",
"mov z7.d, z7.d",
"mov z7.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"not p0.b, p7/z, p6.b",
"mov z7.b, p0/m, z1.b",
"add z6.b, z6.b, z7.b",
"add z5.b, z6.b, z5.b",
"tbl z4.b, {z4.b}, z5.b",
@@ -1319,7 +1279,7 @@
]
},
"vpackusdw ymm0, ymm1, ymm2": {
"ExpectedInstructionCount": 23,
"ExpectedInstructionCount": 19,
"Optimal": "No",
"Comment": [
"Map 2 0b01 0x2b 256-bit"
@@ -1333,20 +1293,16 @@
"uzp1 z1.h, z1.h, z1.h",
"movprfx z4, z4",
"splice z4.h, p6, z4.h, z1.h",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[1]",
"mov z5.d, z4.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #0",
"mov z5.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.d, z4.d[2]",
"mov z4.d, z5.d",
"index z0.d, #-2, #1",
"cmpeq p0.d, p7/z, z0.d, #-1",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"udf #0x100",
"mov z16.d, p7/m, z4.d"
]
},
File diff suppressed because it is too large. Load diff
@@ -598,7 +598,7 @@
]
},
"vpsrldq ymm0, ymm1, 15": {
"ExpectedInstructionCount": 14,
"ExpectedInstructionCount": 11,
"Optimal": "No",
"Comment": [
"Map group 14 0b011 256-bit"
@@ -610,13 +610,10 @@
"movprfx z1, z4",
"ext z1.b, z1.b, z5.b, #31",
"mov z4.d, z1.d",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.q, q4",
"mov z4.d, z6.d",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"not p0.b, p7/z, p6.b",
"mov z4.b, p0/m, z1.b",
"mov z16.d, p7/m, z4.d"
]
},
@@ -758,7 +755,7 @@
]
},
"vpslldq ymm0, ymm1, 15": {
"ExpectedInstructionCount": 14,
"ExpectedInstructionCount": 11,
"Optimal": "No",
"Comment": [
"Map group 14 0b111 256-bit"
@@ -770,13 +767,10 @@
"movprfx z1, z5",
"ext z1.b, z1.b, z4.b, #17",
"mov z4.d, z1.d",
"adr x0, #+0x18",
"ldr p0, [x0]",
"mov z1.q, q4",
"mov z4.d, z6.d",
"mov z4.d, p0/m, z1.d",
"b #+0x8",
"unallocated (Unallocated)",
"not p0.b, p7/z, p6.b",
"mov z4.b, p0/m, z1.b",
"mov z16.d, p7/m, z4.d"
]
},