Index: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
index 9a96d19ed4e1b3d069e67cabd3e350acec7165de..97da55cb1de2de54b8f83673adaae9f3b5e7a6b3 100644 |
--- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
+++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
@@ -138,16 +138,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 +183,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 +215,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 +235,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: |