Skip to content

Commit eef4cc5

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. commit-id:72529270
1 parent 4258998 commit eef4cc5

File tree

5 files changed

+40
-17
lines changed

5 files changed

+40
-17
lines changed

llvm/docs/LangRef.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -11203,8 +11203,8 @@ If the ``load`` is marked as ``atomic``, it takes an extra :ref:`ordering
1120311203
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
1120411204
``release`` and ``acq_rel`` orderings are not valid on ``load`` instructions.
1120511205
Atomic loads produce :ref:`defined <memmodel>` results when they may see
11206-
multiple atomic stores. The type of the pointee must be an integer, pointer, or
11207-
floating-point type whose bit width is a power of two greater than or equal to
11206+
multiple atomic stores. The type of the pointee must be an integer, pointer,
11207+
floating-point, or vector type whose bit width is a power of two greater than or equal to
1120811208
eight and less than or equal to a target-specific size limit. ``align`` must be
1120911209
explicitly specified on atomic loads. Note: if the alignment is not greater or
1121011210
equal to the size of the `<value>` type, the atomic operation is likely to
@@ -11344,8 +11344,8 @@ If the ``store`` is marked as ``atomic``, it takes an extra :ref:`ordering
1134411344
<ordering>` and optional ``syncscope("<target-scope>")`` argument. The
1134511345
``acquire`` and ``acq_rel`` orderings aren't valid on ``store`` instructions.
1134611346
Atomic loads produce :ref:`defined <memmodel>` results when they may see
11347-
multiple atomic stores. The type of the pointee must be an integer, pointer, or
11348-
floating-point type whose bit width is a power of two greater than or equal to
11347+
multiple atomic stores. The type of the pointee must be an integer, pointer,
11348+
floating-point, or vector type whose bit width is a power of two greater than or equal to
1134911349
eight and less than or equal to a target-specific size limit. ``align`` must be
1135011350
explicitly specified on atomic stores. Note: if the alignment is not greater or
1135111351
equal to the size of the `<value>` type, the atomic operation is likely to

llvm/docs/ReleaseNotes.md

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Changes to the LLVM IR
6161
removed:
6262

6363
* `mul`
64+
* A `load atomic` may now be used with vector types.
6465

6566
* Updated semantics of `llvm.type.checked.load.relative` to match that of
6667
`llvm.load.relative`.

llvm/lib/IR/Verifier.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -4300,9 +4300,10 @@ void Verifier::visitLoadInst(LoadInst &LI) {
43004300
Check(LI.getOrdering() != AtomicOrdering::Release &&
43014301
LI.getOrdering() != AtomicOrdering::AcquireRelease,
43024302
"Load cannot have Release ordering", &LI);
4303-
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4304-
"atomic load operand must have integer, pointer, or floating point "
4305-
"type!",
4303+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4304+
ElTy->getScalarType()->isFloatingPointTy(),
4305+
"atomic load operand must have integer, pointer, floating point, "
4306+
"or vector type!",
43064307
ElTy, &LI);
43074308
checkAtomicMemAccessSize(ElTy, &LI);
43084309
} else {
@@ -4326,9 +4327,10 @@ void Verifier::visitStoreInst(StoreInst &SI) {
43264327
Check(SI.getOrdering() != AtomicOrdering::Acquire &&
43274328
SI.getOrdering() != AtomicOrdering::AcquireRelease,
43284329
"Store cannot have Acquire ordering", &SI);
4329-
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4330-
"atomic store operand must have integer, pointer, or floating point "
4331-
"type!",
4330+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4331+
ElTy->getScalarType()->isFloatingPointTy(),
4332+
"atomic store operand must have integer, pointer, floating point, "
4333+
"or vector type!",
43324334
ElTy, &SI);
43334335
checkAtomicMemAccessSize(ElTy, &SI);
43344336
} else {

llvm/test/Assembler/atomic.ll

+19
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

+8-7
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)