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

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

Issue 17777004: Concurrency support for PNaCl ABI (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Update PNaClLangRef to reflect the implementation work I will now go forward with. Created 7 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 9a96d19ed4e1b3d069e67cabd3e350acec7165de..b4c9f02f540213501d56e3584b28d9f735001b6f 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
@@ -19,6 +19,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/NaClIntrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
@@ -138,16 +139,7 @@ static bool isValidScalarOperand(const Value *Val) {
isa<UndefValue>(Val));
}
-static bool isAllowedAlignment(unsigned Alignment, Type *Ty, bool IsAtomic) {
- if (IsAtomic) {
- // For atomic operations, the alignment must match the size of the type.
- if (Ty->isIntegerTy()) {
- unsigned Bits = Ty->getIntegerBitWidth();
- return Bits % 8 == 0 && Alignment == Bits / 8;
- }
- return (Ty->isDoubleTy() && Alignment == 8) ||
- (Ty->isFloatTy() && Alignment == 4);
- }
+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
@@ -192,6 +184,10 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
// ExtractValue and InsertValue operate on struct values.
case Instruction::ExtractValue:
case Instruction::InsertValue:
+ // Atomics should become NaCl intrinsics.
+ case Instruction::AtomicCmpXchg:
+ case Instruction::AtomicRMW:
+ case Instruction::Fence:
return "bad instruction opcode";
default:
return "unknown instruction opcode";
@@ -220,8 +216,6 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
- // Memory instructions
- case Instruction::Fence:
// Conversion operations
case Instruction::Trunc:
case Instruction::ZExt:
@@ -242,32 +236,32 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
// Memory accesses.
case Instruction::Load: {
const LoadInst *Load = cast<LoadInst>(Inst);
+ PtrOperandIndex = Load->getPointerOperandIndex();
+ if (Load->isAtomic())
+ return "atomic";
+ if (Load->isVolatile())
+ return "volatile";
if (!isAllowedAlignment(Load->getAlignment(),
- Load->getType(),
- Load->isAtomic()))
+ Load->getType()))
return "bad alignment";
- PtrOperandIndex = 0;
if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
return "bad pointer";
break;
}
case Instruction::Store: {
const StoreInst *Store = cast<StoreInst>(Inst);
+ PtrOperandIndex = Store->getPointerOperandIndex();
+ if (Store->isAtomic())
+ return "atomic";
+ if (Store->isVolatile())
+ return "volatile";
if (!isAllowedAlignment(Store->getAlignment(),
- Store->getValueOperand()->getType(),
- Store->isAtomic()))
+ Store->getValueOperand()->getType()))
return "bad alignment";
- PtrOperandIndex = 1;
if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
return "bad pointer";
break;
}
- case Instruction::AtomicCmpXchg:
- case Instruction::AtomicRMW:
- PtrOperandIndex = 0;
- if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
- return "bad pointer";
- break;
// Casts.
case Instruction::BitCast:
@@ -315,6 +309,7 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
isa<MDNode>(Arg)))
return "bad intrinsic operand";
}
+
// Disallow alignments other than 1 on memcpy() etc., for the
// same reason that we disallow them on integer loads and
// stores.
@@ -327,6 +322,35 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) {
return "bad alignment";
}
}
+
+ // Disallow NaCl atomic intrinsics which don't have valid
+ // constant NaCl::AtomicOperation and NaCl::MemoryOrder
+ // parameters.
+ for (size_t II = 0; II != NaCl::NumAtomicIntrinsics; ++II) {
+ if (Call->getIntrinsicID() == NaCl::AtomicIntrinsics[II].ID) {
+ const Value *Operation = Call->getArgOperand(0);
+ const Value *MemoryOrder = Call->getArgOperand(4);
+ const Constant *OperationC = dyn_cast<Constant>(Operation);
+ const Constant *MemoryOrderC = dyn_cast<Constant>(MemoryOrder);
+ if (!Operation)
+ return "non-constant atomic operation";
+ if(!MemoryOrder)
+ return "non-constant atomic memory order";
+ const APInt &OperationI = OperationC->getUniqueInteger();
+ const APInt &MemoryOrderI = MemoryOrderC->getUniqueInteger();
+ if (OperationI.ule(NaCl::AtomicInvalid) ||
+ OperationI.uge(NaCl::AtomicNum))
+ return "invalid atomic operation";
+ if (MemoryOrderI.ule(NaCl::MemoryOrderInvalid) ||
+ MemoryOrderI.uge(NaCl::MemoryOrderNum))
+ return "invalid atomic memory order";
+ // TODO For now only sequential consistency is allowed.
+ if (MemoryOrderI != NaCl::MemoryOrderSequentiallyConsistent)
+ return "only sequential consistency is currently allowed "
+ "as memory order";
+ }
+ }
+
// Allow the instruction and skip the later checks.
return NULL;
}

Powered by Google App Engine
This is Rietveld 408576698