Skip to content

Commit 226a1b6

Browse files
committed
IR/Verifier: Allow vector type in atomic load and store
Vector types on atomics are assumed to be invalid by the verifier. However, this type can be valid if it is lowered by codegen.
1 parent 0967957 commit 226a1b6

File tree

5 files changed

+42
-19
lines changed

5 files changed

+42
-19
lines changed

llvm/docs/LangRef.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11279,9 +11279,9 @@ If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering
1127911279
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
1128011280
``release`` and ``acq_rel`` orderings are not valid on ``load`` instructions.
1128111281
Atomic loads produce :ref:`defined <memmodel>` results when they may see
11282-
multiple atomic stores. The type of the pointee must be an integer, pointer, or
11283-
floating-point type whose bit width is a power of two greater than or equal to
11284-
eight. ``align`` must be
11282+
multiple atomic stores. The type of the pointee must be an integer, pointer,
11283+
floating-point, or vector type whose bit width is a power of two greater than
11284+
or equal to eight. ``align`` must be
1128511285
explicitly specified on atomic loads. Note: if the alignment is not greater or
1128611286
equal to the size of the `<value>` type, the atomic operation is likely to
1128711287
require a lock and have poor performance. ``!nontemporal`` does not have any
@@ -11420,9 +11420,9 @@ If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
1142011420
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
1142111421
``acquire`` and ``acq_rel`` orderings aren't valid on ``store`` instructions.
1142211422
Atomic loads produce :ref:`defined <memmodel>` results when they may see
11423-
multiple atomic stores. The type of the pointee must be an integer, pointer, or
11424-
floating-point type whose bit width is a power of two greater than or equal to
11425-
eight. ``align`` must be
11423+
multiple atomic stores. The type of the pointee must be an integer, pointer,
11424+
floating-point, or vector type whose bit width is a power of two greater than
11425+
or equal to eight. ``align`` must be
1142611426
explicitly specified on atomic stores. Note: if the alignment is not greater or
1142711427
equal to the size of the `<value>` type, the atomic operation is likely to
1142811428
require a lock and have poor performance. ``!nontemporal`` does not have any

llvm/docs/ReleaseNotes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Changes to the LLVM IR
6565
removed:
6666

6767
* `mul`
68+
* A `load atomic` may now be used with vector types.
6869

6970
* Updated semantics of `llvm.type.checked.load.relative` to match that of
7071
`llvm.load.relative`.

llvm/lib/IR/Verifier.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4372,9 +4372,10 @@ void Verifier::visitLoadInst(LoadInst &LI) {
43724372
Check(LI.getOrdering() != AtomicOrdering::Release &&
43734373
LI.getOrdering() != AtomicOrdering::AcquireRelease,
43744374
"Load cannot have Release ordering", &LI);
4375-
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4376-
"atomic load operand must have integer, pointer, or floating point "
4377-
"type!",
4375+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4376+
ElTy->getScalarType()->isFloatingPointTy(),
4377+
"atomic load operand must have integer, pointer, floating point, "
4378+
"or vector type!",
43784379
ElTy, &LI);
43794380
checkAtomicMemAccessSize(ElTy, &LI);
43804381
} else {
@@ -4398,9 +4399,10 @@ void Verifier::visitStoreInst(StoreInst &SI) {
43984399
Check(SI.getOrdering() != AtomicOrdering::Acquire &&
43994400
SI.getOrdering() != AtomicOrdering::AcquireRelease,
44004401
"Store cannot have Acquire ordering", &SI);
4401-
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4402-
"atomic store operand must have integer, pointer, or floating point "
4403-
"type!",
4402+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4403+
ElTy->getScalarType()->isFloatingPointTy(),
4404+
"atomic store operand must have integer, pointer, floating point, "
4405+
"or vector type!",
44044406
ElTy, &SI);
44054407
checkAtomicMemAccessSize(ElTy, &SI);
44064408
} else {

llvm/test/Assembler/atomic.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,25 @@ define void @f(ptr %x) {
5252
; CHECK: atomicrmw volatile usub_sat ptr %x, i32 10 syncscope("agent") monotonic
5353
atomicrmw volatile usub_sat ptr %x, i32 10 syncscope("agent") monotonic
5454

55+
; CHECK : load atomic <1 x i32>, ptr %x unordered, align 4
56+
load atomic <1 x i32>, ptr %x unordered, align 4
57+
; CHECK : store atomic <1 x i32> splat (i32 3), ptr %x release, align 4
58+
store atomic <1 x i32> <i32 3>, ptr %x release, align 4
59+
; CHECK : load atomic <2 x i32>, ptr %x unordered, align 4
60+
load atomic <2 x i32>, ptr %x unordered, align 4
61+
; CHECK : store atomic <2 x i32> <i32 3, i32 4>, ptr %x release, align 4
62+
store atomic <2 x i32> <i32 3, i32 4>, ptr %x release, align 4
63+
64+
; CHECK : load atomic <2 x ptr>, ptr %x unordered, align 4
65+
load atomic <2 x ptr>, ptr %x unordered, align 4
66+
; CHECK : store atomic <2 x ptr> zeroinitializer, ptr %x release, align 4
67+
store atomic <2 x ptr> zeroinitializer, ptr %x release, align 4
68+
69+
; CHECK : load atomic <2 x float>, ptr %x unordered, align 4
70+
load atomic <2 x float>, ptr %x unordered, align 4
71+
; CHECK : store atomic <2 x float> <float 3.0, float 4.0>, ptr %x release, align 4
72+
store atomic <2 x float> <float 3.0, float 4.0>, ptr %x release, align 4
73+
5574
; CHECK: fence syncscope("singlethread") release
5675
fence syncscope("singlethread") release
5776
; CHECK: fence seq_cst

llvm/test/Verifier/atomics.ll

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
; RUN: not opt -passes=verify < %s 2>&1 | FileCheck %s
2+
; CHECK: atomic store operand must have integer, pointer, floating point, or vector type!
3+
; CHECK: atomic load operand must have integer, pointer, floating point, or vector type!
24

3-
; CHECK: atomic store operand must have integer, pointer, or floating point type!
4-
; CHECK: atomic load operand must have integer, pointer, or floating point type!
5+
%ty = type { i32 };
56

6-
define void @foo(ptr %P, <1 x i64> %v) {
7-
store atomic <1 x i64> %v, ptr %P unordered, align 8
7+
define void @foo(ptr %P, %ty %v) {
8+
store atomic %ty %v, ptr %P unordered, align 8
89
ret void
910
}
1011

11-
define <1 x i64> @bar(ptr %P) {
12-
%v = load atomic <1 x i64>, ptr %P unordered, align 8
13-
ret <1 x i64> %v
12+
define %ty @bar(ptr %P) {
13+
%v = load atomic %ty, ptr %P unordered, align 8
14+
ret %ty %v
1415
}

0 commit comments

Comments
 (0)