<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/96815>96815</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [X86] llvm.experimental.constrained.fptrunc ignores rounding for fp32 to fp16 conversion
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ienkovich
      </td>
    </tr>
</table>

<pre>
    **Problem**
Codegen for `llvm.experimental.constrained.fptrunc` intrinsic doesn't respect the requested rounding mode. Using different rounding modes in this intrinsic doesn't affect the resulting code. 

**Details**
Here is a test IR to convert a vector with zero rounding:
```
; ModuleID = 'LLVMDialectModule'
source_filename = "LLVMDialectModule"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
define void @type_convert(ptr %0, ptr %1) local_unnamed_addr #0 {
  %3 = load <16 x float>, ptr %0, align 4
  %4 = tail call <16 x half> @llvm.experimental.constrained.fptrunc.v16f16.v16f32(<16 x float> %3, metadata !"round.towardzero", metadata !"fpexcept.ignore") #2
  store <16 x half> %4, ptr %1, align 2
  ret void
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
declare <16 x half> @llvm.experimental.constrained.fptrunc.v16f16.v16f32(<16 x float>, metadata, metadata) #1

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn }
attributes #1 = { mustprogress nocallback nofree nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
attributes #2 = { strictfp }
```
A command used to compile:
```
llc test.ll -mcpu=sapphirerapids
```
The produced result uses `vcvtps2phx` instruction to make a conversion:
```
type_convert:
        vcvtps2phx      (%rdi), %ymm0
        vmovups %ymm0, (%rsi)
        vzeroupper
 retq
```
This code doesn't provide the requested rounding and produces incorrect results. I'd expect the resulting ASM to use explicit rounding, e.g:
```
        vmovups (%rdi), %zmm0
        vcvtps2ph       $3, %zmm0, (%rsi)
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vl-P4ygS_zTkpZTIxo6TPOQh3ZnWjTQjnW7uTvvWIlBO2MbAQJF0z6dfYefvdEeaXe1GkQ2mqqj61Y8qRIx6axGXbPrApuuRSLRzYanRvri9lrvRxqm3JeMrxlf_Dm5jsBsmrFizYvXoFG7RQusCsKYwZt9N8NVj0B1aEmYinY0UhLaoJq2nkKxkTQHaUtA2agnKYbSMzwgCRo-SgHYIAb8njIQKgktWabuFzimcwP9iHivdthjQ0u1yBG2Bdjp-aF-07cV8TIaymuytDsEcn314ayShTbyO9V8YEHQEAYSR4PN_gBxIZ_cYCATsUZILcNC0gx8Y3Nk1Vp0sN8XxP0yrB_jqVDL4eQ2sWgPjsy9f_v91rYVBScMS47NBOroUJD632qAVHR4V-AcKfFAgEbZIoAQJI95copMKjjtWrXDs-axg1ari_SNPy9tpHjV1_xjr86Dkc1atSj4ft_PiOLL9p-ak3tTjb1nsJ1coaG_Onr_Om-emHif7Yt3Bjo226XW8temsdUHpKVlJ2llYEYXIqhV0KZIPbhswRrCuDYhgXUCZQsyj-GYlWJfsQVsFB21MQErBDjYVttoi7J1WwOqC3jw-HxPJ-NxTAManBeOPcByXjC_AOCnMc7IZfvUslMpLVQFs9jCYhSxa9fEZJxSw6rFs4BVa4wSx6tOVwd64MHprob5SrnvlzDyQwpizhZ0wLas-ZWd_6YhN9mXTlk3_qjjLGbt1pfc0-9AhiUwRYLxknPecnZA7iKAyiXMy3ku1Hl8leprobQa9F1pkMPgplkgu4Hv3-bS-RfUEwlkxIPV5OSZ_tv7TXMjAbYR8udDilgyRgpbU-itWQIedC2-Mz7UVUmKMOhc6zOcEAgp1CJqQ8cWJPtKIj8L7u7JzDfntuEe5vMZEEAW9SYTxyMZ8umYPf_mEwBnzW8vlPcv_JN73nOFnZ87WL1S5rbIrkK7rhFWQIqqhZHdeG7xXlo2RfYGfGAPjTvrEqnUU3u90wCC8VvFDtf_uEHxwKsnctPr-kneMuS3u5Z585H73OvS-SCENJCYHnXhBEMdGErWz9xy7KVMnGTj-LlsM88wqPg1KZ9byx3zc3rqu-Empc_vk43mxl-v1oj6z_Syc60HyHsPxe0D6fgcKHfvGetV8fXB7rfBec8_5OaKXm7d0IeRePeAYJ_CZ8ZmCfLDedfDVt68ZxhQxrxst9eVWkCPCyd0O_B6Hd6D9eA_aCWk4IV1X18IfgnjeeKSWlVpUCzHCZTkrF3XF54titFs2HFW1mRWztmkWMz7l87rdqGbeqrZqRVOM9JIXvC4a3vCirOvFRNRtuUE5nVZtveDVnNUFdkKbSV-EXNiOdIwJl4tmXk5HRmzQxP6ax7nFA_SLuXRP16OwzDrjTdrGXMR0pHixQppMfz_8bd6w6Rp-qcbB0BriJcX5itj6iudktb5srhg_SsEsd0Q-13PGnxh_2mrapc1Euo7xp7zj8TX2wf2Okhh_6gOIjD8NAe6X_I8AAAD__xJqXKg">