Skip to content

Commit

Permalink
IR/Verifier: Allow vector type in atomic load and store
Browse files Browse the repository at this point in the history
Vector types on atomics are assumed to be invalid by the verifier. However,
this type can be valid if it is lowered by codegen.

commit-id:72529270
  • Loading branch information
jofrn committed Dec 19, 2024
1 parent b5d0278 commit 7b13a0d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 17 deletions.
8 changes: 4 additions & 4 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10956,8 +10956,8 @@ If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
``release`` and ``acq_rel`` orderings are not valid on ``load`` instructions.
Atomic loads produce :ref:`defined <memmodel>` results when they may see
multiple atomic stores. The type of the pointee must be an integer, pointer, or
floating-point type whose bit width is a power of two greater than or equal to
multiple atomic stores. The type of the pointee must be an integer, pointer,
floating-point, or vector 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. Note: if the alignment is not greater or
equal to the size of the `<value>` type, the atomic operation is likely to
Expand Down Expand Up @@ -11097,8 +11097,8 @@ If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
``acquire`` and ``acq_rel`` orderings aren't valid on ``store`` instructions.
Atomic loads produce :ref:`defined <memmodel>` results when they may see
multiple atomic stores. The type of the pointee must be an integer, pointer, or
floating-point type whose bit width is a power of two greater than or equal to
multiple atomic stores. The type of the pointee must be an integer, pointer,
floating-point, or vector 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. Note: if the alignment is not greater or
equal to the size of the `<value>` type, the atomic operation is likely to
Expand Down
14 changes: 8 additions & 6 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4259,9 +4259,10 @@ void Verifier::visitLoadInst(LoadInst &LI) {
Check(LI.getOrdering() != AtomicOrdering::Release &&
LI.getOrdering() != AtomicOrdering::AcquireRelease,
"Load cannot have Release ordering", &LI);
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
"atomic load operand must have integer, pointer, or floating point "
"type!",
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
ElTy->getScalarType()->isFloatingPointTy(),
"atomic load operand must have integer, pointer, floating point, "
"or vector type!",
ElTy, &LI);
checkAtomicMemAccessSize(ElTy, &LI);
} else {
Expand All @@ -4285,9 +4286,10 @@ void Verifier::visitStoreInst(StoreInst &SI) {
Check(SI.getOrdering() != AtomicOrdering::Acquire &&
SI.getOrdering() != AtomicOrdering::AcquireRelease,
"Store cannot have Acquire ordering", &SI);
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
"atomic store operand must have integer, pointer, or floating point "
"type!",
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
ElTy->getScalarType()->isFloatingPointTy(),
"atomic store operand must have integer, pointer, floating point, "
"or vector type!",
ElTy, &SI);
checkAtomicMemAccessSize(ElTy, &SI);
} else {
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/Assembler/atomic.ll
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ define void @f(ptr %x) {
; CHECK: atomicrmw volatile usub_sat ptr %x, i32 10 syncscope("agent") monotonic
atomicrmw volatile usub_sat ptr %x, i32 10 syncscope("agent") monotonic

; CHECK : load atomic <1 x i32>, ptr %x unordered, align 4
load atomic <1 x i32>, ptr %x unordered, align 4
; CHECK : store atomic <1 x i32> splat (i32 3), ptr %x release, align 4
store atomic <1 x i32> <i32 3>, ptr %x release, align 4
; CHECK : load atomic <2 x i32>, ptr %x unordered, align 4
load atomic <2 x i32>, ptr %x unordered, align 4
; CHECK : store atomic <2 x i32> <i32 3, i32 4>, ptr %x release, align 4
store atomic <2 x i32> <i32 3, i32 4>, ptr %x release, align 4

; CHECK: fence syncscope("singlethread") release
fence syncscope("singlethread") release
; CHECK: fence seq_cst
Expand Down
15 changes: 8 additions & 7 deletions llvm/test/Verifier/atomics.ll
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
; RUN: not opt -passes=verify < %s 2>&1 | FileCheck %s
; CHECK: atomic store operand must have integer, pointer, floating point, or vector type!
; CHECK: atomic load operand must have integer, pointer, floating point, or vector type!

; CHECK: atomic store operand must have integer, pointer, or floating point type!
; CHECK: atomic load operand must have integer, pointer, or floating point type!
%ty = type { i32 };

define void @foo(ptr %P, <1 x i64> %v) {
store atomic <1 x i64> %v, ptr %P unordered, align 8
define void @foo(ptr %P, %ty %v) {
store atomic %ty %v, ptr %P unordered, align 8
ret void
}

define <1 x i64> @bar(ptr %P) {
%v = load atomic <1 x i64>, ptr %P unordered, align 8
ret <1 x i64> %v
define %ty @bar(ptr %P) {
%v = load atomic %ty, ptr %P unordered, align 8
ret %ty %v
}

0 comments on commit 7b13a0d

Please sign in to comment.