From 304dba5f201bf782d76e21910c4b9fc1044ffbde Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 12 Sep 2023 16:10:39 -0700 Subject: [PATCH 1/2] OpcodeDispatcher: Optimize NOP vector move Move instruction to itself here is a nop. Need to be careful about AVX operations which use a different handler since those might actually zero the upper bits on 128-bit move --- FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 57fabfb49..7e971f989 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -24,6 +24,11 @@ namespace FEXCore::IR { #define OpcodeArgs [[maybe_unused]] FEXCore::X86Tables::DecodedOp Op void OpDispatchBuilder::MOVVectorOp(OpcodeArgs) { + if (Op->Dest.IsGPR() && Op->Src[0].IsGPR() && + Op->Dest.Data.GPR.GPR == Op->Src[0].Data.GPR.GPR) { + // Nop + return; + } OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, 1); StoreResult(FPRClass, Op, Src, 1); } From 8a44be0c30302c5c3ba0b7d6c115a5c709f15884 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 12 Sep 2023 16:11:43 -0700 Subject: [PATCH 2/2] InstCountCI: Update for NOP vector moves Adds a couple of instructions that get tested in this code path. --- unittests/InstructionCountCI/DDD.json | 27 ++++------ .../InstructionCountCI/Secondary_OpSize.json | 6 +++ unittests/InstructionCountCI/VEX_map1.json | 50 +++++++++++++++++++ 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/unittests/InstructionCountCI/DDD.json b/unittests/InstructionCountCI/DDD.json index fe91498e6..d7aa62753 100644 --- a/unittests/InstructionCountCI/DDD.json +++ b/unittests/InstructionCountCI/DDD.json @@ -240,13 +240,10 @@ ] }, "pfrcpit1 mm0, mm0": { - "ExpectedInstructionCount": 2, - "Optimal": "No", + "ExpectedInstructionCount": 0, + "Optimal": "Yes", "Comment": "0x0f 0x0f 0xa6", - "ExpectedArm64ASM": [ - "ldr d2, [x28, #752]", - "str d2, [x28, #752]" - ] + "ExpectedArm64ASM": [] }, "pfrsqit1 mm0, mm1": { "ExpectedInstructionCount": 2, @@ -258,13 +255,10 @@ ] }, "pfrsqit1 mm0, mm0": { - "ExpectedInstructionCount": 2, - "Optimal": "No", + "ExpectedInstructionCount": 0, + "Optimal": "Yes", "Comment": "0x0f 0x0f 0xa7", - "ExpectedArm64ASM": [ - "ldr d2, [x28, #752]", - "str d2, [x28, #752]" - ] + "ExpectedArm64ASM": [] }, "pfsubr mm0, mm1": { "ExpectedInstructionCount": 4, @@ -309,13 +303,10 @@ ] }, "pfrcpit2 mm0, mm0": { - "ExpectedInstructionCount": 2, - "Optimal": "No", + "ExpectedInstructionCount": 0, + "Optimal": "Yes", "Comment": "0x0f 0x0f 0xb6", - "ExpectedArm64ASM": [ - "ldr d2, [x28, #752]", - "str d2, [x28, #752]" - ] + "ExpectedArm64ASM": [] }, "db 0x0f, 0x0f, 0xc1, 0xb7": { "ExpectedInstructionCount": 8, diff --git a/unittests/InstructionCountCI/Secondary_OpSize.json b/unittests/InstructionCountCI/Secondary_OpSize.json index 2cb6cbc65..d276bddf1 100644 --- a/unittests/InstructionCountCI/Secondary_OpSize.json +++ b/unittests/InstructionCountCI/Secondary_OpSize.json @@ -9,6 +9,12 @@ ] }, "Instructions": { + "movupd xmm0, xmm0": { + "ExpectedInstructionCount": 0, + "Optimal": "Yes", + "Comment": "0x66 0x0f 0x10", + "ExpectedArm64ASM": [] + }, "movupd xmm0, xmm1": { "ExpectedInstructionCount": 1, "Optimal": "Yes", diff --git a/unittests/InstructionCountCI/VEX_map1.json b/unittests/InstructionCountCI/VEX_map1.json index ff4a963a7..fc71252e9 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -10,6 +10,19 @@ ] }, "Instructions": { + "vmovups xmm0, xmm0": { + "ExpectedInstructionCount": 3, + "Optimal": "No", + "Comment": [ + "Spurious moves", + "Map 1 0b00 0x10 128-bit" + ], + "ExpectedArm64ASM": [ + "mov z2.d, p7/m, z16.d", + "mov v2.16b, v2.16b", + "mov z16.d, p7/m, z2.d" + ] + }, "vmovups xmm0, [rax]": { "ExpectedInstructionCount": 2, "Optimal": "No", @@ -23,6 +36,18 @@ "mov z16.d, p7/m, z2.d" ] }, + "vmovups ymm0, ymm0": { + "ExpectedInstructionCount": 2, + "Optimal": "No", + "Comment": [ + "Spurious moves", + "Map 1 0b00 0x10 256-bit" + ], + "ExpectedArm64ASM": [ + "mov z2.d, p7/m, z16.d", + "mov z16.d, p7/m, z2.d" + ] + }, "vmovups ymm0, [rax]": { "ExpectedInstructionCount": 2, "Optimal": "No", @@ -35,6 +60,19 @@ "mov z16.d, p7/m, z2.d" ] }, + "vmovupd xmm0, xmm0": { + "ExpectedInstructionCount": 3, + "Optimal": "No", + "Comment": [ + "Spurious moves", + "Map 1 0b01 0x10 128-bit" + ], + "ExpectedArm64ASM": [ + "mov z2.d, p7/m, z16.d", + "mov v2.16b, v2.16b", + "mov z16.d, p7/m, z2.d" + ] + }, "vmovupd xmm0, [rax]": { "ExpectedInstructionCount": 2, "Optimal": "No", @@ -48,6 +86,18 @@ "mov z16.d, p7/m, z2.d" ] }, + "vmovupd ymm0, ymm0": { + "ExpectedInstructionCount": 2, + "Optimal": "No", + "Comment": [ + "Spurious moves", + "Map 1 0b01 0x10 256-bit" + ], + "ExpectedArm64ASM": [ + "mov z2.d, p7/m, z16.d", + "mov z16.d, p7/m, z2.d" + ] + }, "vmovupd ymm0, [rax]": { "ExpectedInstructionCount": 2, "Optimal": "No",