Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -114,6 +114,9 @@ using namespace llvm; +static cl::opt VerifyAtomicAlignment("verify-atomic-alignment", + cl::init(false)); + namespace llvm { struct VerifierSupport { @@ -3299,6 +3302,9 @@ "atomic load operand must have integer, pointer, or floating point " "type!", ElTy, &LI); + Assert(!VerifyAtomicAlignment || + LI.getAlignment() >= DL.getTypeSizeInBits(ElTy) / 8, + "atomic load alignment leads to undefined behavior!", &LI); checkAtomicMemAccessSize(ElTy, &LI); } else { Assert(LI.getSyncScopeID() == SyncScope::System, @@ -3327,6 +3333,9 @@ "atomic store operand must have integer, pointer, or floating point " "type!", ElTy, &SI); + Assert(!VerifyAtomicAlignment || + SI.getAlignment() >= DL.getTypeSizeInBits(ElTy) / 8, + "atomic store alignment leads to undefined behavior!", &SI); checkAtomicMemAccessSize(ElTy, &SI); } else { Assert(SI.getSyncScopeID() == SyncScope::System, Index: test/Verifier/atomics.ll =================================================================== --- test/Verifier/atomics.ll +++ test/Verifier/atomics.ll @@ -1,7 +1,9 @@ -; RUN: not opt -verify < %s 2>&1 | FileCheck %s +; RUN: not opt -verify -verify-atomic-alignment=true < %s 2>&1 | FileCheck %s ; CHECK: atomic store operand must have integer, pointer, or floating point type! ; CHECK: atomic load operand must have integer, pointer, or floating point type! +; CHECK: atomic load alignment leads to undefined behavior! +; CHECK: atomic store alignment leads to undefined behavior! define void @foo(x86_mmx* %P, x86_mmx %v) { store atomic x86_mmx %v, x86_mmx* %P unordered, align 8 @@ -12,3 +14,13 @@ %v = load atomic x86_mmx, x86_mmx* %P unordered, align 8 ret x86_mmx %v } + +define i32 @load_alignment(i32* %p) { + %v = load atomic i32, i32* %p unordered, align 2 + ret i32 %v +} + +define void @store_alignment(i32* %p, i32 %v) { + store atomic i32 %v, i32* %p unordered, align 2 + ret void +}