Fixed ImmValue compute

This commit is contained in:
Lander Gallastegi 2025-03-27 01:03:52 +01:00 committed by Lander Gallastegi
parent faf479dcd5
commit b6e9406652
8 changed files with 89 additions and 84 deletions

View File

@ -16,7 +16,7 @@ void CartesianInvokeImpl(Func func, OutputIt out_it,
auto get_tuple = [&]<std::size_t... I>(std::index_sequence<I...>) {
return std::forward_as_tuple(*std::get<I>(arglists_its)...);
};
*out_it++ = std::move(std::apply(func, get_tuple(std::make_index_sequence<N>{})));
out_it = std::move(std::apply(func, get_tuple(std::make_index_sequence<N>{})));
return;
} else {
const auto& arglist = std::get<Level>(arglists_tuple);

View File

@ -43,9 +43,8 @@ static void DoInstructionOperation(Inst* inst, ImmValueList& inst_values, Cache&
#include "shader_recompiler/ir/opcodes.inc"
#undef OPCODE
default:
break;
UNREACHABLE_MSG("Invalid opcode: {}", inst->GetOpcode());
}
UNREACHABLE_MSG("Invalid opcode: {}", inst->GetOpcode());
}
static bool IsSelectInst(Inst* inst) {
@ -69,7 +68,7 @@ void Compute(const Value& value, ImmValueList& values, Cache& cache) {
values.insert(ImmValue(resolved));
return;
}
if (resolved.Type() != Type::Opaque) {
if (resolved.IsImmediate()) {
return;
}
Inst* inst = resolved.InstRecursive();
@ -83,8 +82,7 @@ void Compute(const Value& value, ImmValueList& values, Cache& cache) {
for (size_t i = 0; i < inst->NumArgs(); ++i) {
Compute(inst->Arg(i), inst_values, cache);
}
}
if (IsSelectInst(inst)) {
} else if (IsSelectInst(inst)) {
Compute(inst->Arg(1), inst_values, cache);
Compute(inst->Arg(2), inst_values, cache);
} else {

View File

@ -3,8 +3,8 @@
#pragma once
#include <unordered_map>
#include <unordered_set>
#include <boost/container/flat_map.hpp>
#include "shader_recompiler/ir/compute_value/imm_value.h"
#include "shader_recompiler/ir/value.h"
@ -15,7 +15,7 @@
namespace Shader::IR::ComputeValue {
using ImmValueList = std::unordered_set<ImmValue>;
using Cache = boost::container::flat_map<Inst*, ImmValueList>;
using Cache = std::unordered_map<Inst*, ImmValueList>;
void Compute(const Value& value, ImmValueList& values, Cache& cache);

View File

@ -8,40 +8,40 @@ namespace Shader::IR::ComputeValue {
void DoFPAbs32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Abs<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPAbs64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Abs<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPAdd32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Add<Type::F32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPAdd64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Add<Type::F64, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPSub32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Sub<Type::F32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPFma32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
const ImmValueList& args2) {
Common::CartesianInvoke(ImmValue::Fma<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1,
std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
args2);
}
void DoFPFma64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
const ImmValueList& args2) {
Common::CartesianInvoke(ImmValue::Fma<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1,
std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
args2);
}
@ -56,13 +56,13 @@ void DoFPMax32(ImmValueList& inst_values, const ImmValueList& args0, const ImmVa
}
return ImmValue::Max<Type::F32, true>(a, b);
};
Common::CartesianInvoke(op, std::insert_iterator(inst_values, inst_values.end()), args0, args1,
Common::CartesianInvoke(op, std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
args_legacy);
}
void DoFPMax64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Max<Type::F64, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
@ -76,93 +76,93 @@ void DoFPMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmVa
}
return ImmValue::Min<Type::F32, true>(a, b);
};
Common::CartesianInvoke(op, std::insert_iterator(inst_values, inst_values.end()), args0, args1,
Common::CartesianInvoke(op, std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
args_legacy);
}
void DoFPMin64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Min<Type::F64, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPMul32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Mul<Type::F32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPMul64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Mul<Type::F64, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPDiv32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Div<Type::F32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPDiv64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Div<Type::F64, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoFPNeg32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Neg<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPNeg64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Neg<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPRecip32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Recip<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPRecip64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Recip<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPRecipSqrt32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Rsqrt<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPRecipSqrt64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Rsqrt<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPSqrt(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Sqrt<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPSin(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Sin<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPExp2(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Exp2<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPLdexp(ImmValueList& inst_values, const ImmValueList& args, const ImmValueList& exponents) {
Common::CartesianInvoke(ImmValue::Ldexp<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args, exponents);
std::insert_iterator(inst_values, inst_values.begin()), args, exponents);
}
void DoFPCos(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Cos<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPLog2(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Log2<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPSaturate32(ImmValueList& inst_values, const ImmValueList& args) {
@ -176,63 +176,63 @@ void DoFPSaturate64(ImmValueList& inst_values, const ImmValueList& args) {
void DoFPClamp32(ImmValueList& inst_values, const ImmValueList& args, const ImmValueList& mins,
const ImmValueList& maxs) {
Common::CartesianInvoke(ImmValue::Clamp<Type::F32, true>,
std::insert_iterator(inst_values, inst_values.end()), args, mins, maxs);
std::insert_iterator(inst_values, inst_values.begin()), args, mins, maxs);
}
void DoFPClamp64(ImmValueList& inst_values, const ImmValueList& args, const ImmValueList& mins,
const ImmValueList& maxs) {
Common::CartesianInvoke(ImmValue::Clamp<Type::F64, true>,
std::insert_iterator(inst_values, inst_values.end()), args, mins, maxs);
std::insert_iterator(inst_values, inst_values.begin()), args, mins, maxs);
}
void DoFPRoundEven32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Round<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPRoundEven64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Round<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPFloor32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Floor<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPFloor64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Floor<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPCeil32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Ceil<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPCeil64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Ceil<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPTrunc32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Trunc<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPTrunc64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Trunc<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPFract32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Fract<Type::F32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPFract64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Fract<Type::F64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoFPFrexpSig32(ImmValueList& inst_values, const ImmValueList& args) {

View File

@ -8,12 +8,12 @@ namespace Shader::IR::ComputeValue {
void DoIAdd32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Add<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoIAdd64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Add<Type::U64, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoIAddCary32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
@ -22,22 +22,22 @@ void DoIAddCary32(ImmValueList& inst_values, const ImmValueList& args0, const Im
void DoISub32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Sub<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoISub64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Sub<Type::U64, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoIMul32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Mul<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoIMul64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Mul<Type::U64, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoSMulExt(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
@ -50,103 +50,103 @@ void DoUMulExt(ImmValueList& inst_values, const ImmValueList& args0, const ImmVa
void DoSDiv32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Div<Type::U32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoUDiv32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Div<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoSMod32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Mod<Type::U32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoUMod32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Mod<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoINeg32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Neg<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoINeg64(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Neg<Type::U64>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoIAbs32(ImmValueList& inst_values, const ImmValueList& args) {
Common::CartesianInvoke(ImmValue::Abs<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), args);
std::insert_iterator(inst_values, inst_values.begin()), args);
}
void DoShiftLeftLogical32(ImmValueList& inst_values, const ImmValueList& args,
const ImmValueList& shift) {
Common::CartesianInvoke(ImmValue::LShift<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), args, shift);
std::insert_iterator(inst_values, inst_values.begin()), args, shift);
}
void DoShiftLeftLogical64(ImmValueList& inst_values, const ImmValueList& args,
const ImmValueList& shift) {
Common::CartesianInvoke(ImmValue::LShift<Type::U64>,
std::insert_iterator(inst_values, inst_values.end()), args, shift);
std::insert_iterator(inst_values, inst_values.begin()), args, shift);
}
void DoShiftRightLogical32(ImmValueList& inst_values, const ImmValueList& args,
const ImmValueList& shift) {
Common::CartesianInvoke(ImmValue::RShift<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args, shift);
std::insert_iterator(inst_values, inst_values.begin()), args, shift);
}
void DoShiftRightLogical64(ImmValueList& inst_values, const ImmValueList& args,
const ImmValueList& shift) {
Common::CartesianInvoke(ImmValue::RShift<Type::U64, false>,
std::insert_iterator(inst_values, inst_values.end()), args, shift);
std::insert_iterator(inst_values, inst_values.begin()), args, shift);
}
void DoShiftRightArithmetic32(ImmValueList& inst_values, const ImmValueList& args,
const ImmValueList& shift) {
Common::CartesianInvoke(ImmValue::RShift<Type::U32, true>,
std::insert_iterator(inst_values, inst_values.end()), args, shift);
std::insert_iterator(inst_values, inst_values.begin()), args, shift);
}
void DoShiftRightArithmetic64(ImmValueList& inst_values, const ImmValueList& args,
const ImmValueList& shift) {
Common::CartesianInvoke(ImmValue::RShift<Type::U64, true>,
std::insert_iterator(inst_values, inst_values.end()), args, shift);
std::insert_iterator(inst_values, inst_values.begin()), args, shift);
}
void DoBitwiseAnd32(ImmValueList& inst_values, const ImmValueList& args0,
const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::And<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoBitwiseAnd64(ImmValueList& inst_values, const ImmValueList& args0,
const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::And<Type::U64>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoBitwiseOr32(ImmValueList& inst_values, const ImmValueList& args0,
const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Or<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoBitwiseOr64(ImmValueList& inst_values, const ImmValueList& args0,
const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Or<Type::U64>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoBitwiseXor32(ImmValueList& inst_values, const ImmValueList& args0,
const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Xor<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoBitFieldInsert(ImmValueList& inst_values, const ImmValueList& arg,
@ -179,7 +179,7 @@ void DoBitCount64(ImmValueList& inst_values, const ImmValueList& arg) {
void DoBitwiseNot32(ImmValueList& inst_values, const ImmValueList& arg) {
Common::CartesianInvoke(ImmValue::Not<Type::U32>,
std::insert_iterator(inst_values, inst_values.end()), arg);
std::insert_iterator(inst_values, inst_values.begin()), arg);
}
void DoFindSMsb32(ImmValueList& inst_values, const ImmValueList& arg) {
@ -200,34 +200,34 @@ void DoFindILsb64(ImmValueList& inst_values, const ImmValueList& arg) {
void DoSMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Min<Type::U32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoUMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Min<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoSMax32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Max<Type::U32, true>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoUMax32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
Common::CartesianInvoke(ImmValue::Max<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), args0, args1);
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
}
void DoSClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
const ImmValueList& max) {
Common::CartesianInvoke(ImmValue::Clamp<Type::U32, true>,
std::insert_iterator(inst_values, inst_values.end()), value, min, max);
std::insert_iterator(inst_values, inst_values.begin()), value, min, max);
}
void DoUClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
const ImmValueList& max) {
Common::CartesianInvoke(ImmValue::Clamp<Type::U32, false>,
std::insert_iterator(inst_values, inst_values.end()), value, min, max);
std::insert_iterator(inst_values, inst_values.begin()), value, min, max);
}
} // namespace Shader::IR::ComputeValue

View File

@ -8,22 +8,22 @@ namespace Shader::IR::ComputeValue {
void DoLogicalOr(ImmValueList& inst_values, const ImmValueList& arg1, const ImmValueList& arg2) {
Common::CartesianInvoke(ImmValue::Or<Type::U1>,
std::insert_iterator(inst_values, inst_values.end()), arg1, arg2);
std::insert_iterator(inst_values, inst_values.begin()), arg1, arg2);
}
void DoLogicalAnd(ImmValueList& inst_values, const ImmValueList& arg1, const ImmValueList& arg2) {
Common::CartesianInvoke(ImmValue::And<Type::U1>,
std::insert_iterator(inst_values, inst_values.end()), arg1, arg2);
std::insert_iterator(inst_values, inst_values.begin()), arg1, arg2);
}
void DoLogicalXor(ImmValueList& inst_values, const ImmValueList& arg1, const ImmValueList& arg2) {
Common::CartesianInvoke(ImmValue::Xor<Type::U1>,
std::insert_iterator(inst_values, inst_values.end()), arg1, arg2);
std::insert_iterator(inst_values, inst_values.begin()), arg1, arg2);
}
void DoLogicalNot(ImmValueList& inst_values, const ImmValueList& arg1) {
Common::CartesianInvoke(ImmValue::Not<Type::U1>,
std::insert_iterator(inst_values, inst_values.end()), arg1);
std::insert_iterator(inst_values, inst_values.begin()), arg1);
}
} // namespace Shader::IR::ComputeValue

View File

@ -7,6 +7,7 @@
namespace Shader::IR::ComputeValue {
ImmValue::ImmValue(const IR::Value& value) noexcept {
ASSERT(value.IsImmediate());
switch (value.Type()) {
case Type::U1:
imm_values[0].imm_u1 = value.U1();
@ -1223,6 +1224,9 @@ bool ImmValue::IsNan<Type::F64>(const ImmValue& in) noexcept {
}
bool ImmValue::IsSupportedValue(const IR::Value& value) noexcept {
if (!value.IsImmediate()) {
return false;
}
switch (value.Type()) {
case IR::Type::U1:
case IR::Type::U8:

View File

@ -50,8 +50,11 @@ u64 GetNumExecutions(const Inst* inst) {
std::insert_iterator(distances, distances.end()), cond_arg0,
cond_arg1);
}
num_executions *=
std::max<u64>(1, *std::max_element(distances.begin(), distances.end()));
if (!distances.empty()) {
// We assume that the iterator changes by 1 each loop iteration.
num_executions *=
std::max<u64>(1, *std::max_element(distances.begin(), distances.end())) + 1;
}
}
cond_data = cond_data->parent;
}