Clarify the behavior of the llvm.vector.insert/extract intrinsics when the index
is out of range. Both intrinsics return a poison value. Consequently, mark the intrinsics speculatable. Differential Revision: https://reviews.llvm.org/D129656
This commit is contained in:
parent
86d73c11cf
commit
c720b6fddd
|
@ -17395,7 +17395,7 @@ the runtime scaling factor of ``subvec``. The elements of ``vec`` starting at
|
||||||
``idx`` are overwritten with ``subvec``. Elements ``idx`` through (``idx`` +
|
``idx`` are overwritten with ``subvec``. Elements ``idx`` through (``idx`` +
|
||||||
num_elements(``subvec``) - 1) must be valid ``vec`` indices. If this condition
|
num_elements(``subvec``) - 1) must be valid ``vec`` indices. If this condition
|
||||||
cannot be determined statically but is false at runtime, then the result vector
|
cannot be determined statically but is false at runtime, then the result vector
|
||||||
is undefined.
|
is a :ref:`poison value <poisonvalues>`.
|
||||||
|
|
||||||
|
|
||||||
'``llvm.vector.extract``' Intrinsic
|
'``llvm.vector.extract``' Intrinsic
|
||||||
|
@ -17439,9 +17439,9 @@ vector length of the result type. If the result type is a scalable vector,
|
||||||
``idx`` is first scaled by the result type's runtime scaling factor. Elements
|
``idx`` is first scaled by the result type's runtime scaling factor. Elements
|
||||||
``idx`` through (``idx`` + num_elements(result_type) - 1) must be valid vector
|
``idx`` through (``idx`` + num_elements(result_type) - 1) must be valid vector
|
||||||
indices. If this condition cannot be determined statically but is false at
|
indices. If this condition cannot be determined statically but is false at
|
||||||
runtime, then the result vector is undefined. The ``idx`` parameter must be a
|
runtime, then the result vector is a :ref:`poison value <poisonvalues>`. The
|
||||||
vector index constant type (for most targets this will be an integer pointer
|
``idx`` parameter must be a vector index constant type (for most targets this
|
||||||
type).
|
will be an integer pointer type).
|
||||||
|
|
||||||
'``llvm.experimental.vector.reverse``' Intrinsic
|
'``llvm.experimental.vector.reverse``' Intrinsic
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1963,11 +1963,11 @@ def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
|
||||||
//===---------- Intrinsics to perform subvector insertion/extraction ------===//
|
//===---------- Intrinsics to perform subvector insertion/extraction ------===//
|
||||||
def int_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
|
def int_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
|
||||||
[LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty],
|
[LLVMMatchType<0>, llvm_anyvector_ty, llvm_i64_ty],
|
||||||
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
|
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>]>;
|
||||||
|
|
||||||
def int_vector_extract : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
|
def int_vector_extract : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
|
||||||
[llvm_anyvector_ty, llvm_i64_ty],
|
[llvm_anyvector_ty, llvm_i64_ty],
|
||||||
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
|
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>;
|
||||||
|
|
||||||
//===----------------- Pointer Authentication Intrinsics ------------------===//
|
//===----------------- Pointer Authentication Intrinsics ------------------===//
|
||||||
//
|
//
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
|
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
||||||
|
|
||||||
|
declare <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32>, <4 x i32>, i64 immarg)
|
||||||
|
declare <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32>, i64 immarg)
|
||||||
|
|
||||||
|
define <vscale x 4 x i32> @speculate_vector_insert(i32 %c, <4 x i32> %v1, <4 x i32> %v2) {
|
||||||
|
; CHECK-LABEL: @speculate_vector_insert(
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C:%.*]], 0
|
||||||
|
; CHECK-NEXT: [[T1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> zeroinitializer, <4 x i32> [[V1:%.*]], i64 0)
|
||||||
|
; CHECK-NEXT: [[T2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> zeroinitializer, <4 x i32> [[V2:%.*]], i64 0)
|
||||||
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], <vscale x 4 x i32> [[T2]], <vscale x 4 x i32> [[T1]]
|
||||||
|
; CHECK-NEXT: ret <vscale x 4 x i32> [[COND]]
|
||||||
|
;
|
||||||
|
entry:
|
||||||
|
%tobool = icmp eq i32 %c, 0
|
||||||
|
br i1 %tobool, label %cond.else, label %cond.then
|
||||||
|
|
||||||
|
cond.then: ; preds = %entry
|
||||||
|
%t1 = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> zeroinitializer, <4 x i32> %v1, i64 0)
|
||||||
|
br label %cond.end
|
||||||
|
|
||||||
|
cond.else: ; preds = %entry
|
||||||
|
%t2 = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> zeroinitializer, <4 x i32> %v2, i64 0)
|
||||||
|
br label %cond.end
|
||||||
|
|
||||||
|
cond.end: ; preds = %cond.else, %cond.then
|
||||||
|
%cond = phi <vscale x 4 x i32> [ %t1, %cond.then ], [ %t2, %cond.else ]
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %cond.end
|
||||||
|
ret <vscale x 4 x i32> %cond
|
||||||
|
}
|
||||||
|
|
||||||
|
define <4 x i32> @speculate_vector_extract(i32 %c, <vscale x 4 x i32> %v1, <vscale x 4 x i32> %v2) {
|
||||||
|
; CHECK-LABEL: @speculate_vector_extract(
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C:%.*]], 0
|
||||||
|
; CHECK-NEXT: [[T1:%.*]] = tail call <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> [[V1:%.*]], i64 0)
|
||||||
|
; CHECK-NEXT: [[T2:%.*]] = tail call <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> [[V2:%.*]], i64 0)
|
||||||
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], <4 x i32> [[T2]], <4 x i32> [[T1]]
|
||||||
|
; CHECK-NEXT: ret <4 x i32> [[COND]]
|
||||||
|
;
|
||||||
|
entry:
|
||||||
|
%tobool = icmp eq i32 %c, 0
|
||||||
|
br i1 %tobool, label %cond.else, label %cond.then
|
||||||
|
|
||||||
|
cond.then: ; preds = %entry
|
||||||
|
%t1 = tail call <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> %v1, i64 0)
|
||||||
|
br label %cond.end
|
||||||
|
|
||||||
|
cond.else: ; preds = %entry
|
||||||
|
%t2 = tail call <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> %v2, i64 0)
|
||||||
|
br label %cond.end
|
||||||
|
|
||||||
|
cond.end: ; preds = %cond.else, %cond.then
|
||||||
|
%cond = phi <4 x i32> [ %t1, %cond.then ], [ %t2, %cond.else ]
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %cond.end
|
||||||
|
ret <4 x i32> %cond
|
||||||
|
}
|
|
@ -808,9 +808,9 @@ llvm.func @vector_insert_extract(%f256: vector<8xi32>, %f128: vector<4xi32>,
|
||||||
// CHECK-DAG: declare <8 x i64> @llvm.vp.fptosi.v8i64.v8f64(<8 x double>, <8 x i1>, i32) #2
|
// CHECK-DAG: declare <8 x i64> @llvm.vp.fptosi.v8i64.v8f64(<8 x double>, <8 x i1>, i32) #2
|
||||||
// CHECK-DAG: declare <8 x i64> @llvm.vp.ptrtoint.v8i64.v8p0(<8 x ptr>, <8 x i1>, i32) #2
|
// CHECK-DAG: declare <8 x i64> @llvm.vp.ptrtoint.v8i64.v8p0(<8 x ptr>, <8 x i1>, i32) #2
|
||||||
// CHECK-DAG: declare <8 x ptr> @llvm.vp.inttoptr.v8p0.v8i64(<8 x i64>, <8 x i1>, i32) #2
|
// CHECK-DAG: declare <8 x ptr> @llvm.vp.inttoptr.v8p0.v8i64(<8 x i64>, <8 x i1>, i32) #2
|
||||||
// CHECK-DAG: declare <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v8i32(<vscale x 4 x i32>, <8 x i32>, i64 immarg) #2
|
// CHECK-DAG: declare <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v8i32(<vscale x 4 x i32>, <8 x i32>, i64 immarg) #0
|
||||||
// CHECK-DAG: declare <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32>, <4 x i32>, i64 immarg) #2
|
// CHECK-DAG: declare <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32>, <4 x i32>, i64 immarg) #0
|
||||||
// CHECK-DAG: declare <8 x i32> @llvm.vector.insert.v8i32.v4i32(<8 x i32>, <4 x i32>, i64 immarg) #2
|
// CHECK-DAG: declare <8 x i32> @llvm.vector.insert.v8i32.v4i32(<8 x i32>, <4 x i32>, i64 immarg) #0
|
||||||
// CHECK-DAG: declare <8 x i32> @llvm.vector.extract.v8i32.nxv4i32(<vscale x 4 x i32>, i64 immarg) #2
|
// CHECK-DAG: declare <8 x i32> @llvm.vector.extract.v8i32.nxv4i32(<vscale x 4 x i32>, i64 immarg) #0
|
||||||
// CHECK-DAG: declare <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32>, i64 immarg) #2
|
// CHECK-DAG: declare <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32>, i64 immarg) #0
|
||||||
// CHECK-DAG: declare <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32>, i64 immarg) #2
|
// CHECK-DAG: declare <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32>, i64 immarg) #0
|
||||||
|
|
Loading…
Reference in New Issue