Skip to content

Commit 90cdb49

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 86b89a6 commit 90cdb49

File tree

5 files changed

+57
-21
lines changed

5 files changed

+57
-21
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
@@ -62,6 +62,7 @@ Changes to the LLVM IR
6262
* The `ptrtoaddr` instruction was introduced. This instruction returns the
6363
address component of a pointer type variable but unlike `ptrtoint` does not
6464
capture provenance ([#125687](https://github.com/llvm/llvm-project/pull/125687)).
65+
* A `load atomic` may now be used with vector types.
6566

6667
Changes to LLVM infrastructure
6768
------------------------------

llvm/lib/IR/Verifier.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4446,10 +4446,18 @@ 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!",
4452-
ElTy, &LI);
4449+
if (TT.isX86())
4450+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4451+
ElTy->getScalarType()->isFloatingPointTy(),
4452+
"atomic load operand must have integer, pointer, floating point, "
4453+
"or vector type!",
4454+
ElTy, &LI);
4455+
else
4456+
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4457+
"atomic load operand must have integer, pointer, or floating point "
4458+
"type!",
4459+
ElTy, &LI);
4460+
44534461
checkAtomicMemAccessSize(ElTy, &LI);
44544462
} else {
44554463
Check(LI.getSyncScopeID() == SyncScope::System,
@@ -4472,10 +4480,17 @@ void Verifier::visitStoreInst(StoreInst &SI) {
44724480
Check(SI.getOrdering() != AtomicOrdering::Acquire &&
44734481
SI.getOrdering() != AtomicOrdering::AcquireRelease,
44744482
"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!",
4478-
ElTy, &SI);
4483+
if (TT.isX86())
4484+
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
4485+
ElTy->getScalarType()->isFloatingPointTy(),
4486+
"atomic store operand must have integer, pointer, floating point, "
4487+
"or vector type!",
4488+
ElTy, &SI);
4489+
else
4490+
Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
4491+
"atomic load operand must have integer, pointer, or floating point "
4492+
"type!",
4493+
ElTy, &LI);
44794494
checkAtomicMemAccessSize(ElTy, &SI);
44804495
} else {
44814496
Check(SI.getSyncScopeID() == SyncScope::System,

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)