PPU LLVM: Fix constant folding of BitCast

This commit is contained in:
Eladash 2020-07-29 23:13:41 +03:00 committed by Ani
parent f6764767f6
commit dd497625a5
1 changed files with 25 additions and 23 deletions

View File

@ -129,9 +129,8 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* _module, const ppu_mo
m_reloc = &m_info.segs[0]; m_reloc = &m_info.segs[0];
} }
const auto nan_u32 = ConstantInt::get(get_type<u32>(), 0x7FC00000u); const auto nan_v = v128::from32p(0x7FC00000u);
const auto nan_f32 = ConstantExpr::getBitCast(nan_u32, get_type<f32>()); nan_vec4 = make_const_vector(nan_v, get_type<f32[4]>());
nan_vec4 = ConstantVector::getSplat(4, nan_f32);
} }
PPUTranslator::~PPUTranslator() PPUTranslator::~PPUTranslator()
@ -236,13 +235,13 @@ Value* PPUTranslator::VecHandleNan(Value* val)
Value* PPUTranslator::VecHandleDenormal(Value* val) Value* PPUTranslator::VecHandleDenormal(Value* val)
{ {
const auto type = val->getType(); const auto type = val->getType();
const auto value = type == GetType<u32[4]>() ? val : m_ir->CreateBitCast(val, GetType<u32[4]>()); const auto value = bitcast(val, GetType<u32[4]>());
const auto mask = SExt(m_ir->CreateICmpEQ(m_ir->CreateAnd(value, Broadcast(RegLoad(m_jm_mask), 4)), ConstantVector::getSplat(4, m_ir->getInt32(0))), GetType<s32[4]>()); const auto mask = SExt(m_ir->CreateICmpEQ(m_ir->CreateAnd(value, Broadcast(RegLoad(m_jm_mask), 4)), ConstantVector::getSplat(4, m_ir->getInt32(0))), GetType<s32[4]>());
const auto nz = m_ir->CreateLShr(mask, 1); const auto nz = m_ir->CreateLShr(mask, 1);
const auto result = m_ir->CreateAnd(m_ir->CreateNot(nz), value); const auto result = m_ir->CreateAnd(m_ir->CreateNot(nz), value);
return type == GetType<u32[4]>() ? result : m_ir->CreateBitCast(result, type); return bitcast(result, type);
} }
Value* PPUTranslator::VecHandleResult(Value* val) Value* PPUTranslator::VecHandleResult(Value* val)
@ -398,7 +397,7 @@ void PPUTranslator::FlushRegisters()
m_ir->SetInsertPoint(block); m_ir->SetInsertPoint(block);
} }
m_ir->CreateStore(local, m_ir->CreateBitCast(m_globals[index], local->getType()->getPointerTo())); m_ir->CreateStore(local, bitcast(m_globals[index], local->getType()->getPointerTo()));
m_globals[index] = nullptr; m_globals[index] = nullptr;
} }
} }
@ -414,20 +413,20 @@ Value* PPUTranslator::Solid(Value* value)
if (value->getType() == GetType<bool[4]>()) if (value->getType() == GetType<bool[4]>())
{ {
return m_ir->CreateBitCast(SExt(value, GetType<u32[4]>()), m_ir->getIntNTy(128)); return bitcast(SExt(value, GetType<u32[4]>()), m_ir->getIntNTy(128));
} }
if (value->getType() == GetType<bool[8]>()) if (value->getType() == GetType<bool[8]>())
{ {
return m_ir->CreateBitCast(SExt(value, GetType<u16[8]>()), m_ir->getIntNTy(128)); return bitcast(SExt(value, GetType<u16[8]>()), m_ir->getIntNTy(128));
} }
if (value->getType() == GetType<bool[16]>()) if (value->getType() == GetType<bool[16]>())
{ {
return m_ir->CreateBitCast(SExt(value, GetType<u8[16]>()), m_ir->getIntNTy(128)); return bitcast(SExt(value, GetType<u8[16]>()), m_ir->getIntNTy(128));
} }
return m_ir->CreateBitCast(value, m_ir->getIntNTy(size)); return bitcast(value, m_ir->getIntNTy(size));
} }
Value* PPUTranslator::IsZero(Value* value) Value* PPUTranslator::IsZero(Value* value)
@ -580,7 +579,7 @@ void PPUTranslator::UseCondition(MDNode* hint, Value* cond)
llvm::Value* PPUTranslator::GetMemory(llvm::Value* addr, llvm::Type* type) llvm::Value* PPUTranslator::GetMemory(llvm::Value* addr, llvm::Type* type)
{ {
return m_ir->CreateBitCast(m_ir->CreateGEP(m_base_loaded, {m_ir->getInt64(0), addr}), type->getPointerTo()); return bitcast(m_ir->CreateGEP(m_base_loaded, {m_ir->getInt64(0), addr}), type->getPointerTo());
} }
Value* PPUTranslator::ReadMemory(Value* addr, Type* type, bool is_be, u32 align) Value* PPUTranslator::ReadMemory(Value* addr, Type* type, bool is_be, u32 align)
@ -592,7 +591,7 @@ Value* PPUTranslator::ReadMemory(Value* addr, Type* type, bool is_be, u32 align)
// Read, byteswap, bitcast // Read, byteswap, bitcast
const auto int_type = m_ir->getIntNTy(size); const auto int_type = m_ir->getIntNTy(size);
const auto value = m_ir->CreateAlignedLoad(GetMemory(addr, int_type), llvm::MaybeAlign{align}, true); const auto value = m_ir->CreateAlignedLoad(GetMemory(addr, int_type), llvm::MaybeAlign{align}, true);
return m_ir->CreateBitCast(Call(int_type, fmt::format("llvm.bswap.i%u", size), value), type); return bitcast(Call(int_type, fmt::format("llvm.bswap.i%u", size), value), type);
} }
// Read normally // Read normally
@ -608,7 +607,7 @@ void PPUTranslator::WriteMemory(Value* addr, Value* value, bool is_be, u32 align
{ {
// Bitcast, byteswap // Bitcast, byteswap
const auto int_type = m_ir->getIntNTy(size); const auto int_type = m_ir->getIntNTy(size);
value = Call(int_type, fmt::format("llvm.bswap.i%u", size), m_ir->CreateBitCast(value, int_type)); value = Call(int_type, fmt::format("llvm.bswap.i%u", size), bitcast(value, int_type));
} }
// Write // Write
@ -2771,7 +2770,7 @@ void PPUTranslator::MTOCRF(ppu_opcode_t op)
const auto index = m_ir->CreateAnd(m_ir->CreateLShr(value, 28 - i * 4), 15); const auto index = m_ir->CreateAnd(m_ir->CreateLShr(value, 28 - i * 4), 15);
const auto src = m_ir->CreateGEP(m_mtocr_table, {m_ir->getInt32(0), m_ir->CreateShl(index, 2)}); const auto src = m_ir->CreateGEP(m_mtocr_table, {m_ir->getInt32(0), m_ir->CreateShl(index, 2)});
const auto dst = m_ir->CreateBitCast(m_ir->CreateStructGEP(nullptr, m_thread, static_cast<uint>(m_cr - m_locals) + i * 4), GetType<u8*>()); const auto dst = bitcast(m_ir->CreateStructGEP(nullptr, m_thread, static_cast<uint>(m_cr - m_locals) + i * 4), GetType<u8*>());
Call(GetType<void>(), "llvm.memcpy.p0i8.p0i8.i32", dst, src, m_ir->getInt32(4), m_ir->getFalse()); Call(GetType<void>(), "llvm.memcpy.p0i8.p0i8.i32", dst, src, m_ir->getInt32(4), m_ir->getFalse());
} }
} }
@ -4553,15 +4552,15 @@ Value* PPUTranslator::GetFpr(u32 r, u32 bits, bool as_int)
} }
else else
{ {
return Trunc(m_ir->CreateBitCast(value, GetType<u64>()), m_ir->getIntNTy(bits)); return Trunc(bitcast(value, GetType<u64>()), m_ir->getIntNTy(bits));
} }
} }
void PPUTranslator::SetFpr(u32 r, Value* val) void PPUTranslator::SetFpr(u32 r, Value* val)
{ {
const auto f64_val = const auto f64_val =
val->getType() == GetType<s32>() ? m_ir->CreateBitCast(SExt(val), GetType<f64>()) : val->getType() == GetType<s32>() ? bitcast(SExt(val), GetType<f64>()) :
val->getType() == GetType<s64>() ? m_ir->CreateBitCast(val, GetType<f64>()) : val->getType() == GetType<s64>() ? bitcast(val, GetType<f64>()) :
val->getType() == GetType<f32>() ? m_ir->CreateFPExt(val, GetType<f64>()) : val; val->getType() == GetType<f32>() ? m_ir->CreateFPExt(val, GetType<f64>()) : val;
RegStore(f64_val, m_fpr[r]); RegStore(f64_val, m_fpr[r]);
@ -4571,16 +4570,19 @@ Value* PPUTranslator::GetVr(u32 vr, VrType type)
{ {
const auto value = RegLoad(m_vr[vr]); const auto value = RegLoad(m_vr[vr]);
llvm::Type* _type{};
switch (type) switch (type)
{ {
case VrType::vi32: return m_ir->CreateBitCast(value, GetType<u32[4]>()); case VrType::vi32: _type = GetType<u32[4]>(); break;
case VrType::vi8: return m_ir->CreateBitCast(value, GetType<u8[16]>()); case VrType::vi8 : _type = GetType<u8[16]>(); break;
case VrType::vi16: return m_ir->CreateBitCast(value, GetType<u16[8]>()); case VrType::vi16: _type = GetType<u16[8]>(); break;
case VrType::vf: return m_ir->CreateBitCast(value, GetType<f32[4]>()); case VrType::vf : _type = GetType<f32[4]>(); break;
case VrType::i128: return m_ir->CreateBitCast(value, GetType<u128>()); case VrType::i128: _type = GetType<u128>(); break;
default: report_fatal_error("GetVr(): invalid type");
} }
report_fatal_error("GetVr(): invalid type"); return bitcast(value, _type);
} }
void PPUTranslator::SetVr(u32 vr, Value* value) void PPUTranslator::SetVr(u32 vr, Value* value)