[llvm] c720b6f - Clarify the behavior of the llvm.vector.insert/extract intrinsics when the index

David Kreitzer via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 15 08:00:39 PDT 2022


Author: David Kreitzer
Date: 2022-07-15T07:56:44-07:00
New Revision: c720b6fddd22d8521cdebb8244d0af437dcafc25

URL: https://github.com/llvm/llvm-project/commit/c720b6fddd22d8521cdebb8244d0af437dcafc25
DIFF: https://github.com/llvm/llvm-project/commit/c720b6fddd22d8521cdebb8244d0af437dcafc25.diff

LOG: 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

Added: 
    llvm/test/Transforms/SimplifyCFG/speculate-vector-insert-extract.ll

Modified: 
    llvm/docs/LangRef.rst
    llvm/include/llvm/IR/Intrinsics.td
    mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index d4dbff6f10f81..f641a3cfd4346 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -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`` +
 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
-is undefined.
+is a :ref:`poison value <poisonvalues>`.
 
 
 '``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`` through (``idx`` + num_elements(result_type) - 1) must be valid vector
 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
-vector index constant type (for most targets this will be an integer pointer
-type).
+runtime, then the result vector is a :ref:`poison value <poisonvalues>`. The
+``idx`` parameter must be a vector index constant type (for most targets this
+will be an integer pointer type).
 
 '``llvm.experimental.vector.reverse``' Intrinsic
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 8bf8e9ca76adf..28eb23458ba98 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1963,11 +1963,11 @@ def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
 //===---------- Intrinsics to perform subvector insertion/extraction ------===//
 def int_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_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],
                                                [llvm_anyvector_ty, llvm_i64_ty],
-                                               [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+                                               [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>;
 
 //===----------------- Pointer Authentication Intrinsics ------------------===//
 //

diff  --git a/llvm/test/Transforms/SimplifyCFG/speculate-vector-insert-extract.ll b/llvm/test/Transforms/SimplifyCFG/speculate-vector-insert-extract.ll
new file mode 100644
index 0000000000000..1bc4e8bbd60dd
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/speculate-vector-insert-extract.ll
@@ -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
+}

diff  --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index b9145be374662..752f5a30e3ef2 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -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.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 <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.v4i32(<vscale x 4 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) #2
-// CHECK-DAG: declare <8 x i32> @llvm.vector.extract.v8i32.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) #2
-// CHECK-DAG: declare <2 x i32> @llvm.vector.extract.v2i32.v8i32(<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) #0
+// 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) #0
+// 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) #0


        


More information about the llvm-commits mailing list