IR/Verifier: Allow vector type in atomic load and store (#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.
This commit is contained in:
parent
d8563e51b5
commit
5c666f559c
@ -11455,9 +11455,9 @@ 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
|
||||
eight. ``align`` must be
|
||||
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. ``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
|
||||
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
|
||||
<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
|
||||
eight. ``align`` must be
|
||||
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. ``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
|
||||
require a lock and have poor performance. ``!nontemporal`` does not have any
|
||||
|
||||
@ -66,6 +66,7 @@ Changes to the LLVM IR
|
||||
`@llvm.masked.gather` and `@llvm.masked.scatter` intrinsics has been removed.
|
||||
Instead, the `align` attribute should be placed on the pointer (or vector of
|
||||
pointers) argument.
|
||||
* A `load atomic` may now be used with vector types on x86.
|
||||
|
||||
Changes to LLVM infrastructure
|
||||
------------------------------
|
||||
|
||||
@ -4446,10 +4446,12 @@ 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 {
|
||||
Check(LI.getSyncScopeID() == SyncScope::System,
|
||||
@ -4472,9 +4474,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 {
|
||||
|
||||
@ -52,6 +52,25 @@ 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 : load atomic <2 x ptr>, ptr %x unordered, align 4
|
||||
load atomic <2 x ptr>, ptr %x unordered, align 4
|
||||
; CHECK : store atomic <2 x ptr> zeroinitializer, ptr %x release, align 4
|
||||
store atomic <2 x ptr> zeroinitializer, ptr %x release, align 4
|
||||
|
||||
; CHECK : load atomic <2 x float>, ptr %x unordered, align 4
|
||||
load atomic <2 x float>, ptr %x unordered, align 4
|
||||
; CHECK : store atomic <2 x float> <float 3.0, float 4.0>, ptr %x release, align 4
|
||||
store atomic <2 x float> <float 3.0, float 4.0>, ptr %x release, align 4
|
||||
|
||||
; CHECK: fence syncscope("singlethread") release
|
||||
fence syncscope("singlethread") release
|
||||
; CHECK: fence seq_cst
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user