Skip to content

Commit b0b03e8

Browse files
jofrnLukacma
authored andcommitted
IR/Verifier: Allow vector type in atomic load and store (llvm#148893)
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 837ab55 commit b0b03e8

File tree

5 files changed

+43
-19
lines changed

5 files changed

+43
-19
lines changed

llvm/docs/LangRef.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11455,9 +11455,9 @@ If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering
1145511455
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
1145611456
``release`` and ``acq_rel`` orderings are not valid on ``load`` instructions.
1145711457
Atomic loads produce :ref:`defined <memmodel>` results when they may see
11458-
multiple atomic stores. The type of the pointee must be an integer, pointer, or
11459-
floating-point type whose bit width is a power of two greater than or equal to
11460-
eight. ``align`` must be
11458+
multiple atomic stores. The type of the pointee must be an integer, pointer,
11459+
floating-point, or vector type whose bit width is a power of two greater than
11460+
or equal to eight. ``align`` must be
1146111461
explicitly specified on atomic loads. Note: if the alignment is not greater or
1146211462
equal to the size of the `<value>` type, the atomic operation is likely to
1146311463
require a lock and have poor performance. ``!nontemporal`` does not have any
@@ -11594,9 +11594,9 @@ If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
1159411594
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
1159511595
``acquire`` and ``acq_rel`` orderings aren't valid on ``store`` instructions.
1159611596
Atomic loads produce :ref:`defined <memmodel>` results when they may see
11597-
multiple atomic stores. The type of the pointee must be an integer, pointer, or
11598-
floating-point type whose bit width is a power of two greater than or equal to
11599-
eight. ``align`` must be
11597+
multiple atomic stores. The type of the pointee must be an integer, pointer,
11598+
floating-point, or vector type whose bit width is a power of two greater than
11599+
or equal to eight. ``align`` must be
1160011600
explicitly specified on atomic stores. Note: if the alignment is not greater or
1160111601
equal to the size of the `<value>` type, the atomic operation is likely to
1160211602
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
@@ -66,6 +66,7 @@ Changes to the LLVM IR
6666
`@llvm.masked.gather` and `@llvm.masked.scatter` intrinsics has been removed.
6767
Instead, the `align` attribute should be placed on the pointer (or vector of
6868
pointers) argument.
69+
* A `load atomic` may now be used with vector types on x86.
6970

7071
Changes to LLVM infrastructure
7172
------------------------------

llvm/lib/IR/Verifier.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4446,10 +4446,12 @@ void Verifier::visitLoadInst(LoadInst &LI) {
44464446
Check(LI.getOrdering() != AtomicOrdering::Release &&
44474447
LI.getOrdering() != AtomicOrdering::AcquireRelease,
44484448
"Load cannot have Release ordering", &LI);
4449-
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4450-
"atomic load operand must have integer, pointer, or floating point "
4451-
"type!",
4449+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4450+
ElTy->getScalarType()->isFloatingPointTy(),
4451+
"atomic load operand must have integer, pointer, floating point, "
4452+
"or vector type!",
44524453
ElTy, &LI);
4454+
44534455
checkAtomicMemAccessSize(ElTy, &LI);
44544456
} else {
44554457
Check(LI.getSyncScopeID() == SyncScope::System,
@@ -4472,9 +4474,10 @@ void Verifier::visitStoreInst(StoreInst &SI) {
44724474
Check(SI.getOrdering() != AtomicOrdering::Acquire &&
44734475
SI.getOrdering() != AtomicOrdering::AcquireRelease,
44744476
"Store cannot have Acquire ordering", &SI);
4475-
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4476-
"atomic store operand must have integer, pointer, or floating point "
4477-
"type!",
4477+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4478+
ElTy->getScalarType()->isFloatingPointTy(),
4479+
"atomic store operand must have integer, pointer, floating point, "
4480+
"or vector type!",
44784481
ElTy, &SI);
44794482
checkAtomicMemAccessSize(ElTy, &SI);
44804483
} 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)