Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -6829,17 +6829,16 @@ execution of this ``load`` with other :ref:`volatile operations `. -If the ``load`` is marked as ``atomic``, it takes an extra -:ref:`ordering ` and optional ``singlethread`` argument. The -``release`` and ``acq_rel`` orderings are not valid on ``load`` -instructions. Atomic loads produce :ref:`defined ` results -when they may see multiple atomic stores. The type of the pointee must -be an integer type whose bit width is a power of two greater than or -equal to eight and less than or equal to a target-specific size limit. -``align`` must be explicitly specified on atomic loads, and the load has -undefined behavior if the alignment is not set to a value which is at -least the size in bytes of the pointee. ``!nontemporal`` does not have -any defined semantics for atomic loads. +If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering +` and optional ``singlethread`` argument. The ``release`` and +``acq_rel`` orderings are not valid on ``load`` instructions. Atomic loads +produce :ref:`defined ` results when they may see multiple atomic +stores. The type of the pointee must be an integer or pointer type whose bit +width is a power of two greater than or equal to eight and less than or equal to +a target-specific size limit. ``align`` must be explicitly specified on atomic +loads, and the load has undefined behavior if the alignment is not set to a +value which is at least the size in bytes of the pointee. ``!nontemporal`` does +not have any defined semantics for atomic loads. The optional constant ``align`` argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 @@ -6954,17 +6953,16 @@ execution of this ``store`` with other :ref:`volatile operations `. -If the ``store`` is marked as ``atomic``, it takes an extra -:ref:`ordering ` and optional ``singlethread`` argument. The -``acquire`` and ``acq_rel`` orderings aren't valid on ``store`` -instructions. Atomic loads produce :ref:`defined ` results -when they may see multiple atomic stores. The type of the pointee must -be an integer type whose bit width is a power of two greater than or -equal to eight and less than or equal to a target-specific size limit. -``align`` must be explicitly specified on atomic stores, and the store -has undefined behavior if the alignment is not set to a value which is -at least the size in bytes of the pointee. ``!nontemporal`` does not -have any defined semantics for atomic stores. +If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering +` and optional ``singlethread`` argument. The ``acquire`` and +``acq_rel`` orderings aren't valid on ``store`` instructions. Atomic loads +produce :ref:`defined ` results when they may see multiple atomic +stores. The type of the pointee must be an integer or pointer type whose bit +width is a power of two greater than or equal to eight and less than or equal to +a target-specific size limit. ``align`` must be explicitly specified on atomic +stores, and the store has undefined behavior if the alignment is not set to a +value which is at least the size in bytes of the pointee. ``!nontemporal`` does +not have any defined semantics for atomic stores. The optional constant ``align`` argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -83,6 +83,7 @@ struct VerifierSupport { raw_ostream &OS; const Module *M; + const DataLayout *DL; /// \brief Track the brokenness of the module while recursively visiting. bool Broken; @@ -214,6 +215,7 @@ bool verify(const Function &F) { M = F.getParent(); + DL = &M->getDataLayout(); Context = &M->getContext(); // First ensure the function is well-enough formed to compute dominance @@ -252,6 +254,7 @@ bool verify(const Module &M) { this->M = &M; + DL = &M.getDataLayout(); Context = &M.getContext(); Broken = false; @@ -2719,14 +2722,13 @@ "Load cannot have Release ordering", &LI); Assert(LI.getAlignment() != 0, "Atomic load must specify explicit alignment", &LI); - if (!ElTy->isPointerTy()) { - Assert(ElTy->isIntegerTy(), "atomic load operand must have integer type!", - &LI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "atomic load operand must be power-of-two byte-sized integer", &LI, - ElTy); - } + Assert(ElTy->isIntegerTy() || ElTy->isPointerTy(), + "atomic load operand must have integer or pointer type!", ElTy, &LI); + unsigned Size = DL->getTypeStoreSizeInBits(ElTy); + Assert(Size >= 8, "atomic load element size must be byte-sized", ElTy, &LI); + Assert(!(Size & (Size - 1)), + "atomic load operand must be power-of-two integer or pointer", ElTy, + &LI); } else { Assert(LI.getSynchScope() == CrossThread, "Non-atomic load cannot have SynchronizationScope specified", &LI); @@ -2748,14 +2750,15 @@ "Store cannot have Acquire ordering", &SI); Assert(SI.getAlignment() != 0, "Atomic store must specify explicit alignment", &SI); - if (!ElTy->isPointerTy()) { - Assert(ElTy->isIntegerTy(), - "atomic store operand must have integer type!", &SI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "atomic store operand must be power-of-two byte-sized integer", - &SI, ElTy); - } + Assert(ElTy->isIntegerTy() || ElTy->isPointerTy(), + "atomic store operand must have integer or pointer type!", ElTy, + &SI); + unsigned Size = DL->getTypeStoreSizeInBits(ElTy); + Assert(Size >= 8, "atomic store element size must be byte-sized", ElTy, + &SI); + Assert(!(Size & (Size - 1)), + "atomic store operand must be power-of-two integer or pointer", ElTy, + &SI); } else { Assert(SI.getSynchScope() == CrossThread, "Non-atomic store cannot have SynchronizationScope specified", &SI); @@ -2802,9 +2805,10 @@ Type *ElTy = PTy->getElementType(); Assert(ElTy->isIntegerTy(), "cmpxchg operand must have integer type!", &CXI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "cmpxchg operand must be power-of-two byte-sized integer", &CXI, ElTy); + unsigned Size = DL->getTypeStoreSizeInBits(ElTy); + Assert(Size >= 8, "cmpxchg element size must be byte-sized", ElTy, &CXI); + Assert(!(Size & (Size - 1)), "cmpxchg operand must be power-of-two integer", + ElTy, &CXI); Assert(ElTy == CXI.getOperand(1)->getType(), "Expected value type does not match pointer operand type!", &CXI, ElTy); @@ -2823,10 +2827,10 @@ Type *ElTy = PTy->getElementType(); Assert(ElTy->isIntegerTy(), "atomicrmw operand must have integer type!", &RMWI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "atomicrmw operand must be power-of-two byte-sized integer", &RMWI, - ElTy); + unsigned Size = DL->getTypeStoreSizeInBits(ElTy); + Assert(Size >= 8, "atomicrmw element size must be byte-sized", ElTy, &RMWI); + Assert(!(Size & (Size - 1)), "atomicrmw operand must be power-of-two integer", + ElTy, &RMWI); Assert(ElTy == RMWI.getOperand(1)->getType(), "Argument value type does not match pointer operand type!", &RMWI, ElTy);