[PATCH] D56534: [Verifier] Add verification of unaligned atomic load/store

Serguei Katkov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 10 00:22:51 PST 2019


skatkov created this revision.
skatkov added reviewers: sanjoy, reames, majnemer, chandlerc.
Herald added a subscriber: jfb.

According to LangRef "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."

It would be useful to detect optimization introducing the undefined behavior
in verifier. By default the check is off and can be enabled by
verify-atomic-alignment option


https://reviews.llvm.org/D56534

Files:
  lib/IR/Verifier.cpp
  test/Verifier/atomics.ll


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
+}
Index: lib/IR/Verifier.cpp
===================================================================
--- lib/IR/Verifier.cpp
+++ lib/IR/Verifier.cpp
@@ -114,6 +114,9 @@
 
 using namespace llvm;
 
+static cl::opt<bool> 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,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D56534.181002.patch
Type: text/x-patch
Size: 2268 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190110/2e0175c7/attachment.bin>


More information about the llvm-commits mailing list