Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: src/IceInstARM32.cpp

Issue 1876083004: Subzero. ARM32. Fixes Insert/Extract v(8|16)i1 bug. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fixes lit. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/select-vec.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceInstARM32.cpp
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index 92a57e01d5ee0ade69a989f8b58d570fd646620e..718360f5076b556858117c00f53a341b621e716d 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -1108,8 +1108,27 @@ Register getDRegister(const Variable *Src, uint32_t Index) {
}
}
-constexpr uint32_t getDIndex(uint32_t NumElements, uint32_t Index) {
- return (Index < NumElements / 2) ? Index : Index - (NumElements / 2);
+uint32_t adjustDIndex(Type Ty, uint32_t DIndex) {
+ // If Ty is a vector of i1, we may need to adjust DIndex. This is needed
+ // because, e.g., the second i1 in a v4i1 is accessed with a
+ //
+ // vmov.s8 Qd[4], Rn
+ switch (Ty) {
+ case IceType_v4i1:
+ return DIndex * 4;
+ case IceType_v8i1:
+ return DIndex * 2;
+ case IceType_v16i1:
+ return DIndex;
+ default:
+ return DIndex;
+ }
+}
+
+uint32_t getDIndex(Type Ty, uint32_t NumElements, uint32_t Index) {
+ const uint32_t DIndex =
+ (Index < NumElements / 2) ? Index : Index - (NumElements / 2);
+ return adjustDIndex(Ty, DIndex);
}
// For floating point values, we can insertelement or extractelement by moving
@@ -1152,12 +1171,13 @@ void InstARM32Extract::emit(const Cfg *Func) const {
getDest()->emit(Func);
Str << ", ";
- const size_t VectorSize = typeNumElements(Src->getType());
+ const Type SrcTy = Src->getType();
+ const size_t VectorSize = typeNumElements(SrcTy);
const Register SrcReg = getDRegister(Src, Index);
Str << RegARM32::RegTable[SrcReg].Name;
- Str << "[" << getDIndex(VectorSize, Index) << "]";
+ Str << "[" << getDIndex(SrcTy, VectorSize, Index) << "]";
} else if (isFloatingType(DestTy)) {
const Register SrcReg = getSRegister(Src, Index);
@@ -1175,11 +1195,12 @@ void InstARM32Extract::emitIAS(const Cfg *Func) const {
const Operand *Dest = getDest();
const Type DestTy = Dest->getType();
const Operand *Src = getSrc(0);
+ const Type SrcTy = Src->getType();
assert(isVectorType(Src->getType()));
assert(DestTy == typeElementType(Src->getType()));
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (isIntegerType(DestTy)) {
- Asm->vmovrqi(Dest, Src, Index, getPredicate());
+ Asm->vmovrqi(Dest, Src, adjustDIndex(SrcTy, Index), getPredicate());
assert(!Asm->needsTextFixup());
return;
}
@@ -1188,12 +1209,28 @@ void InstARM32Extract::emitIAS(const Cfg *Func) const {
assert(!Asm->needsTextFixup());
}
+namespace {
+Type insertionType(Type Ty) {
+ assert(isVectorType(Ty));
+ switch (Ty) {
+ case IceType_v4i1:
+ return IceType_v4i32;
+ case IceType_v8i1:
+ return IceType_v8i16;
+ case IceType_v16i1:
+ return IceType_v16i8;
+ default:
+ return Ty;
+ }
+}
+} // end of anonymous namespace
+
void InstARM32Insert::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
const Variable *Dest = getDest();
- const Type DestTy = getDest()->getType();
-
const auto *Src = llvm::cast<Variable>(getSrc(0));
+ const Type DestTy = insertionType(getDest()->getType());
+ assert(isVectorType(DestTy));
if (isIntegerType(DestTy)) {
Str << "\t"
@@ -1203,7 +1240,8 @@ void InstARM32Insert::emit(const Cfg *Func) const {
const size_t VectorSize = typeNumElements(DestTy);
const Register DestReg = getDRegister(Dest, Index);
- const uint32_t Index = getDIndex(VectorSize, this->Index);
+ const uint32_t Index =
+ getDIndex(insertionType(DestTy), VectorSize, this->Index);
Str << RegARM32::RegTable[DestReg].Name;
Str << "[" << Index << "], ";
Src->emit(Func);
@@ -1221,14 +1259,16 @@ void InstARM32Insert::emit(const Cfg *Func) const {
void InstARM32Insert::emitIAS(const Cfg *Func) const {
const Variable *Dest = getDest();
- const Operand *Src = getSrc(0);
- const Type SrcTy = Src->getType();
- assert(isVectorType(Dest->getType()));
- assert(typeElementType(Dest->getType()) == SrcTy);
+ const auto *Src = llvm::cast<Variable>(getSrc(0));
+ const Type DestTy = insertionType(Dest->getType());
+ const Type SrcTy = typeElementType(DestTy);
+ assert(SrcTy == Src->getType() || Src->getType() == IceType_i1);
+ assert(isVectorType(DestTy));
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (isIntegerType(SrcTy)) {
- const Operand *Src = getSrc(0);
- Asm->vmovqir(Dest, Index, Src, getPredicate());
+ Asm->vmovqir(Dest->asType(Func, DestTy, Dest->getRegNum()),
+ adjustDIndex(DestTy, Index),
+ Src->asType(Func, SrcTy, Src->getRegNum()), getPredicate());
Eric Holk 2016/04/11 17:34:57 Are we guaranteed that Src has a registers at this
John 2016/04/11 18:23:23 yes
assert(!Asm->needsTextFixup());
return;
}
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/select-vec.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698