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

Unified Diff: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp

Issue 321733002: PNaCl SIMD: allow element-aligned vector load/store (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Rebase. Created 6 years, 6 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
Index: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
index 24d43f9ad6506be9d9e850bf2e4d98613a8870dd..986c6094699e289765b5197b9ca08686fb400d34 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
@@ -56,11 +56,14 @@ class PNaClABIVerifyFunctions : public FunctionPass {
AtomicIntrinsics.reset(new NaCl::AtomicIntrinsics(M.getContext()));
return false;
}
+ virtual void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.addRequired<DataLayout>();
jvoung (off chromium) 2014/06/10 16:28:32 Should probably also setPreservesAll() ?
JF 2014/06/10 18:26:29 Done.
+ }
bool runOnFunction(Function &F);
virtual void print(raw_ostream &O, const Module *M) const;
private:
bool IsWhitelistedMetadata(unsigned MDKind);
- const char *checkInstruction(const Instruction *Inst);
+ const char *checkInstruction(const DataLayout *DL, const Instruction *Inst);
PNaClABIErrorReporter *Reporter;
bool ReporterIsOwned;
OwningPtr<NaCl::AtomicIntrinsics> AtomicIntrinsics;
@@ -88,14 +91,12 @@ bool PNaClABIVerifyFunctions::IsWhitelistedMetadata(unsigned MDKind) {
// A valid pointer type is either:
// * a pointer to a valid PNaCl scalar type (except i1), or
+// * a pointer to a valid PNaCl vector type (except i1), or
// * a function pointer (with valid argument and return types).
//
// i1 is disallowed so that all loads and stores are a whole number of
// bytes, and so that we do not need to define whether a store of i1
// zero-extends.
-//
-// Vector pointer types aren't currently allowed because vector memory
-// accesses go through their scalar elements.
static bool isValidPointerType(Type *Ty) {
if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) {
if (PtrTy->getAddressSpace() != 0)
@@ -103,6 +104,9 @@ static bool isValidPointerType(Type *Ty) {
Type *EltTy = PtrTy->getElementType();
if (PNaClABITypeChecker::isValidScalarType(EltTy) && !EltTy->isIntegerTy(1))
return true;
+ if (PNaClABITypeChecker::isValidVectorType(EltTy) &&
+ !cast<VectorType>(EltTy)->getElementType()->isIntegerTy(1))
+ return true;
if (FunctionType *FTy = dyn_cast<FunctionType>(EltTy))
return PNaClABITypeChecker::isValidFunctionType(FTy);
}
@@ -166,23 +170,32 @@ static bool isValidVectorOperand(const Value *Val) {
isa<UndefValue>(Val);
}
-static bool isAllowedAlignment(unsigned Alignment, Type *Ty) {
- // Non-atomic integer operations must always use "align 1", since we
- // do not want the backend to generate code with non-portable
- // undefined behaviour (such as misaligned access faults) if user
- // code specifies "align 4" but uses a misaligned pointer. As a
- // concession to performance, we allow larger alignment values for
- // floating point types.
+static bool isAllowedAlignment(const DataLayout *DL, uint64_t Alignment,
+ Type *Ty) {
+ // Non-atomic integer operations must always use "align 1", since we do not
+ // want the backend to generate code with non-portable undefined behaviour
+ // (such as misaligned access faults) if user code specifies "align 4" but
+ // uses a misaligned pointer. As a concession to performance, we allow larger
+ // alignment values for floating point types, and we only allow vectors to be
+ // aligned by their element's size.
//
- // To reduce the set of alignment values that need to be encoded in
- // pexes, we disallow other alignment values. We require alignments
- // to be explicit by disallowing Alignment == 0.
+ // TODO(jfb) Allow vectors to be marked as align == 1. This requires proper
+ // testing on each supported ISA, and is probably not as common as
+ // align == elemsize.
//
- // Vector memory accesses go through their scalar elements, there is
- // therefore no such thing as vector alignment.
- return Alignment == 1 ||
- (Ty->isDoubleTy() && Alignment == 8) ||
- (Ty->isFloatTy() && Alignment == 4);
+ // To reduce the set of alignment values that need to be encoded in pexes, we
+ // disallow other alignment values. We require alignments to be explicit by
+ // disallowing Alignment == 0.
+ if (Alignment > std::numeric_limits<uint64_t>::max() / CHAR_BIT)
+ return false; // No overflow assumed below.
+ else if (VectorType *VTy = dyn_cast<VectorType>(Ty))
+ return !VTy->getElementType()->isIntegerTy(1) &&
+ (Alignment * CHAR_BIT ==
+ DL->getTypeSizeInBits(VTy->getElementType()));
+ else
+ return Alignment == 1 ||
+ (Ty->isDoubleTy() && Alignment == 8) ||
+ (Ty->isFloatTy() && Alignment == 4);
}
static bool hasAllowedAtomicRMWOperation(
@@ -253,7 +266,8 @@ static bool hasAllowedLockFreeByteSize(const CallInst *Call) {
//
// This returns an error string if the instruction is rejected, or
// NULL if the instruction is allowed.
-const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
+const char *PNaClABIVerifyFunctions::checkInstruction(const DataLayout *DL,
+ const Instruction *Inst) {
// If the instruction has a single pointer operand, PtrOperandIndex is
// set to its operand index.
unsigned PtrOperandIndex = -1;
@@ -364,8 +378,7 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
return "volatile load";
if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
return "bad pointer";
- if (!isAllowedAlignment(Load->getAlignment(),
- Load->getType()))
+ if (!isAllowedAlignment(DL, Load->getAlignment(), Load->getType()))
return "bad alignment";
break;
}
@@ -378,7 +391,7 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
return "volatile store";
if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
return "bad pointer";
- if (!isAllowedAlignment(Store->getAlignment(),
+ if (!isAllowedAlignment(DL, Store->getAlignment(),
Store->getValueOperand()->getType()))
return "bad alignment";
break;
@@ -541,6 +554,7 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
}
bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
+ const DataLayout *DL = &getAnalysis<DataLayout>();
SmallVector<StringRef, 8> MDNames;
F.getContext().getMDKindNames(MDNames);
@@ -553,7 +567,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
// because some instruction opcodes must be rejected out of hand
// (regardless of the instruction's result type) and the tests
// check the reason for rejection.
- const char *Error = checkInstruction(BBI);
+ const char *Error = checkInstruction(DL, BBI);
// Check the instruction's result type.
bool BadResult = false;
if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) ||
« no previous file with comments | « no previous file | lib/Transforms/NaCl/FixVectorLoadStoreAlignment.cpp » ('j') | test/NaCl/PNaClABI/abi-i1-operations.ll » ('J')

Powered by Google App Engine
This is Rietveld 408576698