Skip to content

Commit

Permalink
LLVM: Allow swapped FMA and multiplications args in match context
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Feb 6, 2024
1 parent 85f4c38 commit 736623d
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
54 changes: 54 additions & 0 deletions rpcs3/Emu/CPU/CPUTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,15 @@ struct llvm_mul
return std::tuple_cat(r1, r2);
}
}

// Argument order does not matter here, try when swapped
if (auto r1 = a1.match(v2, _m); v2)
{
if (auto r2 = a2.match(v1, _m); v1)
{
return std::tuple_cat(r1, r2);
}
}
}

value = nullptr;
Expand Down Expand Up @@ -2868,6 +2877,18 @@ struct llvm_fmuladd
}
}
}

// With multiplication args swapped
if (auto r1 = a1.match(v2, _m); v2)
{
if (auto r2 = a2.match(v1, _m); v1)
{
if (auto r3 = a3.match(v3, _m); v3)
{
return std::tuple_cat(r1, r2, r3);
}
}
}
}

value = nullptr;
Expand All @@ -2884,6 +2905,18 @@ struct llvm_calli

std::tuple<llvm_expr_t<A>...> a;

std::array<usz, sizeof...(A)> order_equality_hint = []()
{
std::array<usz, sizeof...(A)> r{};

for (usz i = 0; i < r.size(); i++)
{
r[i] = i;
}

return r;
}();

llvm::Value*(*c)(llvm::Value**, llvm::IRBuilder<>*){};

llvm::Value* eval(llvm::IRBuilder<>* ir) const
Expand Down Expand Up @@ -2917,6 +2950,13 @@ struct llvm_calli
return *this;
}

template <typename... Args>
llvm_calli& set_order_equality_hint(Args... args)
{
order_equality_hint = {args...};
return *this;
}

llvm_match_tuple<A...> match(llvm::Value*& value, llvm::Module* _m) const
{
return match(value, _m, std::make_index_sequence<sizeof...(A)>());
Expand All @@ -2939,6 +2979,20 @@ struct llvm_calli
{
return std::tuple_cat(std::get<I>(r)...);
}

if costexpr (sizeof...(A) >= 2)
{
if (order_equality_hint[0] == order_equality_hint[1])
{
// Test if it works with the first pair swapped
((v[I <= 1 ? I ^ 1 : I] = i->getOperand(I)), ...);

if (((std::get<I>(r) = std::get<I>(a).match(v[I], _m), v[I]) && ...))
{
return std::tuple_cat(std::get<I <= 1 ? I ^ 1 : I>(r)...);
}
}
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions rpcs3/Emu/Cell/SPULLVMRecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5582,7 +5582,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
template <typename T, typename U>
static llvm_calli<f32[4], T, U> fm(T&& a, U&& b)
{
return {"spu_fm", {std::forward<T>(a), std::forward<U>(b)}};
return llvm_calli<f32[4], T, U>{"spu_fm", {std::forward<T>(a), std::forward<U>(b)}}.set_order_equality_hint(1, 1);
}

void FM(spu_opcode_t op)
Expand Down Expand Up @@ -5912,7 +5912,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
template <typename T, typename U, typename V>
static llvm_calli<f32[4], T, U, V> fnms(T&& a, U&& b, V&& c)
{
return {"spu_fnms", {std::forward<T>(a), std::forward<U>(b), std::forward<V>(c)}};
return llvm_calli<f32[4], T, U, V>{"spu_fnms", {std::forward<T>(a), std::forward<U>(b), std::forward<V>(c)}}.set_order_equality_hint(1, 1, 0);
}

void FNMS(spu_opcode_t op)
Expand Down Expand Up @@ -5947,7 +5947,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
template <typename T, typename U, typename V>
static llvm_calli<f32[4], T, U, V> fma(T&& a, U&& b, V&& c)
{
return {"spu_fma", {std::forward<T>(a), std::forward<U>(b), std::forward<V>(c)}};
return llvm_calli<f32[4], T, U, V>{"spu_fma", {std::forward<T>(a), std::forward<U>(b), std::forward<V>(c)}}.set_order_equality_hint(1, 1, 0);
}

void FMA(spu_opcode_t op)
Expand Down Expand Up @@ -6021,7 +6021,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
template <typename T, typename U, typename V>
static llvm_calli<f32[4], T, U, V> fms(T&& a, U&& b, V&& c)
{
return {"spu_fms", {std::forward<T>(a), std::forward<U>(b), std::forward<V>(c)}};
return llvm_calli<f32[4], T, U, V>{"spu_fms", {std::forward<T>(a), std::forward<U>(b), std::forward<V>(c)}}.set_order_equality_hint(1, 1, 0);
}

void FMS(spu_opcode_t op)
Expand Down

0 comments on commit 736623d

Please sign in to comment.