Fix array addressing of emulated vector types. operator[] on a pointer was using the vector register size (16 bytes) instead of the size of the (emulated) vector type. Change-Id: Ice8677b41a3af81176fe9495fd02ede9f8b0482f Reviewed-on: https://swiftshader-review.googlesource.com/8569 Tested-by: Nicolas Capens <capn@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp index 3187777..7ba4e50 100644 --- a/src/Reactor/SubzeroReactor.cpp +++ b/src/Reactor/SubzeroReactor.cpp
@@ -140,6 +140,25 @@ return reinterpret_cast<BasicBlock*>(b); } + static size_t typeSize(Type *type) + { + if(reinterpret_cast<std::intptr_t>(type) & EmulatedBits) + { + switch(reinterpret_cast<std::intptr_t>(type)) + { + case Type_v2i32: return 8; + case Type_v4i16: return 8; + case Type_v2i16: return 4; + case Type_v8i8: return 8; + case Type_v4i8: return 4; + case Type_v2f32: return 8; + default: assert(false); + } + } + + return Ice::typeWidthInBytes(T(type)); + } + Optimization optimization[10] = {InstructionCombining, Disabled}; using ElfHeader = std::conditional<sizeof(void*) == 8, Elf64_Ehdr, Elf32_Ehdr>::type; @@ -744,34 +763,12 @@ if(valueType & EmulatedBits) { - switch(valueType) - { - case Type_v4i8: - case Type_v2i16: - { - const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; - auto target = ::context->getConstantUndef(Ice::IceType_i32); - auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic); - load->addArg(ptr); - load->addArg(::context->getConstantInt32(4)); - ::basicBlock->appendInst(load); - } - break; - case Type_v2i32: - case Type_v8i8: - case Type_v4i16: - case Type_v2f32: - { - const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; - auto target = ::context->getConstantUndef(Ice::IceType_i32); - auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic); - load->addArg(ptr); - load->addArg(::context->getConstantInt32(8)); - ::basicBlock->appendInst(load); - } - break; - default: assert(false && "UNIMPLEMENTED"); - } + const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F}; + auto target = ::context->getConstantUndef(Ice::IceType_i32); + auto load = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic); + load->addArg(ptr); + load->addArg(::context->getConstantInt32(typeSize(type))); + ::basicBlock->appendInst(load); } else { @@ -788,36 +785,13 @@ if(valueType & EmulatedBits) { - switch(valueType) - { - case Type_v4i8: - case Type_v2i16: - { - const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T}; - auto target = ::context->getConstantUndef(Ice::IceType_i32); - auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic); - store->addArg(value); - store->addArg(ptr); - store->addArg(::context->getConstantInt32(4)); - ::basicBlock->appendInst(store); - } - break; - case Type_v2i32: - case Type_v8i8: - case Type_v4i16: - case Type_v2f32: - { - const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T}; - auto target = ::context->getConstantUndef(Ice::IceType_i32); - auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic); - store->addArg(value); - store->addArg(ptr); - store->addArg(::context->getConstantInt32(8)); - ::basicBlock->appendInst(store); - } - break; - default: assert(false && "UNIMPLEMENTED"); - } + const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T}; + auto target = ::context->getConstantUndef(Ice::IceType_i32); + auto store = Ice::InstIntrinsicCall::create(::function, 3, nullptr, target, intrinsic); + store->addArg(value); + store->addArg(ptr); + store->addArg(::context->getConstantInt32(typeSize(type))); + ::basicBlock->appendInst(store); } else { @@ -836,7 +810,7 @@ if(auto *constant = llvm::dyn_cast<Ice::ConstantInteger32>(index)) { - int32_t offset = constant->getValue() * (int)Ice::typeWidthInBytes(T(type)); + int32_t offset = constant->getValue() * (int)typeSize(type); if(offset == 0) { @@ -848,7 +822,7 @@ if(!Ice::isByteSizedType(T(type))) { - index = createMul(index, createConstantInt((int)Ice::typeWidthInBytes(T(type)))); + index = createMul(index, createConstantInt((int)typeSize(type))); } if(sizeof(void*) == 8)