diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -20073,6 +20073,61 @@ %t = fptosi <4 x float> %a to <4 x i32> %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> undef +.. _int_vp_sitofp: + +'``llvm.vp.sitofp.*``' Intrinsics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" +This is an overloaded intrinsic. + +:: + + declare <16 x float> @llvm.vp.sitofp.v16f32.v16i32 (<16 x i32> , <16 x i1> , i32 ) + declare @llvm.vp.sitofp.nxv4f32.nxv4i32 ( , , i32 ) + declare <256 x double> @llvm.vp.sitofp.v256f64.v256i64 (<256 x i64> , <256 x i1> , i32 ) + +Overview: +""""""""" + +The '``llvm.vp.sitofp``' intrinsic converts its signed integer operand to the +:ref:`floating-point ` return type. The operation has a mask and +an explicit vector length parameter. + + +Arguments: +"""""""""" + +The '``llvm.vp.sitofp``' intrinsic takes a value to cast as its first operand. +The value to cast must be vector of :ref:`integer ` type. The +return type is the type to cast the value to. The return type must be a vector +of :ref:`floating-point ` type. The second operand is the vector +mask. The return type, the value to cast, and the vector mask have the same +number of elements. The third operand is the explicit vector length of the +operation. + +Semantics: +"""""""""" + +The '``llvm.vp.sitofp``' intrinsic interprets its first operand as a signed +integer quantity and converts it to the corresponding floating-point value. If +the value cannot be exactly represented, it is rounded using the default +rounding mode. The conversion is performed on lane positions below the +explicit vector length and where the vector mask is true. Masked-off lanes are +undefined. + +Examples: +""""""""" + +.. code-block:: llvm + + %r = call <4 x float> @llvm.vp.sitofp.v4f32.v4i32(<4 x i32> %a, <4 x i1> %mask, i32 %evl) + ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r + + %t = sitofp <4 x i32> %a to <4 x float> + %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> undef + .. _int_mload_mstore: diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1529,6 +1529,10 @@ [ llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_i32_ty]>; +def int_vp_sitofp : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], + [ llvm_anyvector_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, + llvm_i32_ty]>; // Shuffles. def int_vp_select : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], diff --git a/llvm/include/llvm/IR/VPIntrinsics.def b/llvm/include/llvm/IR/VPIntrinsics.def --- a/llvm/include/llvm/IR/VPIntrinsics.def +++ b/llvm/include/llvm/IR/VPIntrinsics.def @@ -245,6 +245,9 @@ // llvm.vp.fptosi(x,mask,vlen) HELPER_REGISTER_CAST_VP(fptosi, VP_FPTOSI, FPToSI, 0) +// llvm.vp.sitofp(x,mask,vlen) +HELPER_REGISTER_CAST_VP(sitofp, VP_SITOFP, SIToFP, 1) + #undef HELPER_REGISTER_CAST_VP ///// } Type Casts diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -493,6 +493,7 @@ break; } case Intrinsic::vp_fptosi: + case Intrinsic::vp_sitofp: VPFunc = Intrinsic::getDeclaration(M, VPID, {ReturnType, Params[0]->getType()}); break; diff --git a/llvm/test/Verifier/vp-intrinsics.ll b/llvm/test/Verifier/vp-intrinsics.ll --- a/llvm/test/Verifier/vp-intrinsics.ll +++ b/llvm/test/Verifier/vp-intrinsics.ll @@ -1,4 +1,4 @@ -; RUN: opt --verify %s +; RUN: opt --verify --disable-output %s define void @test_vp_int(<8 x i32> %i0, <8 x i32> %i1, <8 x i1> %m, i32 %n) { %r0 = call <8 x i32> @llvm.vp.add.v8i32(<8 x i32> %i0, <8 x i32> %i1, <8 x i1> %m, i32 %n) @@ -57,6 +57,12 @@ ret void } +define void @test_vp_int_fp_conversions(<8 x i32> %i0, <8 x float> %f0, <8 x i1> %mask, i32 %evl) { + %r0 = call <8 x float> @llvm.vp.sitofp.v8f32.v8i32(<8 x i32> %i0, <8 x i1> %mask, i32 %evl) + %r1 = call <8 x i32> @llvm.vp.fptosi.v8i32.v8f32(<8 x float> %f0, <8 x i1> %mask, i32 %evl) + ret void +} + ; integer arith declare <8 x i32> @llvm.vp.add.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) declare <8 x i32> @llvm.vp.sub.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32) @@ -92,6 +98,9 @@ declare float @llvm.vp.reduce.fmax.v8f32(float, <8 x float>, <8 x i1>, i32) declare float @llvm.vp.reduce.fadd.v8f32(float, <8 x float>, <8 x i1>, i32) declare float @llvm.vp.reduce.fmul.v8f32(float, <8 x float>, <8 x i1>, i32) +; casts +declare <8 x float> @llvm.vp.sitofp.v8f32.v8i32(<8 x i32>, <8 x i1>, i32) +declare <8 x i32> @llvm.vp.fptosi.v8i32.v8f32(<8 x float>, <8 x i1>, i32) ; shuffles declare <8 x i32> @llvm.experimental.vp.splice.v8i32(<8 x i32>, <8 x i32>, i32, <8 x i1>, i32, i32) declare @llvm.experimental.vp.splice.nxv8i32(, , i32, , i32, i32) diff --git a/llvm/unittests/IR/VPIntrinsicTest.cpp b/llvm/unittests/IR/VPIntrinsicTest.cpp --- a/llvm/unittests/IR/VPIntrinsicTest.cpp +++ b/llvm/unittests/IR/VPIntrinsicTest.cpp @@ -82,6 +82,8 @@ Str << " declare <8 x i32> @llvm.vp.fptosi.v8i32" << ".v8f32(<8 x float>, <8 x i1>, i32) "; + Str << " declare <8 x float> @llvm.vp.sitofp.v8f32" + << ".v8i32(<8 x i32>, <8 x i1>, i32) "; return parseAssemblyString(Str.str(), Err, C); }