From 320e8d634ae0a0dc0917e9483d12e5156c655160 Mon Sep 17 00:00:00 2001 From: Malcolm Date: Tue, 12 May 2026 22:43:04 -0400 Subject: [PATCH] SPU LLVM: Workaround bad LLVM codegen for FCGT on AARCH64 - LLVM was emitting a nasty sequence for select instead of just using BSL, so let's try using inline assembly. --- rpcs3/Emu/Cell/SPULLVMRecompiler.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 927d7ac187..848129fa20 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -7205,7 +7205,22 @@ public: const auto ai = eval(bitcast(a)); const auto bi = eval(bitcast(b)); +// Awful workaround to some awful LLVM codegen via inline assembly +// Once it is solved upstream we should remove it - Whatcookie +// https://github.com/llvm/llvm-project/issues/197360 +#if defined(ARCH_ARM64) + const auto select_bsl = [&](auto mask, auto t, auto f) + { + const auto asm_type = llvm::FunctionType::get(get_type(), {get_type(), get_type(), get_type()}, false); + const auto bsl_asm = llvm::InlineAsm::get(asm_type, "bsl $0.16b, $1.16b, $2.16b", "=w,w,w,0", false); + + return value(m_ir->CreateCall(asm_type, bsl_asm, {eval(sext(t)).value, eval(sext(f)).value, eval(sext(mask)).value})); + }; + + return eval(sext(fcmp_uno(a != b)) & select_bsl((ai & bi) >= 0, ai > bi, ai < bi)); +#else return eval(sext(fcmp_uno(a != b) & select((ai & bi) >= 0, ai > bi, ai < bi))); +#endif }; set_vr(op.rt, fcgt(get_vr(op.ra), get_vr(op.rb)));