[llvm] [SelectionDAG] Add expansion for llvm.convert.to.arbitrary.fp (PR #193595)

Dmitry Sidorov via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 17:48:30 PDT 2026


https://github.com/MrSidims updated https://github.com/llvm/llvm-project/pull/193595

>From 894b5d07d96409cd4b2887e76b2d235a7f95492c Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Thu, 19 Feb 2026 10:22:21 +0100
Subject: [PATCH 1/9] [SelectionDAG] Add expansion for
 llvm.convert.to.arbitrary.fp

The expansion converts a native IEEE float to an arbitrary-precision
FP format, returning the result as an integer, following this algorithm:

1. Bitcast the source float to an integer and extract sign, exponent,
and mantissa bit fields via masks and shifts.
2. Classify the input (zero/denormal/normal/Inf/NaN).
3. Normalize source denormals by finding the MSB position of the
mantissa and adjusting the effective exponent.
4. Normal path: adjust the exponent bias from source to destination
format and truncate the mantissa with rounding (supports
NearestTiesToEven, TowardZero, TowardPositive, TowardNegative,
NearestTiesToAway).
5. Denormal destination path: when the biased destination exponent is
<= 0, shift the mantissa right to produce a denormalized result
with rounding.
6. Handle mantissa overflow from rounding and exponent overflow. Produce Inf
or saturate to max finite, depending on format and saturation flag.
7. Build special-value results (canonical qNaN, signed Inf, signed
zero) adapted to the destination format's non-finite behavior
(IEEE754, NanOnly, FiniteOnly).
8. Final selection in priority order: NaN > Inf > Zero > Overflow >
Normal/Denorm.

Currently only conversions to OCP floats are covered, in LLVM terms
these are: Float8E5M2, Float8E4M3FN, Float6E3M2FN, Float6E2M3FN,
Float4E2M1FN.

OCP spec:
https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf

E2E testing on X86 done with an assistance of Claude Code Opus 4.6.
---
 llvm/include/llvm/CodeGen/ISDOpcodes.h        |    9 +
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp |  473 ++++++
 .../SelectionDAG/LegalizeFloatTypes.cpp       |   20 +
 .../SelectionDAG/LegalizeIntegerTypes.cpp     |   13 +
 llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h |    3 +
 .../SelectionDAG/LegalizeVectorOps.cpp        |    1 +
 .../SelectionDAG/LegalizeVectorTypes.cpp      |   96 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |   43 +
 .../SelectionDAG/SelectionDAGDumper.cpp       |    1 +
 llvm/lib/CodeGen/TargetLoweringBase.cpp       |    3 +-
 .../CodeGen/AMDGPU/float-to-arbitrary-fp.ll   |  905 +++++++++++
 .../CodeGen/NVPTX/float-to-arbitrary-fp.ll    | 1028 +++++++++++++
 .../X86/float-to-arbitrary-fp-error.ll        |   76 +
 .../test/CodeGen/X86/float-to-arbitrary-fp.ll | 1323 +++++++++++++++++
 14 files changed, 3970 insertions(+), 24 deletions(-)
 create mode 100644 llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
 create mode 100644 llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
 create mode 100644 llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll
 create mode 100644 llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 8a8a9ee71ca02..de9835ee43836 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1020,6 +1020,15 @@ enum NodeType {
   /// The second operand is a constant indicating the source FP semantics.
   CONVERT_FROM_ARBITRARY_FP,
 
+  /// CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary
+  /// floating-point format, returning the result as an integer.
+  /// The first operand is the source value.
+  /// The second operand is a constant indicating the destination FP semantics.
+  /// The third operand is a constant indication the rounding mode.
+  /// The last operand is a boolean consant indicating whether the result has
+  /// to be saturated.
+  CONVERT_TO_ARBITRARY_FP,
+
   /// Perform various unary floating-point operations inspired by libm. For
   /// FPOWI, the result is undefined if the integer operand doesn't fit into
   /// sizeof(int).
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 54d86dfbfa303..7dcc3a1f1c753 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3782,6 +3782,479 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     Results.push_back(Result);
     break;
   }
+  case ISD::CONVERT_TO_ARBITRARY_FP: {
+    // Expand conversion from a native IEEE float type to an arbitrary FP
+    // format, returning the result as an integer using bit manipulation.
+    //
+    // TODO: currently only conversions to FP4, FP6 and FP8 formats from OCP
+    // specification are expanded. Remaining arbitrary FP types: Float8E4M3,
+    // Float8E3M4, Float8E5M2FNUZ, Float8E4M3FNUZ, Float8E4M3B11FNUZ,
+    // Float8E8M0FNU.
+    EVT ResVT = Node->getValueType(0);
+
+    SDValue FloatVal = Node->getOperand(0);
+    const uint64_t SemEnum = Node->getConstantOperandVal(1);
+    const auto Sem = static_cast<APFloatBase::Semantics>(SemEnum);
+    const auto RoundMode =
+        static_cast<RoundingMode>(Node->getConstantOperandVal(2));
+    const bool Saturate = Node->getConstantOperandVal(3) != 0;
+
+    // Supported destination formats.
+    switch (Sem) {
+    case APFloatBase::S_Float8E5M2:
+    case APFloatBase::S_Float8E4M3FN:
+    case APFloatBase::S_Float6E3M2FN:
+    case APFloatBase::S_Float6E2M3FN:
+    case APFloatBase::S_Float4E2M1FN:
+      break;
+    default:
+      DAG.getContext()->emitError("CONVERT_TO_ARBITRARY_FP: not implemented "
+                                  "destination format (semantics enum " +
+                                  Twine(SemEnum) + ")");
+      Results.push_back(DAG.getPOISON(ResVT));
+      break;
+    }
+    if (!Results.empty())
+      break;
+
+    // Destination format parameters.
+    const fltSemantics &DstSem = APFloatBase::EnumToSemantics(Sem);
+    const unsigned DstBits = APFloat::getSizeInBits(DstSem);
+    const unsigned DstPrecision = APFloat::semanticsPrecision(DstSem);
+    const unsigned DstMant = DstPrecision - 1;
+    const unsigned DstExpBits = DstBits - DstMant - 1;
+    const int DstBias = 1 - APFloat::semanticsMinExponent(DstSem);
+    const unsigned DstExpMax = (1U << DstExpBits) - 1;
+    const uint64_t DstMantMask = (DstMant > 0) ? ((1ULL << DstMant) - 1) : 0;
+    const fltNonfiniteBehavior DstNFBehavior = DstSem.nonFiniteBehavior;
+    const fltNanEncoding DstNanEnc = DstSem.nanEncoding;
+
+    // Compute the maximum normal exponent for the destination format.
+    unsigned DstExpMaxNormal;
+    if (DstNFBehavior == fltNonfiniteBehavior::IEEE754)
+      DstExpMaxNormal = DstExpMax - 1;
+    else
+      DstExpMaxNormal = DstExpMax;
+
+    // For NanOnly formats the max exponent field for finite values
+    // is DstExpMax, but the encoding with exp = DstExpMax and
+    // mant = all-ones is NaN. So DstExpMaxNormal = DstExpMax, but max
+    // mantissa at that exponent is DstMantMask - 1 (if NanEnc == AllOnes) to
+    // avoid the NaN encoding.
+    uint64_t DstMaxMantAtMaxExp = DstMantMask;
+    if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
+        DstNanEnc == fltNanEncoding::AllOnes)
+      DstMaxMantAtMaxExp = DstMantMask - 1;
+
+    // Source format parameters.
+    EVT SrcVT = FloatVal.getValueType();
+    const fltSemantics &SrcSem = SrcVT.getFltSemantics();
+    const unsigned SrcBits = APFloat::getSizeInBits(SrcSem);
+    const unsigned SrcPrecision = APFloat::semanticsPrecision(SrcSem);
+    const unsigned SrcMant = SrcPrecision - 1;
+    const unsigned SrcExpBits = SrcBits - SrcMant - 1;
+    const int SrcBias = 1 - APFloat::semanticsMinExponent(SrcSem);
+    const uint64_t SrcMantMask = (1ULL << SrcMant) - 1;
+    const uint64_t SrcExpMask = (1ULL << SrcExpBits) - 1;
+
+    // Work in the source integer type.
+    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), SrcBits);
+    EVT SetCCVT = getSetCCResultType(IntVT);
+
+    SDValue Zero = DAG.getConstant(0, dl, IntVT);
+    SDValue One = DAG.getConstant(1, dl, IntVT);
+
+    // Bitcast source float to integer and extract bit fields.
+    SDValue Src = DAG.getNode(ISD::BITCAST, dl, IntVT, FloatVal);
+    SDValue SrcMantField = DAG.getNode(ISD::AND, dl, IntVT, Src,
+                                       DAG.getConstant(SrcMantMask, dl, IntVT));
+
+    SDValue SrcExpField = DAG.getNode(
+        ISD::AND, dl, IntVT,
+        DAG.getNode(ISD::SRL, dl, IntVT, Src,
+                    DAG.getShiftAmountConstant(SrcMant, IntVT, dl)),
+        DAG.getConstant(SrcExpMask, dl, IntVT));
+
+    SDValue SignBit =
+        DAG.getNode(ISD::SRL, dl, IntVT, Src,
+                    DAG.getShiftAmountConstant(SrcBits - 1, IntVT, dl));
+
+    // Classify the input value.
+    SDValue SrcExpAllOnes = DAG.getConstant(SrcExpMask, dl, IntVT);
+    SDValue IsExpAllOnes =
+        DAG.getSetCC(dl, SetCCVT, SrcExpField, SrcExpAllOnes, ISD::SETEQ);
+    SDValue IsExpZero =
+        DAG.getSetCC(dl, SetCCVT, SrcExpField, Zero, ISD::SETEQ);
+    SDValue IsMantZero =
+        DAG.getSetCC(dl, SetCCVT, SrcMantField, Zero, ISD::SETEQ);
+    SDValue IsMantNonZero =
+        DAG.getSetCC(dl, SetCCVT, SrcMantField, Zero, ISD::SETNE);
+
+    // If source is IEEE fp, tehn NaN = exp_all_ones && mant != 0.
+    SDValue IsNaN =
+        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpAllOnes, IsMantNonZero);
+    // Inf = exp_all_ones && mant == 0.
+    SDValue IsInf =
+        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpAllOnes, IsMantZero);
+    // Zero = exp == 0 && mant == 0.
+    SDValue IsZero =
+        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantZero);
+    // Source denorm = exp == 0 && mant != 0.
+    SDValue IsSrcDenorm =
+        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantNonZero);
+
+    // Source denormal normalization.
+    // For a source denormal, the true exponent is (1 - SrcBias) and the
+    // mantissa has no implicit leading 1. Normalize by finding the position
+    // of the leading 1 in the mantissa.
+    SDValue LeadingZeros =
+        DAG.getNode(ISD::CTLZ_ZERO_UNDEF, dl, IntVT, SrcMantField);
+
+    // normShift = LeadingZeros - (SrcBits - 1 - SrcMant).
+    const unsigned LZOffset = SrcBits - 1 - SrcMant;
+    SDValue NormShift = DAG.getNode(ISD::SUB, dl, IntVT, LeadingZeros,
+                                    DAG.getConstant(LZOffset, dl, IntVT));
+
+    // Normalized mantissa.
+    SDValue NormMant =
+        DAG.getNode(ISD::AND, dl, IntVT,
+                    DAG.getNode(ISD::SHL, dl, IntVT, SrcMantField, NormShift),
+                    DAG.getConstant(SrcMantMask, dl, IntVT));
+
+    // effective_exp = 1 - NormShift.
+    SDValue DenormSrcExp =
+        DAG.getNode(ISD::SUB, dl, IntVT, One, NormShift);
+
+    // Select between normal and denorm source.
+    SDValue EffSrcExp =
+        DAG.getSelect(dl, IntVT, IsSrcDenorm, DenormSrcExp, SrcExpField);
+    SDValue EffSrcMant =
+        DAG.getSelect(dl, IntVT, IsSrcDenorm, NormMant, SrcMantField);
+
+    // Compute new biased exponent for destination.
+    // new_exp = src_exp - SrcBias + DstBias
+    const int BiasAdjust = DstBias - SrcBias;
+    SDValue NewExp = DAG.getNode(
+        ISD::ADD, dl, IntVT, EffSrcExp,
+        DAG.getConstant(APInt(SrcBits, BiasAdjust, true), dl, IntVT));
+
+    // Compute rounding increment given the round bit, sticky bits, and LSB
+    // of the truncated mantissa.
+    auto ComputeRoundUp = [&](SDValue RoundBit, SDValue StickyBits,
+                              SDValue LSB) -> SDValue {
+      if (RoundMode == RoundingMode::NearestTiesToEven) {
+        // Round up if round_bit && (sticky || lsb)
+        SDValue StickyOrLSB = DAG.getNode(ISD::OR, dl, IntVT, StickyBits, LSB);
+        return DAG.getNode(ISD::AND, dl, IntVT, RoundBit, StickyOrLSB);
+      }
+      if (RoundMode == RoundingMode::TowardZero)
+        return Zero;
+      if (RoundMode == RoundingMode::TowardPositive) {
+        // Round up if positive and any truncated bits are set.
+        SDValue AnyTruncBits =
+            DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
+        SDValue HasTruncBits =
+            DAG.getSetCC(dl, SetCCVT, AnyTruncBits, Zero, ISD::SETNE);
+        SDValue IsPositive =
+            DAG.getSetCC(dl, SetCCVT, SignBit, Zero, ISD::SETEQ);
+        SDValue DoRound =
+            DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsPositive);
+        return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
+      }
+      if (RoundMode == RoundingMode::TowardNegative) {
+        // Round up if negative and any truncated bits are set (to -Inf).
+        SDValue AnyTruncBits =
+            DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
+        SDValue HasTruncBits =
+            DAG.getSetCC(dl, SetCCVT, AnyTruncBits, Zero, ISD::SETNE);
+        SDValue IsNegative =
+            DAG.getSetCC(dl, SetCCVT, SignBit, Zero, ISD::SETNE);
+        SDValue DoRound =
+            DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsNegative);
+        return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
+      }
+      if (RoundMode == RoundingMode::NearestTiesToAway)
+        return RoundBit;
+      llvm_unreachable("Unsupported rounding mode");
+    };
+
+    // Round mantissa from SrcMant bits to DstMant bits.
+    SDValue TruncMant;
+    SDValue RoundUp;
+    if (SrcMant > DstMant) {
+      const unsigned Shift = SrcMant - DstMant;
+      SDValue ShiftConst = DAG.getShiftAmountConstant(Shift, IntVT, dl);
+      TruncMant =
+          DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant, ShiftConst);
+
+      // Check bit at position Shift - 1 aka the round bit.
+      SDValue RoundBit;
+      if (Shift >= 1) {
+        RoundBit = DAG.getNode(
+            ISD::AND, dl, IntVT,
+            DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant,
+                        DAG.getShiftAmountConstant(Shift - 1, IntVT, dl)),
+            One);
+      } else {
+        RoundBit = Zero;
+      }
+
+      // OR of all bits below the round bit to get sticky bits.
+      SDValue StickyBits;
+      if (Shift >= 2) {
+        uint64_t StickyMask = (1ULL << (Shift - 1)) - 1;
+        StickyBits = DAG.getNode(ISD::AND, dl, IntVT, EffSrcMant,
+                                 DAG.getConstant(StickyMask, dl, IntVT));
+        StickyBits = DAG.getSetCC(dl, SetCCVT, StickyBits, Zero, ISD::SETNE);
+        StickyBits =
+            DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, StickyBits);
+      } else {
+        StickyBits = Zero;
+      }
+
+      // LSB of truncated mantissa.
+      SDValue LSB = DAG.getNode(ISD::AND, dl, IntVT, TruncMant, One);
+
+      RoundUp = ComputeRoundUp(RoundBit, StickyBits, LSB);
+    } else {
+      // If DstMant >= SrcMant, then no rounding needed, just shift left.
+      SDValue MantShift =
+          DAG.getShiftAmountConstant(DstMant - SrcMant, IntVT, dl);
+      TruncMant = DAG.getNode(ISD::SHL, dl, IntVT, EffSrcMant, MantShift);
+      RoundUp = Zero;
+    }
+
+    // Apply rounding.
+    SDValue RoundedMant =
+        DAG.getNode(ISD::ADD, dl, IntVT, TruncMant, RoundUp);
+
+    // Handle mantissa overflow from rounding.
+    // If rounded_mant > DstMantMask, carry into exponent.
+    SDValue MantOverflow = DAG.getSetCC(
+        dl, SetCCVT, RoundedMant,
+        DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
+    // On overflow: mant = 0, exp += 1.
+    SDValue AdjMant =
+        DAG.getSelect(dl, IntVT, MantOverflow, Zero, RoundedMant);
+    SDValue AdjExp = DAG.getNode(
+        ISD::ADD, dl, IntVT, NewExp,
+        DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, MantOverflow));
+
+    // Precompute sign shifted to MSB of destination.
+    SDValue SignShifted = DAG.getNode(
+        ISD::SHL, dl, IntVT, SignBit,
+        DAG.getShiftAmountConstant(DstBits - 1, IntVT, dl));
+
+    // Destination denormal conversion (when new_exp <= 0).
+    // Shift the mantissa right by 1 - new_exp additional bits and set the
+    // exponent field to 0.
+    SDValue ExpIsNeg =
+        DAG.getSetCC(dl, SetCCVT, AdjExp,
+                     DAG.getConstant(1, dl, IntVT), ISD::SETLT);
+
+    SDValue DenormResult;
+    {
+      // denorm_shift = 1 - NewExp.
+      SDValue DenormShift =
+          DAG.getNode(ISD::SUB, dl, IntVT, One, NewExp);
+
+      // full_src_mant = (1 << SrcMant) | EffSrcMant.
+      SDValue ImplicitOne = DAG.getNode(
+          ISD::SHL, dl, IntVT, One,
+          DAG.getShiftAmountConstant(SrcMant, IntVT, dl));
+      SDValue FullSrcMant =
+          DAG.getNode(ISD::OR, dl, IntVT, EffSrcMant, ImplicitOne);
+
+      // Total right shift = (SrcMant - DstMant) + DenormShift
+      SDValue TotalShift;
+      if (SrcMant >= DstMant) {
+        TotalShift =
+            DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
+                        DAG.getConstant(SrcMant - DstMant, dl, IntVT));
+      } else {
+        TotalShift =
+            DAG.getNode(ISD::SUB, dl, IntVT, DenormShift,
+                        DAG.getConstant(DstMant - SrcMant, dl, IntVT));
+      }
+
+      // Clamp total shift to avoid UB, then trancate denorm mantissa.
+      SDValue MaxShift = DAG.getConstant(SrcBits - 1, dl, IntVT);
+      SDValue ClampedShift = DAG.getNode(ISD::UMIN, dl, IntVT, TotalShift,
+                                         MaxShift);
+      SDValue DenormTruncMant =
+          DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, ClampedShift);
+
+      // Rounding for denorm path.
+      SDValue DenormRoundUp;
+      {
+        // Round bit is at position TotalShift - 1 of FullSrcMant.
+        // Clamp to at least 1 so the subtraction doesn't underflow and create
+        // shift nodes with invalid shift amounts.
+        SDValue SafeShift =
+            DAG.getNode(ISD::UMAX, dl, IntVT, ClampedShift, One);
+        SDValue RoundBitPos =
+            DAG.getNode(ISD::SUB, dl, IntVT, SafeShift, One);
+        SDValue DenormRoundBit = DAG.getNode(
+            ISD::AND, dl, IntVT,
+            DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, RoundBitPos), One);
+
+        // Sticky: all bits below round bit.
+        // sticky_mask = (1 << RoundBitPos) - 1
+        SDValue StickyMask = DAG.getNode(
+            ISD::SUB, dl, IntVT,
+            DAG.getNode(ISD::SHL, dl, IntVT, One, RoundBitPos), One);
+        SDValue DenormStickyBits =
+            DAG.getNode(ISD::AND, dl, IntVT, FullSrcMant, StickyMask);
+        SDValue HasSticky =
+            DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT,
+                        DAG.getSetCC(dl, SetCCVT, DenormStickyBits, Zero,
+                                     ISD::SETNE));
+
+        SDValue DenormLSB =
+            DAG.getNode(ISD::AND, dl, IntVT, DenormTruncMant, One);
+
+        DenormRoundUp =
+            ComputeRoundUp(DenormRoundBit, HasSticky, DenormLSB);
+
+        // Only apply rounding if TotalShift >= 1 (i.e., there are bits to
+        // round).
+        SDValue ShiftGEOne =
+            DAG.getSetCC(dl, SetCCVT, ClampedShift, One, ISD::SETUGE);
+        DenormRoundUp = DAG.getSelect(dl, IntVT, ShiftGEOne, DenormRoundUp,
+                                      Zero);
+      }
+
+      SDValue DenormRoundedMant =
+          DAG.getNode(ISD::ADD, dl, IntVT, DenormTruncMant, DenormRoundUp);
+
+      // If rounding caused overflow into the normal range, then we get the
+      // smallest normal number.
+      SDValue DenormMantOF = DAG.getSetCC(
+          dl, SetCCVT, DenormRoundedMant,
+          DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
+      SDValue DenormFinalMant = DAG.getSelect(
+          dl, IntVT, DenormMantOF, Zero, DenormRoundedMant);
+      SDValue DenormFinalExp = DAG.getSelect(
+          dl, IntVT, DenormMantOF, One, Zero);
+
+      // Assemble: sign | (exp << DstMant) | mant
+      SDValue DenormExpShifted = DAG.getNode(
+          ISD::SHL, dl, IntVT, DenormFinalExp,
+          DAG.getShiftAmountConstant(DstMant, IntVT, dl));
+      DenormResult = DAG.getNode(
+          ISD::OR, dl, IntVT,
+          DAG.getNode(ISD::OR, dl, IntVT, SignShifted, DenormExpShifted),
+          DenormFinalMant);
+
+      // If the value is to small for even a denorm (all mantissa bits
+      // shifted away), handle based on rounding mode.
+      // This is covered by the DenormRoundedMant = 0 case naturally.
+    }
+
+    // Exponent overflow detection.
+    SDValue ExpOF = DAG.getSetCC(
+        dl, SetCCVT, AdjExp,
+        DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETGT);
+
+    // Also check if AdjExp == DstExpMaxNormal and mantissa overflow into
+    // a value that exceeds the max allowed mantissa at that exponent.
+    SDValue ExpAtMax = DAG.getSetCC(
+        dl, SetCCVT, AdjExp,
+        DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETEQ);
+    SDValue MantExceedsMax = DAG.getSetCC(
+        dl, SetCCVT, AdjMant,
+        DAG.getConstant(DstMaxMantAtMaxExp, dl, IntVT), ISD::SETGT);
+    SDValue ExpMantOF =
+        DAG.getNode(ISD::AND, dl, SetCCVT, ExpAtMax, MantExceedsMax);
+    SDValue IsOverflow =
+        DAG.getNode(ISD::OR, dl, SetCCVT, ExpOF, ExpMantOF);
+
+    // Build overflow result.
+    SDValue OverflowResult;
+
+    if (Saturate) {
+      // Clamp to max finite value:
+      // sign | (DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp
+      uint64_t MaxFinite =
+          ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
+      OverflowResult =
+          DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                      DAG.getConstant(MaxFinite, dl, IntVT));
+    } else if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
+      // Produce infinity.
+      uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
+      OverflowResult =
+          DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                      DAG.getConstant(InfBits, dl, IntVT));
+    } else {
+      // Emit poison if no Inf in format and not saturating.
+      OverflowResult = DAG.getPOISON(IntVT);
+    }
+
+    // Assemble normal result: sign | (AdjExp << DstMant) | AdjMant
+    SDValue NormExpShifted = DAG.getNode(
+        ISD::SHL, dl, IntVT, AdjExp,
+        DAG.getShiftAmountConstant(DstMant, IntVT, dl));
+    SDValue NormResult = DAG.getNode(
+        ISD::OR, dl, IntVT,
+        DAG.getNode(ISD::OR, dl, IntVT, SignShifted, NormExpShifted), AdjMant);
+
+    // Build special-value results.
+    SDValue NaNResult;
+    if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
+      // Produce canonical NaN.
+      const uint64_t QNaNBit = (DstMant > 0) ? (1ULL << (DstMant - 1)) : 0;
+      NaNResult =
+          DAG.getConstant(((uint64_t)DstExpMax << DstMant) | QNaNBit, dl,
+                          IntVT);
+    } else if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
+               DstNanEnc == fltNanEncoding::AllOnes) {
+      // E4M3FN-style: NaN is exp=all-ones, mant=all-ones.
+      NaNResult =
+          DAG.getConstant(((uint64_t)DstExpMax << DstMant) | DstMantMask, dl,
+                          IntVT);
+    } else {
+      // NaN -> poison for finite only values.
+      NaNResult = DAG.getPOISON(IntVT);
+    }
+
+    // Inf handling.
+    SDValue InfResult;
+    if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
+      // Produce signed infinity.
+      uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
+      InfResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                              DAG.getConstant(InfBits, dl, IntVT));
+    } else if (Saturate) {
+      // Inf saturates to max finite.
+      uint64_t MaxFinite =
+          ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
+      InfResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                              DAG.getConstant(MaxFinite, dl, IntVT));
+    } else {
+      // No Inf and not saturating -> poison.
+      InfResult = DAG.getPOISON(IntVT);
+    }
+
+    SDValue ZeroResult = SignShifted;
+
+    // Final selection in an order: NaN takes priority, then Inf, then Zero.
+    SDValue FiniteResult = DAG.getSelect(dl, IntVT, ExpIsNeg, DenormResult,
+                                         NormResult);
+    FiniteResult =
+        DAG.getSelect(dl, IntVT, IsOverflow, OverflowResult, FiniteResult);
+
+    SDValue Result = FiniteResult;
+    Result = DAG.getSelect(dl, IntVT, IsZero, ZeroResult, Result);
+    Result = DAG.getSelect(dl, IntVT, IsInf, InfResult, Result);
+    Result = DAG.getSelect(dl, IntVT, IsNaN, NaNResult, Result);
+
+    // Truncate to destination integer type.
+    Result = DAG.getZExtOrTrunc(Result, dl, ResVT);
+
+    Results.push_back(Result);
+    break;
+  }
   case ISD::FCANONICALIZE: {
     SDValue Mul = TLI.expandFCANONICALIZE(Node, DAG);
     Results.push_back(Mul);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 25f4f75eaedea..65a031027b4b1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -3194,6 +3194,8 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
   case ISD::FP_TO_SINT_SAT:
   case ISD::FP_TO_UINT_SAT:
                         Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
+  case ISD::CONVERT_TO_ARBITRARY_FP:
+                        Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(N); break;
   case ISD::STRICT_FP_EXTEND:
   case ISD::FP_EXTEND:  Res = SoftPromoteHalfOp_FP_EXTEND(N); break;
   case ISD::SELECT_CC:  Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break;
@@ -3309,6 +3311,24 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
                      N->getOperand(1));
 }
 
+// TODO: CONVERT_TO_ARBITRARY_FP also needs SoftenFloatOperand and
+// ExpandFloatOperand handlers for targets with software float or ppcf128
+// source types. Same gap exists for CONVERT_FROM_ARBITRARY_FP.
+SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
+    SDNode *N) {
+  EVT RVT = N->getValueType(0);
+  SDValue Op = N->getOperand(0);
+  EVT SVT = Op.getValueType();
+  SDLoc dl(N);
+
+  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType());
+  Op = GetSoftPromotedHalf(Op);
+  SDValue Res = DAG.getNode(GetPromotionOpcode(SVT, RVT), dl, NVT, Op);
+
+  return DAG.getNode(ISD::CONVERT_TO_ARBITRARY_FP, dl, N->getValueType(0), Res,
+                     N->getOperand(1), N->getOperand(2), N->getOperand(3));
+}
+
 SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SELECT_CC(SDNode *N,
                                                       unsigned OpNo) {
   assert(OpNo == 0 && "Can only soften the comparison values");
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 238eba021c124..a87471c766911 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -196,6 +196,9 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::FP_TO_FP16:
     Res = PromoteIntRes_FP_TO_FP16_BF16(N);
     break;
+  case ISD::CONVERT_TO_ARBITRARY_FP:
+    Res = PromoteIntRes_CONVERT_TO_ARBITRARY_FP(N);
+    break;
   case ISD::STRICT_FP_TO_BF16:
   case ISD::STRICT_FP_TO_FP16:
     Res = PromoteIntRes_STRICT_FP_TO_FP16_BF16(N);
@@ -952,6 +955,16 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_FP16_BF16(SDNode *N) {
   return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
 }
 
+// TODO: CONVERT_TO_ARBITRARY_FP also needs an ExpandIntegerResult handler for
+// wider arbitrary FP formats whose integer result requires expansion.
+SDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_TO_ARBITRARY_FP(SDNode *N) {
+  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+  SDLoc dl(N);
+
+  return DAG.getNode(ISD::CONVERT_TO_ARBITRARY_FP, dl, NVT, N->getOperand(0),
+                     N->getOperand(1), N->getOperand(2), N->getOperand(3));
+}
+
 SDValue DAGTypeLegalizer::PromoteIntRes_STRICT_FP_TO_FP16_BF16(SDNode *N) {
   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
   SDLoc dl(N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 84c91a80ade79..52c6a2bc1ac43 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -313,6 +313,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue PromoteIntRes_FP_TO_XINT(SDNode *N);
   SDValue PromoteIntRes_FP_TO_XINT_SAT(SDNode *N);
   SDValue PromoteIntRes_FP_TO_FP16_BF16(SDNode *N);
+  SDValue PromoteIntRes_CONVERT_TO_ARBITRARY_FP(SDNode *N);
   SDValue PromoteIntRes_STRICT_FP_TO_FP16_BF16(SDNode *N);
   SDValue PromoteIntRes_XRINT(SDNode *N);
   SDValue PromoteIntRes_FREEZE(SDNode *N);
@@ -804,6 +805,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue SoftPromoteHalfOp_FP_EXTEND(SDNode *N);
   SDValue SoftPromoteHalfOp_Op0WithStrict(SDNode *N);
   SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N);
+  SDValue SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(SDNode *N);
   SDValue SoftPromoteHalfOp_SETCC(SDNode *N);
   SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);
   SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo);
@@ -846,6 +848,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N);
   SDValue ScalarizeVecRes_FP_ROUND(SDNode *N);
   SDValue ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(SDNode *N);
+  SDValue ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(SDNode *N);
   SDValue ScalarizeVecRes_UnaryOpWithExtraInput(SDNode *N);
   SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
   SDValue ScalarizeVecRes_LOAD(LoadSDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index ccad9354fc820..49165abfc3223 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -464,6 +464,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
   case ISD::SMULO:
   case ISD::UMULO:
   case ISD::CONVERT_FROM_ARBITRARY_FP:
+  case ISD::CONVERT_TO_ARBITRARY_FP:
   case ISD::FCANONICALIZE:
   case ISD::FFREXP:
   case ISD::FMODF:
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index f3ddb9e4b811e..7a14d855e275c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -65,6 +65,9 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::CONVERT_FROM_ARBITRARY_FP:
     R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(N);
     break;
+  case ISD::CONVERT_TO_ARBITRARY_FP:
+    R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(N);
+    break;
   case ISD::AssertZext:
   case ISD::AssertSext:
   case ISD::FPOWI:
@@ -529,6 +532,22 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(SDNode *N) {
                      N->getOperand(1));
 }
 
+SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(SDNode *N) {
+  SDLoc DL(N);
+  SDValue Op = N->getOperand(0);
+  EVT OpVT = Op.getValueType();
+  // The result needs scalarizing, but it's not a given that the source does.
+  if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
+    Op = GetScalarizedVector(Op);
+  } else {
+    EVT VT = OpVT.getVectorElementType();
+    Op = DAG.getExtractVectorElt(DL, VT, Op, 0);
+  }
+  return DAG.getNode(ISD::CONVERT_TO_ARBITRARY_FP, DL,
+                     N->getValueType(0).getVectorElementType(), Op,
+                     N->getOperand(1), N->getOperand(2), N->getOperand(3));
+}
+
 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(SDNode *N) {
   SDValue Op = GetScalarizedVector(N->getOperand(0));
   return DAG.getNode(N->getOpcode(), SDLoc(N), Op.getValueType(), Op,
@@ -872,6 +891,17 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
   case ISD::CONVERT_FROM_ARBITRARY_FP:
     Res = ScalarizeVecOp_UnaryOpWithExtraInput(N);
     break;
+  case ISD::CONVERT_TO_ARBITRARY_FP: {
+    assert(N->getValueType(0).getVectorNumElements() == 1 &&
+           "Unexpected vector type!");
+    SDValue Elt = GetScalarizedVector(N->getOperand(0));
+    SDValue Op = DAG.getNode(N->getOpcode(), SDLoc(N),
+                             N->getValueType(0).getScalarType(), Elt,
+                             N->getOperand(1), N->getOperand(2),
+                             N->getOperand(3));
+    Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Op);
+    break;
+  }
   case ISD::STRICT_SINT_TO_FP:
   case ISD::STRICT_UINT_TO_FP:
   case ISD::STRICT_FP_TO_SINT:
@@ -1475,6 +1505,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::FCANONICALIZE:
   case ISD::AssertNoFPClass:
   case ISD::CONVERT_FROM_ARBITRARY_FP:
+  case ISD::CONVERT_TO_ARBITRARY_FP:
     SplitVecRes_UnaryOp(N, Lo, Hi);
     break;
   case ISD::ADDRSPACECAST:
@@ -2898,6 +2929,13 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
 
   const SDNodeFlags Flags = N->getFlags();
   unsigned Opcode = N->getOpcode();
+  if (Opcode == ISD::CONVERT_TO_ARBITRARY_FP) {
+    Lo = DAG.getNode(Opcode, dl, LoVT, Lo, N->getOperand(1),
+                     N->getOperand(2), N->getOperand(3), Flags);
+    Hi = DAG.getNode(Opcode, dl, HiVT, Hi, N->getOperand(1),
+                     N->getOperand(2), N->getOperand(3), Flags);
+    return;
+  }
   if (N->getNumOperands() <= 2) {
     if (Opcode == ISD::FP_ROUND || Opcode == ISD::AssertNoFPClass ||
         Opcode == ISD::CONVERT_FROM_ARBITRARY_FP) {
@@ -3715,6 +3753,7 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
   case ISD::VP_FP_ROUND:
   case ISD::FP_ROUND:
   case ISD::CONVERT_FROM_ARBITRARY_FP:
+  case ISD::CONVERT_TO_ARBITRARY_FP:
     Res = SplitVecOp_FP_ROUND(N);
     break;
   case ISD::FCOPYSIGN:         Res = SplitVecOp_FPOpDifferentTypes(N); break;
@@ -4855,6 +4894,11 @@ SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) {
         DAG.SplitEVL(N->getOperand(2), N->getValueType(0), DL);
     Lo = DAG.getNode(ISD::VP_FP_ROUND, DL, OutVT, Lo, MaskLo, EVLLo);
     Hi = DAG.getNode(ISD::VP_FP_ROUND, DL, OutVT, Hi, MaskHi, EVLHi);
+  } else if (N->getOpcode() == ISD::CONVERT_TO_ARBITRARY_FP) {
+    Lo = DAG.getNode(N->getOpcode(), DL, OutVT, Lo, N->getOperand(1),
+                     N->getOperand(2), N->getOperand(3));
+    Hi = DAG.getNode(N->getOpcode(), DL, OutVT, Hi, N->getOperand(1),
+                     N->getOperand(2), N->getOperand(3));
   } else {
     Lo = DAG.getNode(N->getOpcode(), DL, OutVT, Lo, N->getOperand(1));
     Hi = DAG.getNode(N->getOpcode(), DL, OutVT, Hi, N->getOperand(1));
@@ -5294,6 +5338,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::ZERO_EXTEND:
   case ISD::VP_ZERO_EXTEND:
   case ISD::CONVERT_FROM_ARBITRARY_FP:
+  case ISD::CONVERT_TO_ARBITRARY_FP:
     Res = WidenVecRes_Convert(N);
     break;
 
@@ -5863,20 +5908,27 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
   EVT InWidenVT = EVT::getVectorVT(Ctx, InEltVT, WidenEC);
   ElementCount InVTEC = InVT.getVectorElementCount();
 
+  // Helper to build node with all scalar trailing operands.
+  auto MakeConvertNode = [&](EVT VT, SDValue Op) -> SDValue {
+    if (N->getNumOperands() == 1)
+      return DAG.getNode(Opcode, DL, VT, Op, Flags);
+    if (Opcode == ISD::CONVERT_TO_ARBITRARY_FP)
+      return DAG.getNode(Opcode, DL, VT, Op, N->getOperand(1),
+                         N->getOperand(2), N->getOperand(3), Flags);
+    return DAG.getNode(Opcode, DL, VT, Op, N->getOperand(1), Flags);
+  };
+
   if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
     InOp = GetWidenedVector(N->getOperand(0));
     InVT = InOp.getValueType();
     InVTEC = InVT.getVectorElementCount();
     if (InVTEC == WidenEC) {
-      if (N->getNumOperands() == 1)
-        return DAG.getNode(Opcode, DL, WidenVT, InOp, Flags);
-      if (N->getNumOperands() == 3) {
-        assert(N->isVPOpcode() && "Expected VP opcode");
+      if (N->getNumOperands() == 3 && N->isVPOpcode()) {
         SDValue Mask =
             GetWidenedMask(N->getOperand(1), WidenVT.getVectorElementCount());
         return DAG.getNode(Opcode, DL, WidenVT, InOp, Mask, N->getOperand(2));
       }
-      return DAG.getNode(Opcode, DL, WidenVT, InOp, N->getOperand(1), Flags);
+      return MakeConvertNode(WidenVT, InOp);
     }
     if (WidenVT.getSizeInBits() == InVT.getSizeInBits()) {
       // If both input and result vector types are of same width, extend
@@ -5919,17 +5971,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
       SmallVector<SDValue, 16> Ops(NumConcat, DAG.getPOISON(InVT));
       Ops[0] = InOp;
       SDValue InVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InWidenVT, Ops);
-      if (N->getNumOperands() == 1)
-        return DAG.getNode(Opcode, DL, WidenVT, InVec, Flags);
-      return DAG.getNode(Opcode, DL, WidenVT, InVec, N->getOperand(1), Flags);
+      return MakeConvertNode(WidenVT, InVec);
     }
 
     if (InVTEC.isKnownMultipleOf(WidenEC.getKnownMinValue())) {
       SDValue InVal = DAG.getExtractSubvector(DL, InWidenVT, InOp, 0);
       // Extract the input and convert the shorten input vector.
-      if (N->getNumOperands() == 1)
-        return DAG.getNode(Opcode, DL, WidenVT, InVal, Flags);
-      return DAG.getNode(Opcode, DL, WidenVT, InVal, N->getOperand(1), Flags);
+      return MakeConvertNode(WidenVT, InVal);
     }
   }
 
@@ -5941,10 +5989,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
   unsigned MinElts = N->getValueType(0).getVectorNumElements();
   for (unsigned i=0; i < MinElts; ++i) {
     SDValue Val = DAG.getExtractVectorElt(DL, InEltVT, InOp, i);
-    if (N->getNumOperands() == 1)
-      Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, Flags);
-    else
-      Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, N->getOperand(1), Flags);
+    Ops[i] = MakeConvertNode(EltVT, Val);
   }
 
   return DAG.getBuildVector(WidenVT, DL, Ops);
@@ -7444,6 +7489,7 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
   case ISD::STRICT_UINT_TO_FP:
   case ISD::TRUNCATE:
   case ISD::CONVERT_FROM_ARBITRARY_FP:
+  case ISD::CONVERT_TO_ARBITRARY_FP:
     Res = WidenVecOp_Convert(N);
     break;
 
@@ -7648,6 +7694,16 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
   EVT InVT = InOp.getValueType();
   unsigned Opcode = N->getOpcode();
 
+  // Helper to build a convert node with all scalar trailing operands.
+  auto MakeConvertNode = [&](EVT VT, SDValue Op) -> SDValue {
+    if (Opcode == ISD::CONVERT_TO_ARBITRARY_FP)
+      return DAG.getNode(Opcode, dl, VT, Op, N->getOperand(1),
+                         N->getOperand(2), N->getOperand(3));
+    if (Opcode == ISD::FP_ROUND || Opcode == ISD::CONVERT_FROM_ARBITRARY_FP)
+      return DAG.getNode(Opcode, dl, VT, Op, N->getOperand(1));
+    return DAG.getNode(Opcode, dl, VT, Op);
+  };
+
   // See if a widened result type would be legal, if so widen the node.
   // FIXME: This isn't safe for StrictFP. Other optimization here is needed.
   EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
@@ -7665,10 +7721,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
       // use the new one.
       ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
     } else {
-      if (Opcode == ISD::FP_ROUND || Opcode == ISD::CONVERT_FROM_ARBITRARY_FP)
-        Res = DAG.getNode(Opcode, dl, WideVT, InOp, N->getOperand(1));
-      else
-        Res = DAG.getNode(Opcode, dl, WideVT, InOp);
+      Res = MakeConvertNode(WideVT, InOp);
     }
     return DAG.getExtractSubvector(dl, VT, Res, 0);
   }
@@ -7691,10 +7744,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
   } else {
     for (unsigned i = 0; i < NumElts; ++i) {
       SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
-      if (Opcode == ISD::FP_ROUND || Opcode == ISD::CONVERT_FROM_ARBITRARY_FP)
-        Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt, N->getOperand(1));
-      else
-        Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
+      Ops[i] = MakeConvertNode(EltVT, Elt);
     }
   }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 1f3b099c9c577..cc15e0c85148d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7194,6 +7194,49 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
                              SemConst));
     return;
   }
+  case Intrinsic::convert_to_arbitrary_fp: {
+    // Extract format metadata and convert to semantics enum.
+    EVT DstVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
+    Metadata *MD = cast<MetadataAsValue>(I.getArgOperand(1))->getMetadata();
+    StringRef FormatStr = cast<MDString>(MD)->getString();
+    const fltSemantics *DstSem =
+        APFloatBase::getArbitraryFPSemantics(FormatStr);
+    if (!DstSem) {
+      DAG.getContext()->emitError(
+          "convert_to_arbitrary_fp: not implemented format '" + FormatStr +
+          "'");
+      setValue(&I, DAG.getPOISON(DstVT));
+      return;
+    }
+    APFloatBase::Semantics SemEnum = APFloatBase::SemanticsToEnum(*DstSem);
+
+    Metadata *RoundMD =
+        cast<MetadataAsValue>(I.getArgOperand(2))->getMetadata();
+    StringRef RoundStr = cast<MDString>(RoundMD)->getString();
+    std::optional<RoundingMode> RoundMode =
+        convertStrToRoundingMode(RoundStr);
+    if (!RoundMode || *RoundMode == RoundingMode::Dynamic) {
+      DAG.getContext()->emitError(
+          "convert_to_arbitrary_fp: unsupported rounding mode '" + RoundStr +
+          "'");
+      setValue(&I, DAG.getPOISON(DstVT));
+      return;
+    }
+
+    uint64_t Saturate =
+        cast<ConstantInt>(I.getArgOperand(3))->getZExtValue() ? 1 : 0;
+
+    SDValue FloatVal = getValue(I.getArgOperand(0));
+
+    SDValue SemConst =
+        DAG.getTargetConstant(static_cast<int>(SemEnum), sdl, MVT::i32);
+    SDValue RoundConst =
+        DAG.getTargetConstant(static_cast<int>(*RoundMode), sdl, MVT::i32);
+    SDValue SatConst = DAG.getTargetConstant(Saturate, sdl, MVT::i32);
+    setValue(&I, DAG.getNode(ISD::CONVERT_TO_ARBITRARY_FP, sdl, DstVT,
+                             FloatVal, SemConst, RoundConst, SatConst));
+    return;
+  }
   case Intrinsic::set_rounding:
     Res = DAG.getNode(ISD::SET_ROUNDING, sdl, MVT::Other,
                       {getRoot(), getValue(I.getArgOperand(0))});
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index ce78072d21114..ebfa895d2ca91 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -436,6 +436,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
   case ISD::FP_TO_BF16:                 return "fp_to_bf16";
   case ISD::STRICT_FP_TO_BF16:          return "strict_fp_to_bf16";
   case ISD::CONVERT_FROM_ARBITRARY_FP:  return "convert_from_arbitrary_fp";
+  case ISD::CONVERT_TO_ARBITRARY_FP:    return "convert_to_arbitrary_fp";
   case ISD::LROUND:                     return "lround";
   case ISD::STRICT_LROUND:              return "strict_lround";
   case ISD::LLROUND:                    return "llround";
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 2f1e3f2f3ff7a..fbc821a42d899 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1149,7 +1149,8 @@ void TargetLoweringBase::initActions() {
                         ISD::FASIN,          ISD::FATAN,
                         ISD::FCOSH,          ISD::FSINH,
                         ISD::FTANH,          ISD::FATAN2,
-                        ISD::FMULADD,        ISD::CONVERT_FROM_ARBITRARY_FP},
+                        ISD::FMULADD,        ISD::CONVERT_FROM_ARBITRARY_FP,
+                        ISD::CONVERT_TO_ARBITRARY_FP},
                        VT, Expand);
 
     // Overflow operations default to expand
diff --git a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
new file mode 100644
index 0000000000000..45639b9d50ca9
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
@@ -0,0 +1,905 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 | FileCheck %s
+
+; Test llvm.convert.to.arbitrary.fp intrinsic expansion.
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+declare i6 @llvm.convert.to.arbitrary.fp.i6.f32(float, metadata, metadata, i1)
+declare i4 @llvm.convert.to.arbitrary.fp.i4.f32(float, metadata, metadata, i1)
+declare <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float>, metadata, metadata, i1)
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1)
+declare i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat, metadata, metadata, i1)
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
+
+; Float8E5M2
+; Layout: sign(1) exp(5) mant(2), bias=15
+; Supports: Inf, NaN, signed zero, denormals
+
+; Float8E5M2 normal: f32 1.0 -> 0_01111_00 = 0x3C
+define i8 @to_f8e5m2_normal() {
+; CHECK-LABEL: to_f8e5m2_normal:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 60
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 zero: f32 0.0 -> 0_00000_00 = 0x00
+define i8 @to_f8e5m2_zero() {
+; CHECK-LABEL: to_f8e5m2_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 negative zero: f32 -0.0 -> 1_00000_00 = 0x80
+define i8 @to_f8e5m2_neg_zero() {
+; CHECK-LABEL: to_f8e5m2_neg_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x80
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float -0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 +Inf: f32 Inf -> 0_11111_00 = 0x7C
+define i8 @to_f8e5m2_inf() {
+; CHECK-LABEL: to_f8e5m2_inf:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7c
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 NaN: f32 NaN -> qNaN
+define i8 @to_f8e5m2_nan() {
+; CHECK-LABEL: to_f8e5m2_nan:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7e
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 max: 57344.0 -> 0_11110_11 = 0x7B
+define i8 @to_f8e5m2_max() {
+; CHECK-LABEL: to_f8e5m2_max:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7b
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 57344.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 overflow (no saturation): 100000.0 -> Inf = 0x7C
+define i8 @to_f8e5m2_overflow() {
+; CHECK-LABEL: to_f8e5m2_overflow:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7c
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 overflow with saturation: 100000.0 -> max = 0x7B
+define i8 @to_f8e5m2_overflow_sat() {
+; CHECK-LABEL: to_f8e5m2_overflow_sat:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7b
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 true)
+  ret i8 %r
+}
+
+; Float8E5M2 denorm: very small value -> dst denorm
+define i8 @to_f8e5m2_denorm() {
+  ; 2^(-16) = 0x37800000 -> smallest E5M2 denorm 0_00000_01 = 0x01
+; CHECK-LABEL: to_f8e5m2_denorm:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 1
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x3EF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 runtime arg test
+define i8 @to_f8e5m2_dynamic(float %x) {
+; CHECK-LABEL: to_f8e5m2_dynamic:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffff, v0
+; CHECK-NEXT:    v_ffbh_u32_e32 v3, v1
+; CHECK-NEXT:    v_bfe_u32 v2, v0, 23, 8
+; CHECK-NEXT:    v_add_u32_e32 v4, -8, v3
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v2
+; CHECK-NEXT:    v_lshlrev_b32_e32 v4, v4, v1
+; CHECK-NEXT:    v_and_b32_e32 v4, 0x7fffff, v4
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
+; CHECK-NEXT:    v_and_b32_e32 v6, 0xfffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[6:7], 0, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
+; CHECK-NEXT:    v_and_or_b32 v6, v5, 1, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, 20, v4
+; CHECK-NEXT:    v_and_b32_e32 v6, v7, v6
+; CHECK-NEXT:    v_add_u32_e32 v5, v5, v6
+; CHECK-NEXT:    v_sub_u32_e32 v3, 9, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[6:7], 3, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v6, 0xffffff90
+; CHECK-NEXT:    v_addc_co_u32_e64 v6, s[4:5], v3, v6, s[6:7]
+; CHECK-NEXT:    v_sub_u32_e32 v3, 0x86, v3
+; CHECK-NEXT:    v_min_u32_e32 v3, 31, v3
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x800000, v4
+; CHECK-NEXT:    v_sub_u32_e64 v9, v3, 1 clamp
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_bfe_u32 v10, v4, 0, v9
+; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v3, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, v9, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, v4, s[4:5]
+; CHECK-NEXT:    v_add_u32_e32 v3, v8, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[6:7]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 2, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, s[4:5]
+; CHECK-NEXT:    v_or3_b32 v7, v0, v7, v5
+; CHECK-NEXT:    v_or3_b32 v3, v0, v4, v3
+; CHECK-NEXT:    v_cmp_gt_i32_e64 s[4:5], 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v7, v3, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], 30, v6
+; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 30, v6
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v0
+; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, v4, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
+; CHECK-NEXT:    s_movk_i32 s6, 0xff
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v1
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], s6, v2
+; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
+; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN (NanOnly, NanEncoding=AllOnes)
+; Layout: sign(1) exp(4) mant(3), maxExp=8, minExp=-6, bias=7
+; Only 0_1111_111 and 1_1111_111 are NaN; all other exp=15 values are finite.
+
+; Float8E4M3FN normal: f32 1.0 -> 0_0111_000 = 0x38
+define i8 @to_f8e4m3fn_normal() {
+; CHECK-LABEL: to_f8e4m3fn_normal:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 56
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN max: 448.0 -> 0_1111_110 = 0x7E
+define i8 @to_f8e4m3fn_max() {
+; CHECK-LABEL: to_f8e4m3fn_max:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7e
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 448.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN NaN: f32 NaN -> 0_1111_111 = 0x7F
+define i8 @to_f8e4m3fn_nan() {
+; CHECK-LABEL: to_f8e4m3fn_nan:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7f
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN overflow with saturation: 1000.0 -> max = 0x7E
+define i8 @to_f8e4m3fn_overflow_sat() {
+; CHECK-LABEL: to_f8e4m3fn_overflow_sat:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7e
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1000.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 true)
+  ret i8 %r
+}
+
+; Float6E3M2FN (FiniteOnly)
+; Layout: sign(1) exp(3) mant(2), bias=3, maxExp=4
+; No Inf, no NaN. All bit patterns are finite.
+
+; Float6E3M2FN normal: f32 1.0 -> 0_011_00 = 0x0C
+define i6 @to_f6e3m2fn_normal() {
+; CHECK-LABEL: to_f6e3m2fn_normal:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 12
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN max: 28.0 -> 0_111_11 = 0x1F
+define i6 @to_f6e3m2fn_max() {
+; CHECK-LABEL: to_f6e3m2fn_max:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 31
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 28.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN zero: f32 0.0 -> 0_000_00 = 0x00
+define i6 @to_f6e3m2fn_zero() {
+; CHECK-LABEL: to_f6e3m2fn_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 0.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN negative: f32 -1.0 -> 1_011_00
+define i6 @to_f6e3m2fn_negative() {
+; CHECK-LABEL: to_f6e3m2fn_negative:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 44
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float -1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E2M3FN (FiniteOnly)
+; Layout: sign(1) exp(2) mant(3), bias=1, maxExp=2
+; No Inf, no NaN. All bit patterns are finite.
+
+; Float6E2M3FN normal: f32 1.0 -> 0_01_000 = 0x08
+define i6 @to_f6e2m3fn_normal() {
+; CHECK-LABEL: to_f6e2m3fn_normal:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 8
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E2M3FN max: 7.5 -> 0_11_111 = 0x1F
+define i6 @to_f6e2m3fn_max() {
+; CHECK-LABEL: to_f6e2m3fn_max:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 31
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 7.5, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float4E2M1FN (FiniteOnly)
+; Layout: sign(1) exp(2) mant(1), bias=1, maxExp=2
+; No Inf, no NaN.
+
+; Float4E2M1FN normal: f32 1.0 -> 0_01_0 = 0x2
+define i4 @to_f4e2m1fn_normal() {
+; CHECK-LABEL: to_f4e2m1fn_normal:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 2
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 1.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Float4E2M1FN max: 6.0 -> 0_11_1 = 0x7
+define i4 @to_f4e2m1fn_max() {
+; CHECK-LABEL: to_f4e2m1fn_max:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 7
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 6.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Float4E2M1FN denorm: 0.5 -> 0_00_1 = 0x1
+define i4 @to_f4e2m1fn_denorm() {
+; CHECK-LABEL: to_f4e2m1fn_denorm:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 1
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 0.5, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Rounding mode tests
+
+; Round to nearest
+define i8 @to_f8e5m2_round_nearest() {
+; CHECK-LABEL: to_f8e5m2_round_nearest:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 62
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.5, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Round toward zero with runtime arg
+define i8 @to_f8e5m2_round_towardzero(float %x) {
+; CHECK-LABEL: to_f8e5m2_round_towardzero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffff, v0
+; CHECK-NEXT:    v_bfe_u32 v2, v0, 23, 8
+; CHECK-NEXT:    v_ffbh_u32_e32 v3, v1
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v2
+; CHECK-NEXT:    v_add_u32_e32 v4, -8, v3
+; CHECK-NEXT:    v_lshlrev_b32_e32 v4, v4, v1
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_sub_u32_e32 v3, 9, v3
+; CHECK-NEXT:    v_and_b32_e32 v4, 0x7fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
+; CHECK-NEXT:    v_sub_u32_e32 v6, 0x86, v3
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v4
+; CHECK-NEXT:    v_min_u32_e32 v6, 31, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 4, s[4:5]
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 21, v4
+; CHECK-NEXT:    v_or3_b32 v5, v0, v6, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v4
+; CHECK-NEXT:    v_mov_b32_e32 v6, 0xffffff90
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, s[4:5]
+; CHECK-NEXT:    v_addc_co_u32_e64 v3, s[4:5], v3, v6, s[4:5]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v6, 2, v3
+; CHECK-NEXT:    v_or3_b32 v6, v0, v6, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e64 s[4:5], 1, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v6, v5, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v4
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], 30, v3
+; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 30, v3
+; CHECK-NEXT:    v_or_b32_e32 v3, 0x7c, v0
+; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v5, v3, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
+; CHECK-NEXT:    s_movk_i32 s6, 0xff
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v4, v0, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v1
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], s6, v2
+; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v3, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
+; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
+  ret i8 %r
+}
+
+; Vector test: f32 <4 x float> -> <4 x i4> Float4E2M1FN
+define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f4e2m1fn_v4f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v0
+; CHECK-NEXT:    v_ffbh_u32_e32 v4, v5
+; CHECK-NEXT:    v_bfe_u32 v6, v0, 23, 8
+; CHECK-NEXT:    v_add_u32_e32 v7, -8, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0x7fffff, v7
+; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v5, v7, vcc
+; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 22, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v9, v9, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v10, 21, v7
+; CHECK-NEXT:    v_and_b32_e32 v9, v10, v9
+; CHECK-NEXT:    v_add_u32_e32 v8, v8, v9
+; CHECK-NEXT:    v_sub_u32_e32 v4, 9, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v9, v6, v4, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0xffffff82
+; CHECK-NEXT:    v_addc_co_u32_e64 v10, vcc, v9, v4, s[4:5]
+; CHECK-NEXT:    v_sub_u32_e32 v9, 0x95, v9
+; CHECK-NEXT:    v_min_u32_e32 v9, 31, v9
+; CHECK-NEXT:    v_or_b32_e32 v7, 0x800000, v7
+; CHECK-NEXT:    v_sub_u32_e64 v12, v9, 1 clamp
+; CHECK-NEXT:    v_lshrrev_b32_e32 v0, 28, v0
+; CHECK-NEXT:    v_bfe_u32 v13, v7, 0, v12
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, v8, 0, s[4:5]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v11, 1, v10
+; CHECK-NEXT:    v_and_b32_e32 v0, 8, v0
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v13
+; CHECK-NEXT:    v_or3_b32 v8, v0, v11, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v11, v9, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v13, v11, 1, v13
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, v12, v7
+; CHECK-NEXT:    v_and_b32_e32 v7, v7, v13
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v7, vcc
+; CHECK-NEXT:    v_add_u32_e32 v7, v11, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 2, vcc
+; CHECK-NEXT:    v_or3_b32 v7, v0, v9, v7
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v10
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v8, v7, vcc
+; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v7, v0, vcc
+; CHECK-NEXT:    v_ffbh_u32_e32 v7, v5
+; CHECK-NEXT:    v_bfe_u32 v6, v1, 23, 8
+; CHECK-NEXT:    v_add_u32_e32 v8, -8, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x7fffff, v8
+; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v8, v5, v8, vcc
+; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 22, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v10, v10, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v11, 21, v8
+; CHECK-NEXT:    v_and_b32_e32 v10, v11, v10
+; CHECK-NEXT:    v_add_u32_e32 v9, v9, v10
+; CHECK-NEXT:    v_sub_u32_e32 v7, 9, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v9
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v6, v7, vcc
+; CHECK-NEXT:    v_addc_co_u32_e64 v10, vcc, v7, v4, s[4:5]
+; CHECK-NEXT:    v_sub_u32_e32 v7, 0x95, v7
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v8, 0x800000, v8
+; CHECK-NEXT:    v_sub_u32_e64 v12, v7, 1 clamp
+; CHECK-NEXT:    v_lshrrev_b32_e32 v1, 28, v1
+; CHECK-NEXT:    v_bfe_u32 v13, v8, 0, v12
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, v9, 0, s[4:5]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v11, 1, v10
+; CHECK-NEXT:    v_and_b32_e32 v1, 8, v1
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v13
+; CHECK-NEXT:    v_or3_b32 v9, v1, v11, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v11, v7, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v13, v11, 1, v13
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v12, v8
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v13
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v8, vcc
+; CHECK-NEXT:    v_add_u32_e32 v7, v11, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
+; CHECK-NEXT:    v_or3_b32 v7, v1, v8, v7
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v10
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v9, v7, vcc
+; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v7, v1, vcc
+; CHECK-NEXT:    v_ffbh_u32_e32 v7, v5
+; CHECK-NEXT:    v_bfe_u32 v6, v2, 23, 8
+; CHECK-NEXT:    v_add_u32_e32 v8, -8, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x7fffff, v8
+; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v8, v5, v8, vcc
+; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 22, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v10, v10, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v11, 21, v8
+; CHECK-NEXT:    v_and_b32_e32 v10, v11, v10
+; CHECK-NEXT:    v_add_u32_e32 v9, v9, v10
+; CHECK-NEXT:    v_sub_u32_e32 v7, 9, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v9
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v6, v7, vcc
+; CHECK-NEXT:    v_addc_co_u32_e64 v10, vcc, v7, v4, s[4:5]
+; CHECK-NEXT:    v_sub_u32_e32 v7, 0x95, v7
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v8, 0x800000, v8
+; CHECK-NEXT:    v_sub_u32_e64 v12, v7, 1 clamp
+; CHECK-NEXT:    v_lshrrev_b32_e32 v2, 28, v2
+; CHECK-NEXT:    v_bfe_u32 v13, v8, 0, v12
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, v9, 0, s[4:5]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v11, 1, v10
+; CHECK-NEXT:    v_and_b32_e32 v2, 8, v2
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v13
+; CHECK-NEXT:    v_or3_b32 v9, v2, v11, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v11, v7, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v13, v11, 1, v13
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v12, v8
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v13
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v8, vcc
+; CHECK-NEXT:    v_add_u32_e32 v7, v11, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
+; CHECK-NEXT:    v_or3_b32 v7, v2, v8, v7
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v10
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v9, v7, vcc
+; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v7, v2, vcc
+; CHECK-NEXT:    v_ffbh_u32_e32 v7, v5
+; CHECK-NEXT:    v_bfe_u32 v6, v3, 23, 8
+; CHECK-NEXT:    v_add_u32_e32 v8, -8, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x7fffff, v8
+; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v8, v5, v8, vcc
+; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 22, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v10, v10, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v11, 21, v8
+; CHECK-NEXT:    v_and_b32_e32 v10, v11, v10
+; CHECK-NEXT:    v_add_u32_e32 v9, v9, v10
+; CHECK-NEXT:    v_sub_u32_e32 v7, 9, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v9
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, v6, v7, vcc
+; CHECK-NEXT:    v_addc_co_u32_e64 v4, vcc, v7, v4, s[4:5]
+; CHECK-NEXT:    v_sub_u32_e32 v7, 0x95, v7
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v8, 0x800000, v8
+; CHECK-NEXT:    v_sub_u32_e64 v11, v7, 1 clamp
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 28, v3
+; CHECK-NEXT:    v_bfe_u32 v12, v8, 0, v11
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, v9, 0, s[4:5]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v10, 1, v4
+; CHECK-NEXT:    v_and_b32_e32 v3, 8, v3
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v12
+; CHECK-NEXT:    v_or3_b32 v9, v3, v10, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v10, v7, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v12, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v12, v10, 1, v12
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v11, v8
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v12
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v8, vcc
+; CHECK-NEXT:    v_add_u32_e32 v7, v10, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
+; CHECK-NEXT:    v_or3_b32 v7, v3, v8, v7
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v9, v7, vcc
+; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v3, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret <4 x i4> %r
+}
+
+; Float8E5M2 from f16: half -> i8
+define i8 @to_f8e5m2_from_f16(half %x) {
+; CHECK-LABEL: to_f8e5m2_from_f16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x3ff, v0
+; CHECK-NEXT:    v_lshlrev_b32_e32 v3, 16, v1
+; CHECK-NEXT:    v_ffbh_u32_e32 v3, v3
+; CHECK-NEXT:    v_bfe_u32 v2, v0, 10, 5
+; CHECK-NEXT:    v_add_u16_e32 v4, -5, v3
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v2
+; CHECK-NEXT:    v_lshlrev_b16_e32 v4, v4, v1
+; CHECK-NEXT:    v_and_b32_e32 v4, 0x3ff, v4
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7f, v4
+; CHECK-NEXT:    v_mov_b32_e32 v5, 1
+; CHECK-NEXT:    v_cmp_ne_u16_e64 s[6:7], 0, v6
+; CHECK-NEXT:    v_and_b32_sdwa v5, v4, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_lshrrev_b16_e32 v6, 7, v4
+; CHECK-NEXT:    v_and_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_add_u16_sdwa v5, v4, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[6:7], 3, v5
+; CHECK-NEXT:    v_sub_u16_e32 v3, 6, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
+; CHECK-NEXT:    v_add_u16_e32 v6, v3, v6
+; CHECK-NEXT:    v_sub_u16_e32 v3, 9, v3
+; CHECK-NEXT:    v_min_u16_e32 v3, 15, v3
+; CHECK-NEXT:    v_sub_u16_e64 v10, v3, 1 clamp
+; CHECK-NEXT:    v_lshlrev_b16_e64 v11, v10, 1
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x400, v4
+; CHECK-NEXT:    v_add_u16_e32 v11, -1, v11
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_and_b32_e32 v11, v4, v11
+; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_lshrrev_b16_e32 v8, v3, v4
+; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v11
+; CHECK-NEXT:    v_and_b32_e32 v9, 1, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v9, v11, v9
+; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v10, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v9
+; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, v4, s[4:5]
+; CHECK-NEXT:    v_add_u16_e32 v3, v8, v3
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v3
+; CHECK-NEXT:    v_lshlrev_b16_e32 v7, 2, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v7, v0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v4, v0, v4
+; CHECK-NEXT:    v_or_b32_e32 v7, v7, v5
+; CHECK-NEXT:    v_or_b32_e32 v3, v4, v3
+; CHECK-NEXT:    v_cmp_gt_i16_e64 s[4:5], 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v7, v3, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v5
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], 30, v6
+; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 30, v6
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v0
+; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, v4, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v1
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], 31, v2
+; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
+; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 from bf16: bfloat -> i8
+define i8 @to_f8e5m2_from_bf16(bfloat %x) {
+; CHECK-LABEL: to_f8e5m2_from_bf16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7f, v0
+; CHECK-NEXT:    v_lshlrev_b32_e32 v3, 16, v1
+; CHECK-NEXT:    v_ffbh_u32_e32 v3, v3
+; CHECK-NEXT:    v_bfe_u32 v2, v0, 7, 8
+; CHECK-NEXT:    v_add_u16_e32 v4, -8, v3
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v2
+; CHECK-NEXT:    v_lshlrev_b16_e32 v4, v4, v1
+; CHECK-NEXT:    v_and_b32_e32 v4, 0x7f, v4
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
+; CHECK-NEXT:    v_and_b32_e32 v7, 15, v4
+; CHECK-NEXT:    v_lshrrev_b16_e32 v5, 5, v4
+; CHECK-NEXT:    v_cmp_ne_u16_e64 s[6:7], 0, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 1, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v6, v7, v6
+; CHECK-NEXT:    v_lshrrev_b16_e32 v7, 4, v4
+; CHECK-NEXT:    v_and_b32_e32 v6, v7, v6
+; CHECK-NEXT:    v_add_u16_e32 v5, v5, v6
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[6:7], 3, v5
+; CHECK-NEXT:    v_sub_u16_e32 v3, 9, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
+; CHECK-NEXT:    v_add_u16_e32 v6, v3, v6
+; CHECK-NEXT:    v_sub_u16_e32 v3, 0x76, v3
+; CHECK-NEXT:    v_min_u16_e32 v3, 15, v3
+; CHECK-NEXT:    v_sub_u16_e64 v10, v3, 1 clamp
+; CHECK-NEXT:    v_lshlrev_b16_e64 v11, v10, 1
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x80, v4
+; CHECK-NEXT:    v_add_u16_e32 v11, -1, v11
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_and_b32_e32 v11, v4, v11
+; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_lshrrev_b16_e32 v8, v3, v4
+; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v11
+; CHECK-NEXT:    v_and_b32_e32 v9, 1, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v9, v11, v9
+; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v10, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v9
+; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, v4, s[4:5]
+; CHECK-NEXT:    v_add_u16_e32 v3, v8, v3
+; CHECK-NEXT:    v_add_u16_e32 v6, 0xff90, v6
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v3
+; CHECK-NEXT:    v_lshlrev_b16_e32 v7, 2, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v7, v0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v4, v0, v4
+; CHECK-NEXT:    v_or_b32_e32 v7, v7, v5
+; CHECK-NEXT:    v_or_b32_e32 v3, v4, v3
+; CHECK-NEXT:    v_cmp_gt_i16_e64 s[4:5], 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v7, v3, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v5
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], 30, v6
+; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 30, v6
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v0
+; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, v4, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v5
+; CHECK-NEXT:    s_movk_i32 s6, 0xff
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[4:5]
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v1
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], s6, v2
+; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
+; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 from f64: double -> i8
+define i8 @to_f8e5m2_from_f64(double %x) {
+; CHECK-LABEL: to_f8e5m2_from_f64:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v2, v1
+; CHECK-NEXT:    v_and_b32_e32 v1, 0xfffff, v2
+; CHECK-NEXT:    v_ffbh_u32_e32 v5, v0
+; CHECK-NEXT:    v_bfe_u32 v3, v2, 20, 11
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0
+; CHECK-NEXT:    v_add_u32_e32 v5, 32, v5
+; CHECK-NEXT:    v_ffbh_u32_e32 v6, v1
+; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[0:1]
+; CHECK-NEXT:    v_cmp_eq_u64_e64 s[4:5], 0, v[3:4]
+; CHECK-NEXT:    v_min_u32_e32 v9, v5, v6
+; CHECK-NEXT:    v_sub_co_u32_e64 v5, s[6:7], 12, v9
+; CHECK-NEXT:    v_subb_co_u32_e64 v6, s[6:7], 0, 0, s[6:7]
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v14, v3, v5, s[4:5]
+; CHECK-NEXT:    s_movk_i32 s6, 0x423
+; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, v6, s[4:5]
+; CHECK-NEXT:    v_sub_co_u32_e64 v5, s[6:7], s6, v14
+; CHECK-NEXT:    v_subb_co_u32_e64 v6, s[6:7], 0, v13, s[6:7]
+; CHECK-NEXT:    v_cmp_gt_u64_e64 s[6:7], 63, v[5:6]
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, v6, s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 63, v5, s[6:7]
+; CHECK-NEXT:    v_cmp_lt_u64_e64 s[6:7], 1, v[5:6]
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 1, v5, s[6:7]
+; CHECK-NEXT:    v_add_u32_e32 v15, -1, v7
+; CHECK-NEXT:    v_lshlrev_b64 v[7:8], v15, 1
+; CHECK-NEXT:    v_add_co_u32_e64 v9, s[6:7], -11, v9
+; CHECK-NEXT:    v_lshlrev_b64 v[9:10], v9, v[0:1]
+; CHECK-NEXT:    v_add_co_u32_e64 v11, s[6:7], -1, v7
+; CHECK-NEXT:    v_addc_co_u32_e64 v12, s[6:7], -1, v8, s[6:7]
+; CHECK-NEXT:    v_and_b32_e32 v8, 0xfffff, v10
+; CHECK-NEXT:    v_cndmask_b32_e64 v16, v1, v8, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, v0, v9, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v8, 0x100000, v16
+; CHECK-NEXT:    v_and_b32_e32 v10, v8, v12
+; CHECK-NEXT:    v_and_b32_e32 v9, v7, v11
+; CHECK-NEXT:    v_lshrrev_b64 v[11:12], v5, v[7:8]
+; CHECK-NEXT:    v_cmp_ne_u64_e64 s[4:5], 0, v[9:10]
+; CHECK-NEXT:    v_and_b32_e32 v17, 1, v11
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
+; CHECK-NEXT:    v_lshrrev_b64 v[8:9], v15, v[7:8]
+; CHECK-NEXT:    v_or_b32_e32 v9, v10, v17
+; CHECK-NEXT:    v_cmp_ne_u64_e64 s[4:5], 0, v[5:6]
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v9
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, v8, s[4:5]
+; CHECK-NEXT:    v_add_co_u32_e64 v5, s[4:5], v11, v5
+; CHECK-NEXT:    v_addc_co_u32_e64 v6, s[4:5], 0, v12, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 3, v[5:6]
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x1ffff, v16
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 4, s[4:5]
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_and_b32_sdwa v2, v2, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_cmp_ne_u64_e64 s[4:5], 0, v[7:8]
+; CHECK-NEXT:    v_or3_b32 v9, v2, v6, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 1, s[4:5]
+; CHECK-NEXT:    v_bfe_u32 v6, v16, 18, 1
+; CHECK-NEXT:    v_or_b32_e32 v5, v5, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, 17, v16
+; CHECK-NEXT:    v_and_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, 18, v16
+; CHECK-NEXT:    v_add_co_u32_e64 v5, s[4:5], v6, v5
+; CHECK-NEXT:    v_addc_co_u32_e64 v6, s[4:5], 0, 0, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 3, v[5:6]
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, s[4:5]
+; CHECK-NEXT:    v_add_co_u32_e64 v7, s[6:7], v14, v7
+; CHECK-NEXT:    v_addc_co_u32_e64 v8, s[6:7], 0, v13, s[6:7]
+; CHECK-NEXT:    s_movk_i32 s6, 0xfc10
+; CHECK-NEXT:    v_add_co_u32_e64 v7, s[6:7], s6, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[4:5]
+; CHECK-NEXT:    v_addc_co_u32_e64 v8, s[6:7], -1, v8, s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 3, v[5:6]
+; CHECK-NEXT:    v_cmp_eq_u64_e64 s[6:7], 30, v[7:8]
+; CHECK-NEXT:    v_lshlrev_b32_e32 v10, 2, v7
+; CHECK-NEXT:    v_cmp_gt_i64_e64 s[8:9], 1, v[7:8]
+; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 30, v[7:8]
+; CHECK-NEXT:    v_or3_b32 v10, v10, v2, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v10, v9, s[8:9]
+; CHECK-NEXT:    v_or_b32_e32 v7, 0x7c, v2
+; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, v5, v7, s[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v5, v3, v0
+; CHECK-NEXT:    v_mov_b32_e32 v6, v1
+; CHECK-NEXT:    s_mov_b64 s[6:7], 0x7ff
+; CHECK-NEXT:    v_cmp_eq_u64_e64 s[4:5], 0, v[0:1]
+; CHECK-NEXT:    v_cmp_eq_u64_e64 s[6:7], s[6:7], v[3:4]
+; CHECK-NEXT:    v_cmp_eq_u64_e64 s[8:9], 0, v[5:6]
+; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v8, v2, s[8:9]
+; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v7, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
+; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
diff --git a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
new file mode 100644
index 0000000000000..0c98d9ca21713
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
@@ -0,0 +1,1028 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=nvptx64-unknown-unknown | FileCheck %s
+
+; Test llvm.convert.to.arbitrary.fp intrinsic expansion.
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+declare i6 @llvm.convert.to.arbitrary.fp.i6.f32(float, metadata, metadata, i1)
+declare i4 @llvm.convert.to.arbitrary.fp.i4.f32(float, metadata, metadata, i1)
+declare <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float>, metadata, metadata, i1)
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1)
+declare i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat, metadata, metadata, i1)
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
+
+; Float8E5M2
+; Layout: sign(1) exp(5) mant(2), bias=15
+; Supports: Inf, NaN, signed zero, denormals
+
+; Float8E5M2 normal: f32 1.0 -> 0_01111_00 = 0x3C
+define i8 @to_f8e5m2_normal() {
+; CHECK-LABEL: to_f8e5m2_normal(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 60;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 zero: f32 0.0 -> 0_00000_00 = 0x00
+define i8 @to_f8e5m2_zero() {
+; CHECK-LABEL: to_f8e5m2_zero(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 0;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 negative zero: f32 -0.0 -> 1_00000_00 = 0x80
+define i8 @to_f8e5m2_neg_zero() {
+; CHECK-LABEL: to_f8e5m2_neg_zero(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 128;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float -0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 +Inf: f32 Inf -> 0_11111_00 = 0x7C
+define i8 @to_f8e5m2_inf() {
+; CHECK-LABEL: to_f8e5m2_inf(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 124;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 NaN: f32 NaN -> qNaN
+define i8 @to_f8e5m2_nan() {
+; CHECK-LABEL: to_f8e5m2_nan(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 126;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 max: 57344.0 -> 0_11110_11 = 0x7B
+define i8 @to_f8e5m2_max() {
+; CHECK-LABEL: to_f8e5m2_max(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 123;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 57344.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 overflow (no saturation): 100000.0 -> Inf = 0x7C
+define i8 @to_f8e5m2_overflow() {
+; CHECK-LABEL: to_f8e5m2_overflow(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 124;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 overflow with saturation: 100000.0 -> max = 0x7B
+define i8 @to_f8e5m2_overflow_sat() {
+; CHECK-LABEL: to_f8e5m2_overflow_sat(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 123;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 true)
+  ret i8 %r
+}
+
+; Float8E5M2 denorm: very small value -> dst denorm
+define i8 @to_f8e5m2_denorm() {
+  ; 2^(-16) = 0x37800000 -> smallest E5M2 denorm 0_00000_01 = 0x01
+; CHECK-LABEL: to_f8e5m2_denorm(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 1;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x3EF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 runtime arg test
+define i8 @to_f8e5m2_dynamic(float %x) {
+; CHECK-LABEL: to_f8e5m2_dynamic(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<16>;
+; CHECK-NEXT:    .reg .b32 %r<60>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e5m2_dynamic_param_0];
+; CHECK-NEXT:    and.b32 %r2, %r1, 8388607;
+; CHECK-NEXT:    setp.ne.b32 %p1, %r2, 0;
+; CHECK-NEXT:    bfe.u32 %r3, %r1, 23, 8;
+; CHECK-NEXT:    setp.eq.b32 %p2, %r3, 0;
+; CHECK-NEXT:    and.pred %p3, %p2, %p1;
+; CHECK-NEXT:    clz.b32 %r4, %r2;
+; CHECK-NEXT:    add.s32 %r5, %r4, -8;
+; CHECK-NEXT:    shl.b32 %r6, %r2, %r5;
+; CHECK-NEXT:    and.b32 %r7, %r6, 8388607;
+; CHECK-NEXT:    selp.b32 %r8, %r7, %r2, %p3;
+; CHECK-NEXT:    bfe.u32 %r9, %r8, 21, 1;
+; CHECK-NEXT:    and.b32 %r10, %r8, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r10, 0;
+; CHECK-NEXT:    selp.b32 %r11, 1, 0, %p4;
+; CHECK-NEXT:    or.b32 %r12, %r11, %r9;
+; CHECK-NEXT:    shr.u32 %r13, %r8, 20;
+; CHECK-NEXT:    and.b32 %r14, %r13, %r12;
+; CHECK-NEXT:    shr.u32 %r15, %r8, 21;
+; CHECK-NEXT:    add.s32 %r16, %r15, %r14;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r16, 3;
+; CHECK-NEXT:    selp.b32 %r17, 0, %r16, %p5;
+; CHECK-NEXT:    selp.b32 %r18, 1, 0, %p5;
+; CHECK-NEXT:    sub.s32 %r19, 9, %r4;
+; CHECK-NEXT:    selp.b32 %r20, %r19, %r3, %p3;
+; CHECK-NEXT:    add.s32 %r21, %r20, %r18;
+; CHECK-NEXT:    add.s32 %r22, %r21, -112;
+; CHECK-NEXT:    shl.b32 %r23, %r22, 2;
+; CHECK-NEXT:    shr.u32 %r24, %r1, 24;
+; CHECK-NEXT:    and.b32 %r25, %r24, 128;
+; CHECK-NEXT:    or.b32 %r26, %r25, %r23;
+; CHECK-NEXT:    or.b32 %r27, %r26, %r17;
+; CHECK-NEXT:    or.b32 %r28, %r8, 8388608;
+; CHECK-NEXT:    sub.s32 %r29, 134, %r20;
+; CHECK-NEXT:    min.u32 %r30, %r29, 31;
+; CHECK-NEXT:    shr.u32 %r31, %r28, %r30;
+; CHECK-NEXT:    and.b32 %r32, %r31, 1;
+; CHECK-NEXT:    max.u32 %r33, %r30, 1;
+; CHECK-NEXT:    add.s32 %r34, %r33, -1;
+; CHECK-NEXT:    mov.b32 %r35, 1;
+; CHECK-NEXT:    shl.b32 %r36, %r35, %r34;
+; CHECK-NEXT:    add.s32 %r37, %r36, -1;
+; CHECK-NEXT:    and.b32 %r38, %r28, %r37;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r38, 0;
+; CHECK-NEXT:    selp.b32 %r39, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r40, %r39, %r32;
+; CHECK-NEXT:    shr.u32 %r41, %r28, %r34;
+; CHECK-NEXT:    and.b32 %r42, %r41, %r40;
+; CHECK-NEXT:    setp.ne.b32 %p7, %r30, 0;
+; CHECK-NEXT:    selp.b32 %r43, %r42, 0, %p7;
+; CHECK-NEXT:    add.s32 %r44, %r31, %r43;
+; CHECK-NEXT:    setp.gt.s32 %p8, %r44, 3;
+; CHECK-NEXT:    selp.b32 %r45, 0, %r44, %p8;
+; CHECK-NEXT:    selp.b32 %r46, 4, 0, %p8;
+; CHECK-NEXT:    or.b32 %r47, %r25, %r46;
+; CHECK-NEXT:    or.b32 %r48, %r47, %r45;
+; CHECK-NEXT:    setp.lt.s32 %p9, %r22, 1;
+; CHECK-NEXT:    selp.b32 %r49, %r48, %r27, %p9;
+; CHECK-NEXT:    setp.gt.s32 %p10, %r17, 3;
+; CHECK-NEXT:    or.b32 %r50, %r25, 124;
+; CHECK-NEXT:    selp.b32 %r51, %r50, %r49, %p10;
+; CHECK-NEXT:    setp.eq.b32 %p11, %r22, 30;
+; CHECK-NEXT:    selp.b32 %r52, %r51, %r49, %p11;
+; CHECK-NEXT:    setp.gt.s32 %p12, %r22, 30;
+; CHECK-NEXT:    selp.b32 %r53, %r50, %r52, %p12;
+; CHECK-NEXT:    or.b32 %r54, %r3, %r2;
+; CHECK-NEXT:    setp.eq.b32 %p13, %r54, 0;
+; CHECK-NEXT:    selp.b32 %r55, %r25, %r53, %p13;
+; CHECK-NEXT:    setp.eq.b32 %p14, %r2, 0;
+; CHECK-NEXT:    selp.b32 %r56, %r50, %r55, %p14;
+; CHECK-NEXT:    setp.eq.b32 %p15, %r3, 255;
+; CHECK-NEXT:    selp.b32 %r57, %r56, %r55, %p15;
+; CHECK-NEXT:    selp.b32 %r58, 126, %r57, %p1;
+; CHECK-NEXT:    selp.b32 %r59, %r58, %r57, %p15;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r59;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN (NanOnly, NanEncoding=AllOnes)
+; Layout: sign(1) exp(4) mant(3), maxExp=8, minExp=-6, bias=7
+; Only 0_1111_111 and 1_1111_111 are NaN; all other exp=15 values are finite.
+
+; Float8E4M3FN normal: f32 1.0 -> 0_0111_000 = 0x38
+define i8 @to_f8e4m3fn_normal() {
+; CHECK-LABEL: to_f8e4m3fn_normal(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 56;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN max: 448.0 -> 0_1111_110 = 0x7E
+define i8 @to_f8e4m3fn_max() {
+; CHECK-LABEL: to_f8e4m3fn_max(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 126;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 448.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN NaN: f32 NaN -> 0_1111_111 = 0x7F
+define i8 @to_f8e4m3fn_nan() {
+; CHECK-LABEL: to_f8e4m3fn_nan(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 127;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN overflow with saturation: 1000.0 -> max = 0x7E
+define i8 @to_f8e4m3fn_overflow_sat() {
+; CHECK-LABEL: to_f8e4m3fn_overflow_sat(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 126;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1000.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 true)
+  ret i8 %r
+}
+
+; Float6E3M2FN (FiniteOnly)
+; Layout: sign(1) exp(3) mant(2), bias=3, maxExp=4
+; No Inf, no NaN. All bit patterns are finite.
+
+; Float6E3M2FN normal: f32 1.0 -> 0_011_00 = 0x0C
+define i6 @to_f6e3m2fn_normal() {
+; CHECK-LABEL: to_f6e3m2fn_normal(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 12;
+; CHECK-NEXT:    ret;
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN max: 28.0 -> 0_111_11 = 0x1F
+define i6 @to_f6e3m2fn_max() {
+; CHECK-LABEL: to_f6e3m2fn_max(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 31;
+; CHECK-NEXT:    ret;
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 28.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN zero: f32 0.0 -> 0_000_00 = 0x00
+define i6 @to_f6e3m2fn_zero() {
+; CHECK-LABEL: to_f6e3m2fn_zero(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 0;
+; CHECK-NEXT:    ret;
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 0.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN negative: f32 -1.0 -> 1_011_00
+define i6 @to_f6e3m2fn_negative() {
+; CHECK-LABEL: to_f6e3m2fn_negative(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 44;
+; CHECK-NEXT:    ret;
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float -1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E2M3FN (FiniteOnly)
+; Layout: sign(1) exp(2) mant(3), bias=1, maxExp=2
+; No Inf, no NaN. All bit patterns are finite.
+
+; Float6E2M3FN normal: f32 1.0 -> 0_01_000 = 0x08
+define i6 @to_f6e2m3fn_normal() {
+; CHECK-LABEL: to_f6e2m3fn_normal(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 8;
+; CHECK-NEXT:    ret;
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E2M3FN max: 7.5 -> 0_11_111 = 0x1F
+define i6 @to_f6e2m3fn_max() {
+; CHECK-LABEL: to_f6e2m3fn_max(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 31;
+; CHECK-NEXT:    ret;
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 7.5, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float4E2M1FN (FiniteOnly)
+; Layout: sign(1) exp(2) mant(1), bias=1, maxExp=2
+; No Inf, no NaN.
+
+; Float4E2M1FN normal: f32 1.0 -> 0_01_0 = 0x2
+define i4 @to_f4e2m1fn_normal() {
+; CHECK-LABEL: to_f4e2m1fn_normal(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 2;
+; CHECK-NEXT:    ret;
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 1.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Float4E2M1FN max: 6.0 -> 0_11_1 = 0x7
+define i4 @to_f4e2m1fn_max() {
+; CHECK-LABEL: to_f4e2m1fn_max(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 7;
+; CHECK-NEXT:    ret;
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 6.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Float4E2M1FN denorm: 0.5 -> 0_00_1 = 0x1
+define i4 @to_f4e2m1fn_denorm() {
+; CHECK-LABEL: to_f4e2m1fn_denorm(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 1;
+; CHECK-NEXT:    ret;
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 0.5, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Rounding mode tests
+
+; Round to nearest
+define i8 @to_f8e5m2_round_nearest() {
+; CHECK-LABEL: to_f8e5m2_round_nearest(
+; CHECK:       {
+; CHECK-EMPTY:
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    st.param.b32 [func_retval0], 62;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.5, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Round toward zero with runtime arg
+define i8 @to_f8e5m2_round_towardzero(float %x) {
+; CHECK-LABEL: to_f8e5m2_round_towardzero(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<13>;
+; CHECK-NEXT:    .reg .b32 %r<40>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e5m2_round_towardzero_param_0];
+; CHECK-NEXT:    and.b32 %r2, %r1, 8388607;
+; CHECK-NEXT:    setp.ne.b32 %p1, %r2, 0;
+; CHECK-NEXT:    bfe.u32 %r3, %r1, 23, 8;
+; CHECK-NEXT:    setp.eq.b32 %p2, %r3, 0;
+; CHECK-NEXT:    and.pred %p3, %p2, %p1;
+; CHECK-NEXT:    clz.b32 %r4, %r2;
+; CHECK-NEXT:    add.s32 %r5, %r4, -8;
+; CHECK-NEXT:    shl.b32 %r6, %r2, %r5;
+; CHECK-NEXT:    and.b32 %r7, %r6, 8388607;
+; CHECK-NEXT:    selp.b32 %r8, %r7, %r2, %p3;
+; CHECK-NEXT:    or.b32 %r9, %r8, 8388608;
+; CHECK-NEXT:    sub.s32 %r10, 9, %r4;
+; CHECK-NEXT:    selp.b32 %r11, %r10, %r3, %p3;
+; CHECK-NEXT:    sub.s32 %r12, 134, %r11;
+; CHECK-NEXT:    min.u32 %r13, %r12, 31;
+; CHECK-NEXT:    shr.u32 %r14, %r9, %r13;
+; CHECK-NEXT:    setp.gt.s32 %p4, %r14, 3;
+; CHECK-NEXT:    selp.b32 %r15, 0, %r14, %p4;
+; CHECK-NEXT:    selp.b32 %r16, 4, 0, %p4;
+; CHECK-NEXT:    shr.u32 %r17, %r1, 24;
+; CHECK-NEXT:    and.b32 %r18, %r17, 128;
+; CHECK-NEXT:    or.b32 %r19, %r18, %r16;
+; CHECK-NEXT:    or.b32 %r20, %r19, %r15;
+; CHECK-NEXT:    shr.u32 %r21, %r8, 21;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r21, 3;
+; CHECK-NEXT:    selp.b32 %r22, 0, %r21, %p5;
+; CHECK-NEXT:    selp.b32 %r23, 1, 0, %p5;
+; CHECK-NEXT:    add.s32 %r24, %r11, %r23;
+; CHECK-NEXT:    add.s32 %r25, %r24, -112;
+; CHECK-NEXT:    shl.b32 %r26, %r25, 2;
+; CHECK-NEXT:    or.b32 %r27, %r18, %r26;
+; CHECK-NEXT:    or.b32 %r28, %r27, %r22;
+; CHECK-NEXT:    setp.lt.s32 %p6, %r25, 1;
+; CHECK-NEXT:    selp.b32 %r29, %r20, %r28, %p6;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r22, 3;
+; CHECK-NEXT:    or.b32 %r30, %r18, 124;
+; CHECK-NEXT:    selp.b32 %r31, %r30, %r29, %p7;
+; CHECK-NEXT:    setp.eq.b32 %p8, %r25, 30;
+; CHECK-NEXT:    selp.b32 %r32, %r31, %r29, %p8;
+; CHECK-NEXT:    setp.gt.s32 %p9, %r25, 30;
+; CHECK-NEXT:    selp.b32 %r33, %r30, %r32, %p9;
+; CHECK-NEXT:    or.b32 %r34, %r3, %r2;
+; CHECK-NEXT:    setp.eq.b32 %p10, %r34, 0;
+; CHECK-NEXT:    selp.b32 %r35, %r18, %r33, %p10;
+; CHECK-NEXT:    setp.eq.b32 %p11, %r2, 0;
+; CHECK-NEXT:    selp.b32 %r36, %r30, %r35, %p11;
+; CHECK-NEXT:    setp.eq.b32 %p12, %r3, 255;
+; CHECK-NEXT:    selp.b32 %r37, %r36, %r35, %p12;
+; CHECK-NEXT:    selp.b32 %r38, 126, %r37, %p1;
+; CHECK-NEXT:    selp.b32 %r39, %r38, %r37, %p12;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r39;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
+  ret i8 %r
+}
+
+; Vector test: f32 <4 x float> -> <4 x i4> Float4E2M1FN
+define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f4e2m1fn_v4f32(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<41>;
+; CHECK-NEXT:    .reg .b32 %r<202>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.v4.b32 {%r1, %r2, %r3, %r4}, [to_f4e2m1fn_v4f32_param_0];
+; CHECK-NEXT:    and.b32 %r5, %r4, 8388607;
+; CHECK-NEXT:    setp.ne.b32 %p1, %r5, 0;
+; CHECK-NEXT:    bfe.u32 %r6, %r4, 23, 8;
+; CHECK-NEXT:    setp.eq.b32 %p2, %r6, 0;
+; CHECK-NEXT:    and.pred %p3, %p2, %p1;
+; CHECK-NEXT:    clz.b32 %r7, %r5;
+; CHECK-NEXT:    add.s32 %r8, %r7, -8;
+; CHECK-NEXT:    shl.b32 %r9, %r5, %r8;
+; CHECK-NEXT:    and.b32 %r10, %r9, 8388607;
+; CHECK-NEXT:    selp.b32 %r11, %r10, %r5, %p3;
+; CHECK-NEXT:    shr.u32 %r12, %r11, 22;
+; CHECK-NEXT:    and.b32 %r13, %r11, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r13, 0;
+; CHECK-NEXT:    selp.b32 %r14, 1, 0, %p4;
+; CHECK-NEXT:    or.b32 %r15, %r14, %r12;
+; CHECK-NEXT:    shr.u32 %r16, %r11, 21;
+; CHECK-NEXT:    and.b32 %r17, %r16, %r15;
+; CHECK-NEXT:    add.s32 %r18, %r12, %r17;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r18, 1;
+; CHECK-NEXT:    selp.b32 %r19, 0, %r18, %p5;
+; CHECK-NEXT:    selp.b32 %r20, 1, 0, %p5;
+; CHECK-NEXT:    sub.s32 %r21, 9, %r7;
+; CHECK-NEXT:    selp.b32 %r22, %r21, %r6, %p3;
+; CHECK-NEXT:    add.s32 %r23, %r22, %r20;
+; CHECK-NEXT:    add.s32 %r24, %r23, -126;
+; CHECK-NEXT:    shl.b32 %r25, %r24, 1;
+; CHECK-NEXT:    shr.u32 %r26, %r4, 28;
+; CHECK-NEXT:    and.b32 %r27, %r26, 8;
+; CHECK-NEXT:    or.b32 %r28, %r27, %r25;
+; CHECK-NEXT:    or.b32 %r29, %r28, %r19;
+; CHECK-NEXT:    or.b32 %r30, %r11, 8388608;
+; CHECK-NEXT:    sub.s32 %r31, 149, %r22;
+; CHECK-NEXT:    min.u32 %r32, %r31, 31;
+; CHECK-NEXT:    shr.u32 %r33, %r30, %r32;
+; CHECK-NEXT:    and.b32 %r34, %r33, 1;
+; CHECK-NEXT:    max.u32 %r35, %r32, 1;
+; CHECK-NEXT:    add.s32 %r36, %r35, -1;
+; CHECK-NEXT:    mov.b32 %r37, 1;
+; CHECK-NEXT:    shl.b32 %r38, %r37, %r36;
+; CHECK-NEXT:    add.s32 %r39, %r38, -1;
+; CHECK-NEXT:    and.b32 %r40, %r30, %r39;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r40, 0;
+; CHECK-NEXT:    selp.b32 %r41, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r42, %r41, %r34;
+; CHECK-NEXT:    shr.u32 %r43, %r30, %r36;
+; CHECK-NEXT:    and.b32 %r44, %r43, %r42;
+; CHECK-NEXT:    setp.ne.b32 %p7, %r32, 0;
+; CHECK-NEXT:    selp.b32 %r45, %r44, 0, %p7;
+; CHECK-NEXT:    add.s32 %r46, %r33, %r45;
+; CHECK-NEXT:    setp.gt.s32 %p8, %r46, 1;
+; CHECK-NEXT:    selp.b32 %r47, 0, %r46, %p8;
+; CHECK-NEXT:    selp.b32 %r48, 2, 0, %p8;
+; CHECK-NEXT:    or.b32 %r49, %r27, %r48;
+; CHECK-NEXT:    or.b32 %r50, %r49, %r47;
+; CHECK-NEXT:    setp.lt.s32 %p9, %r24, 1;
+; CHECK-NEXT:    selp.b32 %r51, %r50, %r29, %p9;
+; CHECK-NEXT:    or.b32 %r52, %r6, %r5;
+; CHECK-NEXT:    setp.eq.b32 %p10, %r52, 0;
+; CHECK-NEXT:    selp.b32 %r53, %r27, %r51, %p10;
+; CHECK-NEXT:    and.b32 %r54, %r3, 8388607;
+; CHECK-NEXT:    setp.ne.b32 %p11, %r54, 0;
+; CHECK-NEXT:    bfe.u32 %r55, %r3, 23, 8;
+; CHECK-NEXT:    setp.eq.b32 %p12, %r55, 0;
+; CHECK-NEXT:    and.pred %p13, %p12, %p11;
+; CHECK-NEXT:    clz.b32 %r56, %r54;
+; CHECK-NEXT:    add.s32 %r57, %r56, -8;
+; CHECK-NEXT:    shl.b32 %r58, %r54, %r57;
+; CHECK-NEXT:    and.b32 %r59, %r58, 8388607;
+; CHECK-NEXT:    selp.b32 %r60, %r59, %r54, %p13;
+; CHECK-NEXT:    shr.u32 %r61, %r60, 22;
+; CHECK-NEXT:    and.b32 %r62, %r60, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p14, %r62, 0;
+; CHECK-NEXT:    selp.b32 %r63, 1, 0, %p14;
+; CHECK-NEXT:    or.b32 %r64, %r63, %r61;
+; CHECK-NEXT:    shr.u32 %r65, %r60, 21;
+; CHECK-NEXT:    and.b32 %r66, %r65, %r64;
+; CHECK-NEXT:    add.s32 %r67, %r61, %r66;
+; CHECK-NEXT:    setp.gt.s32 %p15, %r67, 1;
+; CHECK-NEXT:    selp.b32 %r68, 0, %r67, %p15;
+; CHECK-NEXT:    selp.b32 %r69, 1, 0, %p15;
+; CHECK-NEXT:    sub.s32 %r70, 9, %r56;
+; CHECK-NEXT:    selp.b32 %r71, %r70, %r55, %p13;
+; CHECK-NEXT:    add.s32 %r72, %r71, %r69;
+; CHECK-NEXT:    add.s32 %r73, %r72, -126;
+; CHECK-NEXT:    shl.b32 %r74, %r73, 1;
+; CHECK-NEXT:    shr.u32 %r75, %r3, 28;
+; CHECK-NEXT:    and.b32 %r76, %r75, 8;
+; CHECK-NEXT:    or.b32 %r77, %r76, %r74;
+; CHECK-NEXT:    or.b32 %r78, %r77, %r68;
+; CHECK-NEXT:    or.b32 %r79, %r60, 8388608;
+; CHECK-NEXT:    sub.s32 %r80, 149, %r71;
+; CHECK-NEXT:    min.u32 %r81, %r80, 31;
+; CHECK-NEXT:    shr.u32 %r82, %r79, %r81;
+; CHECK-NEXT:    and.b32 %r83, %r82, 1;
+; CHECK-NEXT:    max.u32 %r84, %r81, 1;
+; CHECK-NEXT:    add.s32 %r85, %r84, -1;
+; CHECK-NEXT:    shl.b32 %r86, %r37, %r85;
+; CHECK-NEXT:    add.s32 %r87, %r86, -1;
+; CHECK-NEXT:    and.b32 %r88, %r79, %r87;
+; CHECK-NEXT:    setp.ne.b32 %p16, %r88, 0;
+; CHECK-NEXT:    selp.b32 %r89, 1, 0, %p16;
+; CHECK-NEXT:    or.b32 %r90, %r89, %r83;
+; CHECK-NEXT:    shr.u32 %r91, %r79, %r85;
+; CHECK-NEXT:    and.b32 %r92, %r91, %r90;
+; CHECK-NEXT:    setp.ne.b32 %p17, %r81, 0;
+; CHECK-NEXT:    selp.b32 %r93, %r92, 0, %p17;
+; CHECK-NEXT:    add.s32 %r94, %r82, %r93;
+; CHECK-NEXT:    setp.gt.s32 %p18, %r94, 1;
+; CHECK-NEXT:    selp.b32 %r95, 0, %r94, %p18;
+; CHECK-NEXT:    selp.b32 %r96, 2, 0, %p18;
+; CHECK-NEXT:    or.b32 %r97, %r76, %r96;
+; CHECK-NEXT:    or.b32 %r98, %r97, %r95;
+; CHECK-NEXT:    setp.lt.s32 %p19, %r73, 1;
+; CHECK-NEXT:    selp.b32 %r99, %r98, %r78, %p19;
+; CHECK-NEXT:    or.b32 %r100, %r55, %r54;
+; CHECK-NEXT:    setp.eq.b32 %p20, %r100, 0;
+; CHECK-NEXT:    selp.b32 %r101, %r76, %r99, %p20;
+; CHECK-NEXT:    prmt.b32 %r102, %r101, %r53, 0x3340U;
+; CHECK-NEXT:    and.b32 %r103, %r2, 8388607;
+; CHECK-NEXT:    setp.ne.b32 %p21, %r103, 0;
+; CHECK-NEXT:    bfe.u32 %r104, %r2, 23, 8;
+; CHECK-NEXT:    setp.eq.b32 %p22, %r104, 0;
+; CHECK-NEXT:    and.pred %p23, %p22, %p21;
+; CHECK-NEXT:    clz.b32 %r105, %r103;
+; CHECK-NEXT:    add.s32 %r106, %r105, -8;
+; CHECK-NEXT:    shl.b32 %r107, %r103, %r106;
+; CHECK-NEXT:    and.b32 %r108, %r107, 8388607;
+; CHECK-NEXT:    selp.b32 %r109, %r108, %r103, %p23;
+; CHECK-NEXT:    shr.u32 %r110, %r109, 22;
+; CHECK-NEXT:    and.b32 %r111, %r109, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p24, %r111, 0;
+; CHECK-NEXT:    selp.b32 %r112, 1, 0, %p24;
+; CHECK-NEXT:    or.b32 %r113, %r112, %r110;
+; CHECK-NEXT:    shr.u32 %r114, %r109, 21;
+; CHECK-NEXT:    and.b32 %r115, %r114, %r113;
+; CHECK-NEXT:    add.s32 %r116, %r110, %r115;
+; CHECK-NEXT:    setp.gt.s32 %p25, %r116, 1;
+; CHECK-NEXT:    selp.b32 %r117, 0, %r116, %p25;
+; CHECK-NEXT:    selp.b32 %r118, 1, 0, %p25;
+; CHECK-NEXT:    sub.s32 %r119, 9, %r105;
+; CHECK-NEXT:    selp.b32 %r120, %r119, %r104, %p23;
+; CHECK-NEXT:    add.s32 %r121, %r120, %r118;
+; CHECK-NEXT:    add.s32 %r122, %r121, -126;
+; CHECK-NEXT:    shl.b32 %r123, %r122, 1;
+; CHECK-NEXT:    shr.u32 %r124, %r2, 28;
+; CHECK-NEXT:    and.b32 %r125, %r124, 8;
+; CHECK-NEXT:    or.b32 %r126, %r125, %r123;
+; CHECK-NEXT:    or.b32 %r127, %r126, %r117;
+; CHECK-NEXT:    or.b32 %r128, %r109, 8388608;
+; CHECK-NEXT:    sub.s32 %r129, 149, %r120;
+; CHECK-NEXT:    min.u32 %r130, %r129, 31;
+; CHECK-NEXT:    shr.u32 %r131, %r128, %r130;
+; CHECK-NEXT:    and.b32 %r132, %r131, 1;
+; CHECK-NEXT:    max.u32 %r133, %r130, 1;
+; CHECK-NEXT:    add.s32 %r134, %r133, -1;
+; CHECK-NEXT:    shl.b32 %r135, %r37, %r134;
+; CHECK-NEXT:    add.s32 %r136, %r135, -1;
+; CHECK-NEXT:    and.b32 %r137, %r128, %r136;
+; CHECK-NEXT:    setp.ne.b32 %p26, %r137, 0;
+; CHECK-NEXT:    selp.b32 %r138, 1, 0, %p26;
+; CHECK-NEXT:    or.b32 %r139, %r138, %r132;
+; CHECK-NEXT:    shr.u32 %r140, %r128, %r134;
+; CHECK-NEXT:    and.b32 %r141, %r140, %r139;
+; CHECK-NEXT:    setp.ne.b32 %p27, %r130, 0;
+; CHECK-NEXT:    selp.b32 %r142, %r141, 0, %p27;
+; CHECK-NEXT:    add.s32 %r143, %r131, %r142;
+; CHECK-NEXT:    setp.gt.s32 %p28, %r143, 1;
+; CHECK-NEXT:    selp.b32 %r144, 0, %r143, %p28;
+; CHECK-NEXT:    selp.b32 %r145, 2, 0, %p28;
+; CHECK-NEXT:    or.b32 %r146, %r125, %r145;
+; CHECK-NEXT:    or.b32 %r147, %r146, %r144;
+; CHECK-NEXT:    setp.lt.s32 %p29, %r122, 1;
+; CHECK-NEXT:    selp.b32 %r148, %r147, %r127, %p29;
+; CHECK-NEXT:    or.b32 %r149, %r104, %r103;
+; CHECK-NEXT:    setp.eq.b32 %p30, %r149, 0;
+; CHECK-NEXT:    selp.b32 %r150, %r125, %r148, %p30;
+; CHECK-NEXT:    and.b32 %r151, %r1, 8388607;
+; CHECK-NEXT:    setp.ne.b32 %p31, %r151, 0;
+; CHECK-NEXT:    bfe.u32 %r152, %r1, 23, 8;
+; CHECK-NEXT:    setp.eq.b32 %p32, %r152, 0;
+; CHECK-NEXT:    and.pred %p33, %p32, %p31;
+; CHECK-NEXT:    clz.b32 %r153, %r151;
+; CHECK-NEXT:    add.s32 %r154, %r153, -8;
+; CHECK-NEXT:    shl.b32 %r155, %r151, %r154;
+; CHECK-NEXT:    and.b32 %r156, %r155, 8388607;
+; CHECK-NEXT:    selp.b32 %r157, %r156, %r151, %p33;
+; CHECK-NEXT:    shr.u32 %r158, %r157, 22;
+; CHECK-NEXT:    and.b32 %r159, %r157, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p34, %r159, 0;
+; CHECK-NEXT:    selp.b32 %r160, 1, 0, %p34;
+; CHECK-NEXT:    or.b32 %r161, %r160, %r158;
+; CHECK-NEXT:    shr.u32 %r162, %r157, 21;
+; CHECK-NEXT:    and.b32 %r163, %r162, %r161;
+; CHECK-NEXT:    add.s32 %r164, %r158, %r163;
+; CHECK-NEXT:    setp.gt.s32 %p35, %r164, 1;
+; CHECK-NEXT:    selp.b32 %r165, 0, %r164, %p35;
+; CHECK-NEXT:    selp.b32 %r166, 1, 0, %p35;
+; CHECK-NEXT:    sub.s32 %r167, 9, %r153;
+; CHECK-NEXT:    selp.b32 %r168, %r167, %r152, %p33;
+; CHECK-NEXT:    add.s32 %r169, %r168, %r166;
+; CHECK-NEXT:    add.s32 %r170, %r169, -126;
+; CHECK-NEXT:    shl.b32 %r171, %r170, 1;
+; CHECK-NEXT:    shr.u32 %r172, %r1, 28;
+; CHECK-NEXT:    and.b32 %r173, %r172, 8;
+; CHECK-NEXT:    or.b32 %r174, %r173, %r171;
+; CHECK-NEXT:    or.b32 %r175, %r174, %r165;
+; CHECK-NEXT:    or.b32 %r176, %r157, 8388608;
+; CHECK-NEXT:    sub.s32 %r177, 149, %r168;
+; CHECK-NEXT:    min.u32 %r178, %r177, 31;
+; CHECK-NEXT:    shr.u32 %r179, %r176, %r178;
+; CHECK-NEXT:    and.b32 %r180, %r179, 1;
+; CHECK-NEXT:    max.u32 %r181, %r178, 1;
+; CHECK-NEXT:    add.s32 %r182, %r181, -1;
+; CHECK-NEXT:    shl.b32 %r183, %r37, %r182;
+; CHECK-NEXT:    add.s32 %r184, %r183, -1;
+; CHECK-NEXT:    and.b32 %r185, %r176, %r184;
+; CHECK-NEXT:    setp.ne.b32 %p36, %r185, 0;
+; CHECK-NEXT:    selp.b32 %r186, 1, 0, %p36;
+; CHECK-NEXT:    or.b32 %r187, %r186, %r180;
+; CHECK-NEXT:    shr.u32 %r188, %r176, %r182;
+; CHECK-NEXT:    and.b32 %r189, %r188, %r187;
+; CHECK-NEXT:    setp.ne.b32 %p37, %r178, 0;
+; CHECK-NEXT:    selp.b32 %r190, %r189, 0, %p37;
+; CHECK-NEXT:    add.s32 %r191, %r179, %r190;
+; CHECK-NEXT:    setp.gt.s32 %p38, %r191, 1;
+; CHECK-NEXT:    selp.b32 %r192, 0, %r191, %p38;
+; CHECK-NEXT:    selp.b32 %r193, 2, 0, %p38;
+; CHECK-NEXT:    or.b32 %r194, %r173, %r193;
+; CHECK-NEXT:    or.b32 %r195, %r194, %r192;
+; CHECK-NEXT:    setp.lt.s32 %p39, %r170, 1;
+; CHECK-NEXT:    selp.b32 %r196, %r195, %r175, %p39;
+; CHECK-NEXT:    or.b32 %r197, %r152, %r151;
+; CHECK-NEXT:    setp.eq.b32 %p40, %r197, 0;
+; CHECK-NEXT:    selp.b32 %r198, %r173, %r196, %p40;
+; CHECK-NEXT:    prmt.b32 %r199, %r198, %r150, 0x3340U;
+; CHECK-NEXT:    prmt.b32 %r200, %r199, %r102, 0x5410U;
+; CHECK-NEXT:    st.param.b16 [func_retval0], %r200;
+; CHECK-NEXT:    shr.u32 %r201, %r200, 16;
+; CHECK-NEXT:    st.param.b16 [func_retval0+2], %r201;
+; CHECK-NEXT:    ret;
+  %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret <4 x i4> %r
+}
+
+; Float8E5M2 from f16: half -> i8
+define i8 @to_f8e5m2_from_f16(half %x) {
+; CHECK-LABEL: to_f8e5m2_from_f16(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<16>;
+; CHECK-NEXT:    .reg .b16 %rs<60>;
+; CHECK-NEXT:    .reg .b32 %r<8>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.b16 %rs1, [to_f8e5m2_from_f16_param_0];
+; CHECK-NEXT:    and.b16 %rs2, %rs1, 1023;
+; CHECK-NEXT:    setp.ne.b16 %p1, %rs2, 0;
+; CHECK-NEXT:    shr.u16 %rs3, %rs1, 10;
+; CHECK-NEXT:    and.b16 %rs4, %rs3, 31;
+; CHECK-NEXT:    setp.eq.b16 %p2, %rs4, 0;
+; CHECK-NEXT:    and.pred %p3, %p2, %p1;
+; CHECK-NEXT:    cvt.u32.u16 %r1, %rs2;
+; CHECK-NEXT:    shl.b32 %r2, %r1, 16;
+; CHECK-NEXT:    clz.b32 %r3, %r2;
+; CHECK-NEXT:    cvt.u16.u32 %rs5, %r3;
+; CHECK-NEXT:    add.s16 %rs6, %rs5, -5;
+; CHECK-NEXT:    cvt.u32.u16 %r4, %rs6;
+; CHECK-NEXT:    shl.b16 %rs7, %rs2, %r4;
+; CHECK-NEXT:    and.b16 %rs8, %rs7, 1023;
+; CHECK-NEXT:    selp.b16 %rs9, %rs8, %rs2, %p3;
+; CHECK-NEXT:    shr.u16 %rs10, %rs9, 8;
+; CHECK-NEXT:    and.b16 %rs11, %rs10, 1;
+; CHECK-NEXT:    and.b16 %rs12, %rs9, 127;
+; CHECK-NEXT:    setp.ne.b16 %p4, %rs12, 0;
+; CHECK-NEXT:    selp.b16 %rs13, 1, 0, %p4;
+; CHECK-NEXT:    or.b16 %rs14, %rs13, %rs11;
+; CHECK-NEXT:    shr.u16 %rs15, %rs9, 7;
+; CHECK-NEXT:    and.b16 %rs16, %rs15, %rs14;
+; CHECK-NEXT:    add.s16 %rs17, %rs10, %rs16;
+; CHECK-NEXT:    setp.gt.s16 %p5, %rs17, 3;
+; CHECK-NEXT:    selp.b16 %rs18, 0, %rs17, %p5;
+; CHECK-NEXT:    selp.b16 %rs19, 1, 0, %p5;
+; CHECK-NEXT:    sub.s16 %rs20, 6, %rs5;
+; CHECK-NEXT:    selp.b16 %rs21, %rs20, %rs4, %p3;
+; CHECK-NEXT:    add.s16 %rs22, %rs21, %rs19;
+; CHECK-NEXT:    shl.b16 %rs23, %rs22, 2;
+; CHECK-NEXT:    shr.u16 %rs24, %rs1, 8;
+; CHECK-NEXT:    and.b16 %rs25, %rs24, 128;
+; CHECK-NEXT:    or.b16 %rs26, %rs25, %rs23;
+; CHECK-NEXT:    or.b16 %rs27, %rs26, %rs18;
+; CHECK-NEXT:    or.b16 %rs28, %rs9, 1024;
+; CHECK-NEXT:    sub.s16 %rs29, 9, %rs21;
+; CHECK-NEXT:    min.u16 %rs30, %rs29, 15;
+; CHECK-NEXT:    cvt.u32.u16 %r5, %rs30;
+; CHECK-NEXT:    shr.u16 %rs31, %rs28, %r5;
+; CHECK-NEXT:    and.b16 %rs32, %rs31, 1;
+; CHECK-NEXT:    max.u16 %rs33, %rs30, 1;
+; CHECK-NEXT:    add.s16 %rs34, %rs33, -1;
+; CHECK-NEXT:    cvt.u32.u16 %r6, %rs34;
+; CHECK-NEXT:    mov.b16 %rs35, 1;
+; CHECK-NEXT:    shl.b16 %rs36, %rs35, %r6;
+; CHECK-NEXT:    add.s16 %rs37, %rs36, -1;
+; CHECK-NEXT:    and.b16 %rs38, %rs28, %rs37;
+; CHECK-NEXT:    setp.ne.b16 %p6, %rs38, 0;
+; CHECK-NEXT:    selp.b16 %rs39, 1, 0, %p6;
+; CHECK-NEXT:    or.b16 %rs40, %rs39, %rs32;
+; CHECK-NEXT:    shr.u16 %rs41, %rs28, %r6;
+; CHECK-NEXT:    and.b16 %rs42, %rs41, %rs40;
+; CHECK-NEXT:    setp.ne.b16 %p7, %rs30, 0;
+; CHECK-NEXT:    selp.b16 %rs43, %rs42, 0, %p7;
+; CHECK-NEXT:    add.s16 %rs44, %rs31, %rs43;
+; CHECK-NEXT:    setp.gt.s16 %p8, %rs44, 3;
+; CHECK-NEXT:    selp.b16 %rs45, 0, %rs44, %p8;
+; CHECK-NEXT:    selp.b16 %rs46, 4, 0, %p8;
+; CHECK-NEXT:    or.b16 %rs47, %rs25, %rs46;
+; CHECK-NEXT:    or.b16 %rs48, %rs47, %rs45;
+; CHECK-NEXT:    setp.lt.s16 %p9, %rs22, 1;
+; CHECK-NEXT:    selp.b16 %rs49, %rs48, %rs27, %p9;
+; CHECK-NEXT:    setp.gt.s16 %p10, %rs18, 3;
+; CHECK-NEXT:    or.b16 %rs50, %rs25, 124;
+; CHECK-NEXT:    selp.b16 %rs51, %rs50, %rs49, %p10;
+; CHECK-NEXT:    setp.eq.b16 %p11, %rs22, 30;
+; CHECK-NEXT:    selp.b16 %rs52, %rs51, %rs49, %p11;
+; CHECK-NEXT:    setp.gt.s16 %p12, %rs22, 30;
+; CHECK-NEXT:    selp.b16 %rs53, %rs50, %rs52, %p12;
+; CHECK-NEXT:    or.b16 %rs54, %rs4, %rs2;
+; CHECK-NEXT:    setp.eq.b16 %p13, %rs54, 0;
+; CHECK-NEXT:    selp.b16 %rs55, %rs25, %rs53, %p13;
+; CHECK-NEXT:    setp.eq.b16 %p14, %rs2, 0;
+; CHECK-NEXT:    selp.b16 %rs56, %rs50, %rs55, %p14;
+; CHECK-NEXT:    setp.eq.b16 %p15, %rs4, 31;
+; CHECK-NEXT:    selp.b16 %rs57, %rs56, %rs55, %p15;
+; CHECK-NEXT:    selp.b16 %rs58, 126, %rs57, %p1;
+; CHECK-NEXT:    selp.b16 %rs59, %rs58, %rs57, %p15;
+; CHECK-NEXT:    cvt.u32.u16 %r7, %rs59;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r7;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 from bf16: bfloat -> i8
+define i8 @to_f8e5m2_from_bf16(bfloat %x) {
+; CHECK-LABEL: to_f8e5m2_from_bf16(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<16>;
+; CHECK-NEXT:    .reg .b16 %rs<61>;
+; CHECK-NEXT:    .reg .b32 %r<8>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.b16 %rs1, [to_f8e5m2_from_bf16_param_0];
+; CHECK-NEXT:    and.b16 %rs2, %rs1, 127;
+; CHECK-NEXT:    setp.ne.b16 %p1, %rs2, 0;
+; CHECK-NEXT:    shr.u16 %rs3, %rs1, 7;
+; CHECK-NEXT:    and.b16 %rs4, %rs3, 255;
+; CHECK-NEXT:    setp.eq.b16 %p2, %rs4, 0;
+; CHECK-NEXT:    and.pred %p3, %p2, %p1;
+; CHECK-NEXT:    cvt.u32.u16 %r1, %rs2;
+; CHECK-NEXT:    shl.b32 %r2, %r1, 16;
+; CHECK-NEXT:    clz.b32 %r3, %r2;
+; CHECK-NEXT:    cvt.u16.u32 %rs5, %r3;
+; CHECK-NEXT:    add.s16 %rs6, %rs5, -8;
+; CHECK-NEXT:    cvt.u32.u16 %r4, %rs6;
+; CHECK-NEXT:    shl.b16 %rs7, %rs2, %r4;
+; CHECK-NEXT:    and.b16 %rs8, %rs7, 127;
+; CHECK-NEXT:    selp.b16 %rs9, %rs8, %rs2, %p3;
+; CHECK-NEXT:    shr.u16 %rs10, %rs9, 5;
+; CHECK-NEXT:    and.b16 %rs11, %rs10, 1;
+; CHECK-NEXT:    and.b16 %rs12, %rs9, 15;
+; CHECK-NEXT:    setp.ne.b16 %p4, %rs12, 0;
+; CHECK-NEXT:    selp.b16 %rs13, 1, 0, %p4;
+; CHECK-NEXT:    or.b16 %rs14, %rs13, %rs11;
+; CHECK-NEXT:    shr.u16 %rs15, %rs9, 4;
+; CHECK-NEXT:    and.b16 %rs16, %rs15, %rs14;
+; CHECK-NEXT:    add.s16 %rs17, %rs10, %rs16;
+; CHECK-NEXT:    setp.gt.s16 %p5, %rs17, 3;
+; CHECK-NEXT:    selp.b16 %rs18, 0, %rs17, %p5;
+; CHECK-NEXT:    selp.b16 %rs19, 1, 0, %p5;
+; CHECK-NEXT:    sub.s16 %rs20, 9, %rs5;
+; CHECK-NEXT:    selp.b16 %rs21, %rs20, %rs4, %p3;
+; CHECK-NEXT:    add.s16 %rs22, %rs21, %rs19;
+; CHECK-NEXT:    add.s16 %rs23, %rs22, -112;
+; CHECK-NEXT:    shl.b16 %rs24, %rs23, 2;
+; CHECK-NEXT:    shr.u16 %rs25, %rs1, 8;
+; CHECK-NEXT:    and.b16 %rs26, %rs25, 128;
+; CHECK-NEXT:    or.b16 %rs27, %rs26, %rs24;
+; CHECK-NEXT:    or.b16 %rs28, %rs27, %rs18;
+; CHECK-NEXT:    or.b16 %rs29, %rs9, 128;
+; CHECK-NEXT:    sub.s16 %rs30, 118, %rs21;
+; CHECK-NEXT:    min.u16 %rs31, %rs30, 15;
+; CHECK-NEXT:    cvt.u32.u16 %r5, %rs31;
+; CHECK-NEXT:    shr.u16 %rs32, %rs29, %r5;
+; CHECK-NEXT:    and.b16 %rs33, %rs32, 1;
+; CHECK-NEXT:    max.u16 %rs34, %rs31, 1;
+; CHECK-NEXT:    add.s16 %rs35, %rs34, -1;
+; CHECK-NEXT:    cvt.u32.u16 %r6, %rs35;
+; CHECK-NEXT:    mov.b16 %rs36, 1;
+; CHECK-NEXT:    shl.b16 %rs37, %rs36, %r6;
+; CHECK-NEXT:    add.s16 %rs38, %rs37, -1;
+; CHECK-NEXT:    and.b16 %rs39, %rs29, %rs38;
+; CHECK-NEXT:    setp.ne.b16 %p6, %rs39, 0;
+; CHECK-NEXT:    selp.b16 %rs40, 1, 0, %p6;
+; CHECK-NEXT:    or.b16 %rs41, %rs40, %rs33;
+; CHECK-NEXT:    shr.u16 %rs42, %rs29, %r6;
+; CHECK-NEXT:    and.b16 %rs43, %rs42, %rs41;
+; CHECK-NEXT:    setp.ne.b16 %p7, %rs31, 0;
+; CHECK-NEXT:    selp.b16 %rs44, %rs43, 0, %p7;
+; CHECK-NEXT:    add.s16 %rs45, %rs32, %rs44;
+; CHECK-NEXT:    setp.gt.s16 %p8, %rs45, 3;
+; CHECK-NEXT:    selp.b16 %rs46, 0, %rs45, %p8;
+; CHECK-NEXT:    selp.b16 %rs47, 4, 0, %p8;
+; CHECK-NEXT:    or.b16 %rs48, %rs26, %rs47;
+; CHECK-NEXT:    or.b16 %rs49, %rs48, %rs46;
+; CHECK-NEXT:    setp.lt.s16 %p9, %rs23, 1;
+; CHECK-NEXT:    selp.b16 %rs50, %rs49, %rs28, %p9;
+; CHECK-NEXT:    setp.gt.s16 %p10, %rs18, 3;
+; CHECK-NEXT:    or.b16 %rs51, %rs26, 124;
+; CHECK-NEXT:    selp.b16 %rs52, %rs51, %rs50, %p10;
+; CHECK-NEXT:    setp.eq.b16 %p11, %rs23, 30;
+; CHECK-NEXT:    selp.b16 %rs53, %rs52, %rs50, %p11;
+; CHECK-NEXT:    setp.gt.s16 %p12, %rs23, 30;
+; CHECK-NEXT:    selp.b16 %rs54, %rs51, %rs53, %p12;
+; CHECK-NEXT:    or.b16 %rs55, %rs4, %rs2;
+; CHECK-NEXT:    setp.eq.b16 %p13, %rs55, 0;
+; CHECK-NEXT:    selp.b16 %rs56, %rs26, %rs54, %p13;
+; CHECK-NEXT:    setp.eq.b16 %p14, %rs2, 0;
+; CHECK-NEXT:    selp.b16 %rs57, %rs51, %rs56, %p14;
+; CHECK-NEXT:    setp.eq.b16 %p15, %rs4, 255;
+; CHECK-NEXT:    selp.b16 %rs58, %rs57, %rs56, %p15;
+; CHECK-NEXT:    selp.b16 %rs59, 126, %rs58, %p1;
+; CHECK-NEXT:    selp.b16 %rs60, %rs59, %rs58, %p15;
+; CHECK-NEXT:    cvt.u32.u16 %r7, %rs60;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r7;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 from f64: double -> i8
+define i8 @to_f8e5m2_from_f64(double %x) {
+; CHECK-LABEL: to_f8e5m2_from_f64(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<16>;
+; CHECK-NEXT:    .reg .b32 %r<5>;
+; CHECK-NEXT:    .reg .b64 %rd<61>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.b64 %rd1, [to_f8e5m2_from_f64_param_0];
+; CHECK-NEXT:    and.b64 %rd2, %rd1, 4503599627370495;
+; CHECK-NEXT:    setp.ne.b64 %p1, %rd2, 0;
+; CHECK-NEXT:    shr.u64 %rd3, %rd1, 52;
+; CHECK-NEXT:    and.b64 %rd4, %rd3, 2047;
+; CHECK-NEXT:    setp.eq.b64 %p2, %rd4, 0;
+; CHECK-NEXT:    and.pred %p3, %p2, %p1;
+; CHECK-NEXT:    clz.b64 %r1, %rd2;
+; CHECK-NEXT:    cvt.u64.u32 %rd5, %r1;
+; CHECK-NEXT:    add.s64 %rd6, %rd5, -11;
+; CHECK-NEXT:    cvt.u32.u64 %r2, %rd6;
+; CHECK-NEXT:    shl.b64 %rd7, %rd2, %r2;
+; CHECK-NEXT:    and.b64 %rd8, %rd7, 4503599627370495;
+; CHECK-NEXT:    selp.b64 %rd9, %rd8, %rd2, %p3;
+; CHECK-NEXT:    shr.u64 %rd10, %rd9, 50;
+; CHECK-NEXT:    and.b64 %rd11, %rd10, 1;
+; CHECK-NEXT:    and.b64 %rd12, %rd9, 562949953421311;
+; CHECK-NEXT:    setp.ne.b64 %p4, %rd12, 0;
+; CHECK-NEXT:    selp.b64 %rd13, 1, 0, %p4;
+; CHECK-NEXT:    or.b64 %rd14, %rd13, %rd11;
+; CHECK-NEXT:    shr.u64 %rd15, %rd9, 49;
+; CHECK-NEXT:    and.b64 %rd16, %rd15, %rd14;
+; CHECK-NEXT:    add.s64 %rd17, %rd10, %rd16;
+; CHECK-NEXT:    setp.gt.s64 %p5, %rd17, 3;
+; CHECK-NEXT:    selp.b64 %rd18, 0, %rd17, %p5;
+; CHECK-NEXT:    selp.b64 %rd19, 1, 0, %p5;
+; CHECK-NEXT:    sub.s64 %rd20, 12, %rd5;
+; CHECK-NEXT:    selp.b64 %rd21, %rd20, %rd4, %p3;
+; CHECK-NEXT:    add.s64 %rd22, %rd21, %rd19;
+; CHECK-NEXT:    add.s64 %rd23, %rd22, -1008;
+; CHECK-NEXT:    shl.b64 %rd24, %rd23, 2;
+; CHECK-NEXT:    shr.u64 %rd25, %rd1, 56;
+; CHECK-NEXT:    and.b64 %rd26, %rd25, 128;
+; CHECK-NEXT:    or.b64 %rd27, %rd26, %rd24;
+; CHECK-NEXT:    or.b64 %rd28, %rd27, %rd18;
+; CHECK-NEXT:    or.b64 %rd29, %rd9, 4503599627370496;
+; CHECK-NEXT:    sub.s64 %rd30, 1059, %rd21;
+; CHECK-NEXT:    min.u64 %rd31, %rd30, 63;
+; CHECK-NEXT:    cvt.u32.u64 %r3, %rd31;
+; CHECK-NEXT:    shr.u64 %rd32, %rd29, %r3;
+; CHECK-NEXT:    and.b64 %rd33, %rd32, 1;
+; CHECK-NEXT:    max.u64 %rd34, %rd31, 1;
+; CHECK-NEXT:    add.s64 %rd35, %rd34, -1;
+; CHECK-NEXT:    cvt.u32.u64 %r4, %rd35;
+; CHECK-NEXT:    mov.b64 %rd36, 1;
+; CHECK-NEXT:    shl.b64 %rd37, %rd36, %r4;
+; CHECK-NEXT:    add.s64 %rd38, %rd37, -1;
+; CHECK-NEXT:    and.b64 %rd39, %rd29, %rd38;
+; CHECK-NEXT:    setp.ne.b64 %p6, %rd39, 0;
+; CHECK-NEXT:    selp.b64 %rd40, 1, 0, %p6;
+; CHECK-NEXT:    or.b64 %rd41, %rd40, %rd33;
+; CHECK-NEXT:    shr.u64 %rd42, %rd29, %r4;
+; CHECK-NEXT:    and.b64 %rd43, %rd42, %rd41;
+; CHECK-NEXT:    setp.ne.b64 %p7, %rd31, 0;
+; CHECK-NEXT:    selp.b64 %rd44, %rd43, 0, %p7;
+; CHECK-NEXT:    add.s64 %rd45, %rd32, %rd44;
+; CHECK-NEXT:    setp.gt.s64 %p8, %rd45, 3;
+; CHECK-NEXT:    selp.b64 %rd46, 0, %rd45, %p8;
+; CHECK-NEXT:    selp.b64 %rd47, 4, 0, %p8;
+; CHECK-NEXT:    or.b64 %rd48, %rd26, %rd47;
+; CHECK-NEXT:    or.b64 %rd49, %rd48, %rd46;
+; CHECK-NEXT:    setp.lt.s64 %p9, %rd23, 1;
+; CHECK-NEXT:    selp.b64 %rd50, %rd49, %rd28, %p9;
+; CHECK-NEXT:    setp.gt.s64 %p10, %rd18, 3;
+; CHECK-NEXT:    or.b64 %rd51, %rd26, 124;
+; CHECK-NEXT:    selp.b64 %rd52, %rd51, %rd50, %p10;
+; CHECK-NEXT:    setp.eq.b64 %p11, %rd23, 30;
+; CHECK-NEXT:    selp.b64 %rd53, %rd52, %rd50, %p11;
+; CHECK-NEXT:    setp.gt.s64 %p12, %rd23, 30;
+; CHECK-NEXT:    selp.b64 %rd54, %rd51, %rd53, %p12;
+; CHECK-NEXT:    or.b64 %rd55, %rd4, %rd2;
+; CHECK-NEXT:    setp.eq.b64 %p13, %rd55, 0;
+; CHECK-NEXT:    selp.b64 %rd56, %rd26, %rd54, %p13;
+; CHECK-NEXT:    setp.eq.b64 %p14, %rd2, 0;
+; CHECK-NEXT:    selp.b64 %rd57, %rd51, %rd56, %p14;
+; CHECK-NEXT:    setp.eq.b64 %p15, %rd4, 2047;
+; CHECK-NEXT:    selp.b64 %rd58, %rd57, %rd56, %p15;
+; CHECK-NEXT:    selp.b64 %rd59, 126, %rd58, %p1;
+; CHECK-NEXT:    selp.b64 %rd60, %rd59, %rd58, %p15;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %rd60;
+; CHECK-NEXT:    ret;
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll
new file mode 100644
index 0000000000000..b1c5139ebede7
--- /dev/null
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll
@@ -0,0 +1,76 @@
+; RUN: split-file %s %t
+; RUN: not llc < %t/float8e4m3.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E4M3
+; RUN: not llc < %t/float8e3m4.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E3M4
+; RUN: not llc < %t/float8e5m2fnuz.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E5M2FNUZ
+; RUN: not llc < %t/float8e4m3fnuz.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E4M3FNUZ
+; RUN: not llc < %t/float8e4m3b11fnuz.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E4M3B11FNUZ
+; RUN: not llc < %t/float8e8m0fnu.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E8M0FNU
+
+; Test that llvm.convert.to.arbitrary.fp emits an error for formats that pass
+; verifier validation but are not yet implemented in SelectionDAGBuilder.
+
+;--- float8e4m3.ll
+; E4M3: error: convert_to_arbitrary_fp: not implemented format 'Float8E4M3'
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+
+define i8 @to_f8e4m3(float %v) {
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(
+      float %v, metadata !"Float8E4M3", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+;--- float8e3m4.ll
+; E3M4: error: convert_to_arbitrary_fp: not implemented format 'Float8E3M4'
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+
+define i8 @to_f8e3m4(float %v) {
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(
+      float %v, metadata !"Float8E3M4", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+;--- float8e5m2fnuz.ll
+; E5M2FNUZ: error: convert_to_arbitrary_fp: not implemented format 'Float8E5M2FNUZ'
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+
+define i8 @to_f8e5m2fnuz(float %v) {
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(
+      float %v, metadata !"Float8E5M2FNUZ", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+;--- float8e4m3fnuz.ll
+; E4M3FNUZ: error: convert_to_arbitrary_fp: not implemented format 'Float8E4M3FNUZ'
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+
+define i8 @to_f8e4m3fnuz(float %v) {
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(
+      float %v, metadata !"Float8E4M3FNUZ", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+;--- float8e4m3b11fnuz.ll
+; E4M3B11FNUZ: error: convert_to_arbitrary_fp: not implemented format 'Float8E4M3B11FNUZ'
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+
+define i8 @to_f8e4m3b11fnuz(float %v) {
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(
+      float %v, metadata !"Float8E4M3B11FNUZ", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+;--- float8e8m0fnu.ll
+; E8M0FNU: error: convert_to_arbitrary_fp: not implemented format 'Float8E8M0FNU'
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+
+define i8 @to_f8e8m0fnu(float %v) {
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(
+      float %v, metadata !"Float8E8M0FNU", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
new file mode 100644
index 0000000000000..619e42ab03718
--- /dev/null
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
@@ -0,0 +1,1323 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+
+; Test llvm.convert.to.arbitrary.fp intrinsic expansion.
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
+declare i6 @llvm.convert.to.arbitrary.fp.i6.f32(float, metadata, metadata, i1)
+declare i4 @llvm.convert.to.arbitrary.fp.i4.f32(float, metadata, metadata, i1)
+declare <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float>, metadata, metadata, i1)
+
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1)
+declare i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat, metadata, metadata, i1)
+declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
+
+; Float8E5M2
+; Layout: sign(1) exp(5) mant(2), bias=15
+; Supports: Inf, NaN, signed zero, denormals
+
+; Float8E5M2 normal: f32 1.0 -> 0_01111_00 = 0x3C
+define i8 @to_f8e5m2_normal() {
+; CHECK-LABEL: to_f8e5m2_normal:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $60, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 zero: f32 0.0 -> 0_00000_00 = 0x00
+define i8 @to_f8e5m2_zero() {
+; CHECK-LABEL: to_f8e5m2_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 negative zero: f32 -0.0 -> 1_00000_00 = 0x80
+define i8 @to_f8e5m2_neg_zero() {
+; CHECK-LABEL: to_f8e5m2_neg_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $-128, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float -0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 +Inf: f32 Inf -> 0_11111_00 = 0x7C
+define i8 @to_f8e5m2_inf() {
+; CHECK-LABEL: to_f8e5m2_inf:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $124, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 NaN: f32 NaN -> 0_11111_10 = 0x7E
+define i8 @to_f8e5m2_nan() {
+; CHECK-LABEL: to_f8e5m2_nan:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $126, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 max: 57344.0 -> 0_11110_11 = 0x7B
+define i8 @to_f8e5m2_max() {
+; CHECK-LABEL: to_f8e5m2_max:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $123, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 57344.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 overflow (no saturation): 100000.0 -> Inf = 0x7C
+define i8 @to_f8e5m2_overflow() {
+; CHECK-LABEL: to_f8e5m2_overflow:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $124, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 overflow with saturation: 100000.0 -> max = 0x7B
+define i8 @to_f8e5m2_overflow_sat() {
+; CHECK-LABEL: to_f8e5m2_overflow_sat:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $123, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 true)
+  ret i8 %r
+}
+
+; Float8E5M2 denorm: very small value -> dst denorm
+define i8 @to_f8e5m2_denorm() {
+  ; 2^(-16) = 0x00010000 in f32 = 1.52587891e-5
+; CHECK-LABEL: to_f8e5m2_denorm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $1, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x3EF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E5M2 dynamic input
+define i8 @to_f8e5m2_dynamic(float %x) {
+; CHECK-LABEL: to_f8e5m2_dynamic:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    .cfi_offset %rbx, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %eax
+; CHECK-NEXT:    andl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-NEXT:    bsrl %eax, %ecx
+; CHECK-NEXT:    xorl $31, %ecx
+; CHECK-NEXT:    movl $9, %r11d
+; CHECK-NEXT:    subl %ecx, %r11d
+; CHECK-NEXT:    addl $-8, %ecx
+; CHECK-NEXT:    movl %eax, %r10d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r10d
+; CHECK-NEXT:    andl $8388607, %r10d # imm = 0x7FFFFF
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    sete %dil
+; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl $23, %ecx
+; CHECK-NEXT:    movzbl %cl, %r8d
+; CHECK-NEXT:    testl %r8d, %r8d
+; CHECK-NEXT:    sete %r9b
+; CHECK-NEXT:    testb %sil, %r9b
+; CHECK-NEXT:    cmovel %eax, %r10d
+; CHECK-NEXT:    cmovel %r8d, %r11d
+; CHECK-NEXT:    movl $134, %ecx
+; CHECK-NEXT:    subl %r11d, %ecx
+; CHECK-NEXT:    cmpl $31, %ecx
+; CHECK-NEXT:    movl $31, %eax
+; CHECK-NEXT:    cmovbl %ecx, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    leal 8388608(%r10), %ebx
+; CHECK-NEXT:    movl %ebx, %ebp
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl $1, %r14d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r14d
+; CHECK-NEXT:    decl %r14d
+; CHECK-NEXT:    xorl %r15d, %r15d
+; CHECK-NEXT:    testl %r14d, %ebx
+; CHECK-NEXT:    setne %r15b
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebx
+; CHECK-NEXT:    movl %ebx, %r14d
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    orl %r15d, %r14d
+; CHECK-NEXT:    andl %ebp, %r14d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %r14d
+; CHECK-NEXT:    addl %ebx, %r14d
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $4, %r14d
+; CHECK-NEXT:    cmovgel %ecx, %r14d
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    shrl $24, %edx
+; CHECK-NEXT:    andl $-128, %edx
+; CHECK-NEXT:    leal (%rdx,%rax,4), %eax
+; CHECK-NEXT:    orl %r14d, %eax
+; CHECK-NEXT:    movl %r10d, %ebx
+; CHECK-NEXT:    shrl $21, %ebx
+; CHECK-NEXT:    movl %ebx, %ebp
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    testl $1048575, %r10d # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r14b
+; CHECK-NEXT:    orl %ebp, %r14d
+; CHECK-NEXT:    shrl $20, %r10d
+; CHECK-NEXT:    andl %r14d, %r10d
+; CHECK-NEXT:    addl %ebx, %r10d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $4, %r10d
+; CHECK-NEXT:    cmovgel %ecx, %r10d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    leal -112(%r11,%rbx), %ebp
+; CHECK-NEXT:    addl %ebx, %r11d
+; CHECK-NEXT:    leal -448(,%r11,4), %r11d
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    orl %r10d, %ecx
+; CHECK-NEXT:    orl %r11d, %ecx
+; CHECK-NEXT:    testl %ebp, %ebp
+; CHECK-NEXT:    cmovlel %eax, %ecx
+; CHECK-NEXT:    cmpl $4, %r10d
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    cmpl $30, %ebp
+; CHECK-NEXT:    sete %r10b
+; CHECK-NEXT:    andb %al, %r10b
+; CHECK-NEXT:    cmpl $31, %ebp
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %r10b, %al
+; CHECK-NEXT:    leal 124(%rdx), %r10d
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    cmovnel %r10d, %ecx
+; CHECK-NEXT:    testb %dil, %r9b
+; CHECK-NEXT:    cmovnel %edx, %ecx
+; CHECK-NEXT:    cmpl $255, %r8d
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    testb %dil, %al
+; CHECK-NEXT:    cmovnel %r10d, %ecx
+; CHECK-NEXT:    testb %sil, %al
+; CHECK-NEXT:    movl $126, %eax
+; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN
+; Layout: sign(1) exp(4) mant(3), bias=7
+; Supports: NaN (special encoding: 0_1111_111 only), no Inf, signed zero
+
+; Float8E4M3FN normal: f32 1.0 -> 0_0111_000 = 0x38
+define i8 @to_f8e4m3fn_normal() {
+; CHECK-LABEL: to_f8e4m3fn_normal:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $56, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN max: 448.0 -> 0_1111_110 = 0x7E
+define i8 @to_f8e4m3fn_max() {
+; CHECK-LABEL: to_f8e4m3fn_max:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $126, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 448.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN NaN: f32 NaN -> 0_1111_111 = 0x7F
+define i8 @to_f8e4m3fn_nan() {
+; CHECK-LABEL: to_f8e4m3fn_nan:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $127, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Float8E4M3FN overflow with saturation: large value -> max = 0x7E
+define i8 @to_f8e4m3fn_overflow_sat() {
+; CHECK-LABEL: to_f8e4m3fn_overflow_sat:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $126, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1000.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 true)
+  ret i8 %r
+}
+
+; Float6E3M2FN
+; Layout: sign(1) exp(3) mant(2), bias=3
+; Supports: no Inf, no NaN, signed zero (FiniteOnly)
+
+; Float6E3M2FN normal: f32 1.0 -> 0_011_00 = 0x0C
+define i6 @to_f6e3m2fn_normal() {
+; CHECK-LABEL: to_f6e3m2fn_normal:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $12, %al
+; CHECK-NEXT:    retq
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN max: 28.0 -> 0_111_11 = 0x1F
+define i6 @to_f6e3m2fn_max() {
+; CHECK-LABEL: to_f6e3m2fn_max:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $31, %al
+; CHECK-NEXT:    retq
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 28.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN zero: f32 0.0 -> 0_000_00 = 0x00
+define i6 @to_f6e3m2fn_zero() {
+; CHECK-LABEL: to_f6e3m2fn_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    retq
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 0.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E3M2FN negative: f32 -2.0 -> 1_100_00 = 0x30
+define i6 @to_f6e3m2fn_negative() {
+; CHECK-LABEL: to_f6e3m2fn_negative:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $48, %al
+; CHECK-NEXT:    retq
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float -2.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E2M3FN
+; Layout: sign(1) exp(2) mant(3), bias=1
+; Supports: no Inf, no NaN, signed zero (FiniteOnly)
+
+; Float6E2M3FN normal: f32 1.0 -> 0_01_000 = 0x08
+define i6 @to_f6e2m3fn_normal() {
+; CHECK-LABEL: to_f6e2m3fn_normal:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $8, %al
+; CHECK-NEXT:    retq
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float6E2M3FN max: 7.5 -> 0_11_111 = 0x1F
+define i6 @to_f6e2m3fn_max() {
+; CHECK-LABEL: to_f6e2m3fn_max:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $31, %al
+; CHECK-NEXT:    retq
+  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 7.5, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
+  ret i6 %r
+}
+
+; Float4E2M1FN
+; Layout: sign(1) exp(2) mant(1), bias=1
+; Supports: no Inf, no NaN, signed zero (FiniteOnly)
+
+; Float4E2M1FN normal: f32 1.0 -> 0_01_0 = 0x2
+define i4 @to_f4e2m1fn_normal() {
+; CHECK-LABEL: to_f4e2m1fn_normal:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $2, %al
+; CHECK-NEXT:    retq
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 1.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Float4E2M1FN max: 6.0 -> 0_11_1 = 0x7
+define i4 @to_f4e2m1fn_max() {
+; CHECK-LABEL: to_f4e2m1fn_max:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $7, %al
+; CHECK-NEXT:    retq
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 6.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Float4E2M1FN denorm: 0.5 -> 0_00_1 = 0x1
+define i4 @to_f4e2m1fn_denorm() {
+; CHECK-LABEL: to_f4e2m1fn_denorm:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $1, %al
+; CHECK-NEXT:    retq
+  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 0.5, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret i4 %r
+}
+
+; Rounding tests
+
+; Round to nearest even: 1.5 in f32 with E5M2 should round to 1.5 (0_01111_10 = 0x3E)
+define i8 @to_f8e5m2_round_nearest() {
+; CHECK-LABEL: to_f8e5m2_round_nearest:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movb $62, %al
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.5, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; Round toward zero
+define i8 @to_f8e5m2_round_towardzero(float %x) {
+; CHECK-LABEL: to_f8e5m2_round_towardzero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    .cfi_offset %rbx, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    movl %eax, %r11d
+; CHECK-NEXT:    andl $8388607, %r11d # imm = 0x7FFFFF
+; CHECK-NEXT:    bsrl %r11d, %edx
+; CHECK-NEXT:    xorl $31, %edx
+; CHECK-NEXT:    leal -8(%rdx), %ecx
+; CHECK-NEXT:    movl %r11d, %r9d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r9d
+; CHECK-NEXT:    andl $8388607, %r9d # imm = 0x7FFFFF
+; CHECK-NEXT:    movl $9, %r10d
+; CHECK-NEXT:    subl %edx, %r10d
+; CHECK-NEXT:    testl %r11d, %r11d
+; CHECK-NEXT:    sete %sil
+; CHECK-NEXT:    setne %dl
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl $23, %ecx
+; CHECK-NEXT:    movzbl %cl, %edi
+; CHECK-NEXT:    testl %edi, %edi
+; CHECK-NEXT:    sete %r8b
+; CHECK-NEXT:    testb %dl, %r8b
+; CHECK-NEXT:    cmovel %edi, %r10d
+; CHECK-NEXT:    cmovel %r11d, %r9d
+; CHECK-NEXT:    movl %r9d, %r11d
+; CHECK-NEXT:    shrl $21, %r11d
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    cmpl $4, %r11d
+; CHECK-NEXT:    cmovgel %ebp, %r11d
+; CHECK-NEXT:    setge %r14b
+; CHECK-NEXT:    leal (%r10,%r14), %ecx
+; CHECK-NEXT:    leal -448(,%rcx,4), %ebx
+; CHECK-NEXT:    shrl $24, %eax
+; CHECK-NEXT:    andl $-128, %eax
+; CHECK-NEXT:    orl %eax, %ebx
+; CHECK-NEXT:    orl %r11d, %ebx
+; CHECK-NEXT:    movl $134, %r15d
+; CHECK-NEXT:    subl %r10d, %r15d
+; CHECK-NEXT:    cmpl $31, %r15d
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovbl %r15d, %ecx
+; CHECK-NEXT:    orl $8388608, %r9d # imm = 0x800000
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrl %cl, %r9d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $4, %r9d
+; CHECK-NEXT:    cmovgel %ebp, %r9d
+; CHECK-NEXT:    leal -112(%r10,%r14), %r10d
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    leal (%rax,%rcx,4), %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    testl %r10d, %r10d
+; CHECK-NEXT:    cmovgl %ebx, %ecx
+; CHECK-NEXT:    cmpl $4, %r11d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    cmpl $30, %r10d
+; CHECK-NEXT:    sete %r11b
+; CHECK-NEXT:    andb %r9b, %r11b
+; CHECK-NEXT:    cmpl $31, %r10d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    orb %r11b, %r9b
+; CHECK-NEXT:    leal 124(%rax), %r10d
+; CHECK-NEXT:    testb %r9b, %r9b
+; CHECK-NEXT:    cmovnel %r10d, %ecx
+; CHECK-NEXT:    testb %sil, %r8b
+; CHECK-NEXT:    cmovnel %eax, %ecx
+; CHECK-NEXT:    cmpl $255, %edi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    testb %sil, %al
+; CHECK-NEXT:    cmovnel %r10d, %ecx
+; CHECK-NEXT:    testb %dl, %al
+; CHECK-NEXT:    movl $126, %eax
+; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
+  ret i8 %r
+}
+
+; Vector test
+
+; <4 x float> to <4 x i4> (Float4E2M1FN)
+define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f4e2m1fn_v4f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movaps %xmm0, %xmm1
+; CHECK-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
+; CHECK-NEXT:    movd %xmm1, %ecx
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movq %rcx, %rdx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    andl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-NEXT:    bsrl %eax, %ecx
+; CHECK-NEXT:    xorl $31, %ecx
+; CHECK-NEXT:    movl $9, %esi
+; CHECK-NEXT:    subl %ecx, %esi
+; CHECK-NEXT:    addl $-8, %ecx
+; CHECK-NEXT:    movl %eax, %r10d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r10d
+; CHECK-NEXT:    andl $8388607, %r10d # imm = 0x7FFFFF
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
+; CHECK-NEXT:    setne %cl
+; CHECK-NEXT:    # kill: def $edx killed $edx killed $rdx
+; CHECK-NEXT:    shrl $23, %edx
+; CHECK-NEXT:    movzbl %dl, %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    sete %dil
+; CHECK-NEXT:    movb %dil, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
+; CHECK-NEXT:    testb %cl, %dil
+; CHECK-NEXT:    cmovel %eax, %r10d
+; CHECK-NEXT:    cmovel %edx, %esi
+; CHECK-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $149, %eax
+; CHECK-NEXT:    subl %esi, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    movl $31, %r13d
+; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    leal 8388608(%r10), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    movaps %xmm0, %xmm1
+; CHECK-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
+; CHECK-NEXT:    movd %xmm1, %ecx
+; CHECK-NEXT:    movl %ecx, %esi
+; CHECK-NEXT:    movq %rcx, %rbx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
+; CHECK-NEXT:    setne %r8b
+; CHECK-NEXT:    movd %xmm0, %ecx
+; CHECK-NEXT:    movl %ecx, %edx
+; CHECK-NEXT:    movq %rcx, %r14
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %r9d, %ebp
+; CHECK-NEXT:    bsrl %esi, %ecx
+; CHECK-NEXT:    xorl $31, %ecx
+; CHECK-NEXT:    movl $9, %r11d
+; CHECK-NEXT:    subl %ecx, %r11d
+; CHECK-NEXT:    addl $-8, %ecx
+; CHECK-NEXT:    movl %esi, %r12d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r12d
+; CHECK-NEXT:    andl $8388607, %r12d # imm = 0x7FFFFF
+; CHECK-NEXT:    movl %ebx, %eax
+; CHECK-NEXT:    shrl $23, %eax
+; CHECK-NEXT:    movzbl %al, %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    sete %cl
+; CHECK-NEXT:    movb %cl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
+; CHECK-NEXT:    testb %r8b, %cl
+; CHECK-NEXT:    cmovel %esi, %r12d
+; CHECK-NEXT:    cmovel %eax, %r11d
+; CHECK-NEXT:    movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $149, %eax
+; CHECK-NEXT:    subl %r11d, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    leal 8388608(%r12), %r11d
+; CHECK-NEXT:    movl %r11d, %esi
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    movl $1, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r8d
+; CHECK-NEXT:    decl %r8d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    testl %r8d, %r11d
+; CHECK-NEXT:    setne %bl
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r11d
+; CHECK-NEXT:    movl %r11d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r11d
+; CHECK-NEXT:    orl %ebx, %r11d
+; CHECK-NEXT:    andl %esi, %r11d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %r9d, %r11d
+; CHECK-NEXT:    bsrl %edx, %ecx
+; CHECK-NEXT:    xorl $31, %ecx
+; CHECK-NEXT:    movl $9, %esi
+; CHECK-NEXT:    subl %ecx, %esi
+; CHECK-NEXT:    addl $-8, %ecx
+; CHECK-NEXT:    movl %edx, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r8d
+; CHECK-NEXT:    andl $8388607, %r8d # imm = 0x7FFFFF
+; CHECK-NEXT:    movl %r14d, %eax
+; CHECK-NEXT:    shrl $23, %eax
+; CHECK-NEXT:    movzbl %al, %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    sete %cl
+; CHECK-NEXT:    movb %cl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
+; CHECK-NEXT:    testb %dil, %cl
+; CHECK-NEXT:    cmovel %edx, %r8d
+; CHECK-NEXT:    cmovel %eax, %esi
+; CHECK-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $149, %eax
+; CHECK-NEXT:    subl %esi, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    leal 8388608(%r8), %r14d
+; CHECK-NEXT:    movl %r14d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edi
+; CHECK-NEXT:    decl %edi
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    testl %edi, %r14d
+; CHECK-NEXT:    setne %bl
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r14d
+; CHECK-NEXT:    movl %r14d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    orl %ebx, %r14d
+; CHECK-NEXT:    andl %edx, %r14d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %r9d, %r14d
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movd %xmm0, %ecx
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movq %rcx, %rdx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    andl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-NEXT:    bsrl %eax, %ecx
+; CHECK-NEXT:    xorl $31, %ecx
+; CHECK-NEXT:    movl $9, %r15d
+; CHECK-NEXT:    subl %ecx, %r15d
+; CHECK-NEXT:    addl $-8, %ecx
+; CHECK-NEXT:    movl %eax, %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edi
+; CHECK-NEXT:    andl $8388607, %edi # imm = 0x7FFFFF
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
+; CHECK-NEXT:    setne %cl
+; CHECK-NEXT:    movl %edx, %ebx
+; CHECK-NEXT:    shrl $23, %ebx
+; CHECK-NEXT:    movzbl %bl, %ebx
+; CHECK-NEXT:    testl %ebx, %ebx
+; CHECK-NEXT:    sete %dl
+; CHECK-NEXT:    movb %dl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
+; CHECK-NEXT:    testb %cl, %dl
+; CHECK-NEXT:    cmovel %eax, %edi
+; CHECK-NEXT:    cmovel %ebx, %r15d
+; CHECK-NEXT:    movl $149, %edx
+; CHECK-NEXT:    subl %r15d, %edx
+; CHECK-NEXT:    cmpl $31, %edx
+; CHECK-NEXT:    cmovael %r13d, %edx
+; CHECK-NEXT:    cmpl $1, %edx
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    leal 8388608(%rdi), %r13d
+; CHECK-NEXT:    movl %r13d, %ebx
+; CHECK-NEXT:    shrl %cl, %ebx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    decl %eax
+; CHECK-NEXT:    xorl %esi, %esi
+; CHECK-NEXT:    testl %eax, %r13d
+; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %r13d
+; CHECK-NEXT:    movl %r13d, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    orl %esi, %ecx
+; CHECK-NEXT:    andl %ebx, %ecx
+; CHECK-NEXT:    cmpl $1, %edx
+; CHECK-NEXT:    movl $0, %edx
+; CHECK-NEXT:    cmovbl %edx, %ecx
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $2, %ebp
+; CHECK-NEXT:    cmovgel %edx, %ebp
+; CHECK-NEXT:    movl $0, %ebx
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    addl %eax, %eax
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
+; CHECK-NEXT:    shrl $31, %edx
+; CHECK-NEXT:    leal (%rax,%rdx,8), %r9d
+; CHECK-NEXT:    movq %rdx, %rax
+; CHECK-NEXT:    orl %ebp, %r9d
+; CHECK-NEXT:    movl %r10d, %edx
+; CHECK-NEXT:    shrl $22, %edx
+; CHECK-NEXT:    xorl %esi, %esi
+; CHECK-NEXT:    testl $2097151, %r10d # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    orl %edx, %esi
+; CHECK-NEXT:    shrl $21, %r10d
+; CHECK-NEXT:    andl %esi, %r10d
+; CHECK-NEXT:    addl %edx, %r10d
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    cmpl $2, %r10d
+; CHECK-NEXT:    cmovgel %ebx, %r10d
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload
+; CHECK-NEXT:    leal (%rbp,%rdx), %esi
+; CHECK-NEXT:    leal -252(%rsi,%rsi), %esi
+; CHECK-NEXT:    shll $3, %eax
+; CHECK-NEXT:    orl %eax, %r10d
+; CHECK-NEXT:    orl %esi, %r10d
+; CHECK-NEXT:    leal -126(%rbp,%rdx), %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %r9d, %r10d
+; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %edx # 1-byte Folded Reload
+; CHECK-NEXT:    testb %dl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
+; CHECK-NEXT:    cmovnel %eax, %r10d
+; CHECK-NEXT:    movd %r10d, %xmm1
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $2, %r11d
+; CHECK-NEXT:    cmovgel %ebx, %r11d
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    addl %eax, %eax
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload
+; CHECK-NEXT:    shrl $31, %r9d
+; CHECK-NEXT:    leal (%rax,%r9,8), %eax
+; CHECK-NEXT:    orl %r11d, %eax
+; CHECK-NEXT:    movl %r12d, %edx
+; CHECK-NEXT:    shrl $22, %edx
+; CHECK-NEXT:    xorl %esi, %esi
+; CHECK-NEXT:    testl $2097151, %r12d # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    orl %edx, %esi
+; CHECK-NEXT:    shrl $21, %r12d
+; CHECK-NEXT:    andl %esi, %r12d
+; CHECK-NEXT:    addl %edx, %r12d
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    cmpl $2, %r12d
+; CHECK-NEXT:    cmovgel %ebx, %r12d
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload
+; CHECK-NEXT:    leal (%r10,%rdx), %esi
+; CHECK-NEXT:    leal -252(%rsi,%rsi), %esi
+; CHECK-NEXT:    shll $3, %r9d
+; CHECK-NEXT:    orl %r9d, %r12d
+; CHECK-NEXT:    orl %esi, %r12d
+; CHECK-NEXT:    leal -126(%r10,%rdx), %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %eax, %r12d
+; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
+; CHECK-NEXT:    testb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
+; CHECK-NEXT:    cmovnel %r9d, %r12d
+; CHECK-NEXT:    movd %r12d, %xmm2
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $2, %r14d
+; CHECK-NEXT:    cmovgel %ebx, %r14d
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    addl %eax, %eax
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload
+; CHECK-NEXT:    shrl $31, %r9d
+; CHECK-NEXT:    leal (%rax,%r9,8), %eax
+; CHECK-NEXT:    orl %r14d, %eax
+; CHECK-NEXT:    movl %r8d, %edx
+; CHECK-NEXT:    shrl $22, %edx
+; CHECK-NEXT:    xorl %esi, %esi
+; CHECK-NEXT:    testl $2097151, %r8d # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    orl %edx, %esi
+; CHECK-NEXT:    shrl $21, %r8d
+; CHECK-NEXT:    andl %esi, %r8d
+; CHECK-NEXT:    addl %edx, %r8d
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    cmpl $2, %r8d
+; CHECK-NEXT:    cmovgel %ebx, %r8d
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload
+; CHECK-NEXT:    leal (%r10,%rdx), %esi
+; CHECK-NEXT:    leal -252(%rsi,%rsi), %esi
+; CHECK-NEXT:    shll $3, %r9d
+; CHECK-NEXT:    orl %r9d, %r8d
+; CHECK-NEXT:    orl %esi, %r8d
+; CHECK-NEXT:    leal -126(%r10,%rdx), %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %eax, %r8d
+; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
+; CHECK-NEXT:    testb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
+; CHECK-NEXT:    cmovnel %r9d, %r8d
+; CHECK-NEXT:    movd %r8d, %xmm0
+; CHECK-NEXT:    addl %r13d, %ecx
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $2, %ecx
+; CHECK-NEXT:    cmovgel %ebx, %ecx
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    addl %eax, %eax
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload
+; CHECK-NEXT:    shrl $31, %esi
+; CHECK-NEXT:    leal (%rax,%rsi,8), %eax
+; CHECK-NEXT:    orl %ecx, %eax
+; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    shrl $22, %ecx
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    testl $2097151, %edi # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %dl
+; CHECK-NEXT:    orl %ecx, %edx
+; CHECK-NEXT:    shrl $21, %edi
+; CHECK-NEXT:    andl %edx, %edi
+; CHECK-NEXT:    addl %ecx, %edi
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $2, %edi
+; CHECK-NEXT:    cmovgel %ebx, %edi
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    leal -126(%r15,%rcx), %edx
+; CHECK-NEXT:    addl %ecx, %r15d
+; CHECK-NEXT:    leal -252(%r15,%r15), %ecx
+; CHECK-NEXT:    shll $3, %esi
+; CHECK-NEXT:    orl %esi, %edi
+; CHECK-NEXT:    orl %ecx, %edi
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %eax, %edi
+; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
+; CHECK-NEXT:    testb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
+; CHECK-NEXT:    cmovnel %esi, %edi
+; CHECK-NEXT:    movd %edi, %xmm3
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
+  ret <4 x i4> %r
+}
+
+; Different source types
+
+; f16 -> i8 (Float8E5M2)
+define i8 @to_f8e5m2_from_f16(half %x) {
+; CHECK-LABEL: to_f8e5m2_from_f16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    pextrw $0, %xmm0, %eax
+; CHECK-NEXT:    movl %eax, %r11d
+; CHECK-NEXT:    andl $1023, %r11d # imm = 0x3FF
+; CHECK-NEXT:    bsrw %r11w, %si
+; CHECK-NEXT:    xorl $15, %esi
+; CHECK-NEXT:    leal -5(%rsi), %ecx
+; CHECK-NEXT:    movl %r11d, %edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edx
+; CHECK-NEXT:    andl $1023, %edx # imm = 0x3FF
+; CHECK-NEXT:    movl $6, %r10d
+; CHECK-NEXT:    subl %esi, %r10d
+; CHECK-NEXT:    testl %r11d, %r11d
+; CHECK-NEXT:    sete %dil
+; CHECK-NEXT:    setne %r13b
+; CHECK-NEXT:    movl %eax, %r8d
+; CHECK-NEXT:    shrl $10, %r8d
+; CHECK-NEXT:    andl $31, %r8d
+; CHECK-NEXT:    sete %r9b
+; CHECK-NEXT:    testb %r13b, %r9b
+; CHECK-NEXT:    cmovel %r11d, %edx
+; CHECK-NEXT:    cmovel %r8d, %r10d
+; CHECK-NEXT:    movl $9, %r11d
+; CHECK-NEXT:    subl %r10d, %r11d
+; CHECK-NEXT:    cmpw $15, %r11w
+; CHECK-NEXT:    movl $15, %ecx
+; CHECK-NEXT:    cmovbl %r11d, %ecx
+; CHECK-NEXT:    movl %ecx, %ebx
+; CHECK-NEXT:    leal 1024(%rdx), %r11d
+; CHECK-NEXT:    movl %r11d, %ebp
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, %r14d
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    cmpw $1, %cx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movl $1, %r15d
+; CHECK-NEXT:    shll %cl, %r15d
+; CHECK-NEXT:    decl %r15d
+; CHECK-NEXT:    xorl %r12d, %r12d
+; CHECK-NEXT:    testw %r15w, %r11w
+; CHECK-NEXT:    setne %r12b
+; CHECK-NEXT:    orl %r14d, %r12d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrl %cl, %r11d
+; CHECK-NEXT:    andl %r12d, %r11d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpw $1, %bx
+; CHECK-NEXT:    cmovbl %ecx, %r11d
+; CHECK-NEXT:    addl %ebp, %r11d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpw $4, %r11w
+; CHECK-NEXT:    cmovgel %ecx, %r11d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    shrl $8, %eax
+; CHECK-NEXT:    andl $128, %eax
+; CHECK-NEXT:    leal (%rax,%rbx,4), %ebx
+; CHECK-NEXT:    orl %r11d, %ebx
+; CHECK-NEXT:    movzbl %dh, %esi
+; CHECK-NEXT:    movl %esi, %ebp
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testb $127, %dl
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ebp, %r11d
+; CHECK-NEXT:    shrl $7, %edx
+; CHECK-NEXT:    andl %r11d, %edx
+; CHECK-NEXT:    addl %esi, %edx
+; CHECK-NEXT:    xorl %esi, %esi
+; CHECK-NEXT:    cmpw $4, %dx
+; CHECK-NEXT:    cmovgel %ecx, %edx
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    setge %sil
+; CHECK-NEXT:    addl %r10d, %esi
+; CHECK-NEXT:    movl %esi, %r10d
+; CHECK-NEXT:    shll $2, %r10d
+; CHECK-NEXT:    orl %eax, %edx
+; CHECK-NEXT:    orl %r10d, %edx
+; CHECK-NEXT:    testw %si, %si
+; CHECK-NEXT:    cmovlel %ebx, %edx
+; CHECK-NEXT:    cmpw $4, %cx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    cmpw $30, %si
+; CHECK-NEXT:    sete %r10b
+; CHECK-NEXT:    andb %cl, %r10b
+; CHECK-NEXT:    cmpw $31, %si
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    orb %r10b, %cl
+; CHECK-NEXT:    leal 124(%rax), %esi
+; CHECK-NEXT:    testb %cl, %cl
+; CHECK-NEXT:    cmovnel %esi, %edx
+; CHECK-NEXT:    testb %dil, %r9b
+; CHECK-NEXT:    cmovnel %eax, %edx
+; CHECK-NEXT:    cmpw $31, %r8w
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    testb %dil, %al
+; CHECK-NEXT:    cmovnel %esi, %edx
+; CHECK-NEXT:    testb %r13b, %al
+; CHECK-NEXT:    movl $126, %eax
+; CHECK-NEXT:    cmovel %edx, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; bf16 -> i8 (Float8E5M2)
+define i8 @to_f8e5m2_from_bf16(bfloat %x) {
+; CHECK-LABEL: to_f8e5m2_from_bf16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    .cfi_offset %rbx, -48
+; CHECK-NEXT:    .cfi_offset %r12, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    pextrw $0, %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %eax
+; CHECK-NEXT:    andl $127, %eax
+; CHECK-NEXT:    shll $16, %eax
+; CHECK-NEXT:    bsrl %eax, %esi
+; CHECK-NEXT:    xorl $31, %esi
+; CHECK-NEXT:    leal -8(%rsi), %ecx
+; CHECK-NEXT:    movl %eax, %r9d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r9d
+; CHECK-NEXT:    andl $8323072, %r9d # imm = 0x7F0000
+; CHECK-NEXT:    movl $9, %r11d
+; CHECK-NEXT:    subl %esi, %r11d
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    sete %dil
+; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl $7, %ecx
+; CHECK-NEXT:    movzbl %cl, %r8d
+; CHECK-NEXT:    testl %r8d, %r8d
+; CHECK-NEXT:    sete %r10b
+; CHECK-NEXT:    testb %sil, %r10b
+; CHECK-NEXT:    cmovel %eax, %r9d
+; CHECK-NEXT:    cmovel %r8d, %r11d
+; CHECK-NEXT:    leal 8388608(%r9), %ebx
+; CHECK-NEXT:    movl $134, %ecx
+; CHECK-NEXT:    subl %r11d, %ecx
+; CHECK-NEXT:    cmpl $31, %ecx
+; CHECK-NEXT:    movl $31, %eax
+; CHECK-NEXT:    cmovbl %ecx, %eax
+; CHECK-NEXT:    movl %ebx, %ebp
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, %r14d
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movl $1, %r15d
+; CHECK-NEXT:    shll %cl, %r15d
+; CHECK-NEXT:    decl %r15d
+; CHECK-NEXT:    xorl %r12d, %r12d
+; CHECK-NEXT:    testl %r15d, %ebx
+; CHECK-NEXT:    setne %r12b
+; CHECK-NEXT:    orl %r14d, %r12d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrl %cl, %ebx
+; CHECK-NEXT:    andl %r12d, %ebx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %ebx
+; CHECK-NEXT:    addl %ebp, %ebx
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpl $4, %ebx
+; CHECK-NEXT:    cmovgel %ecx, %ebx
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    shrl $8, %edx
+; CHECK-NEXT:    andl $128, %edx
+; CHECK-NEXT:    leal (%rdx,%rax,4), %eax
+; CHECK-NEXT:    orl %ebx, %eax
+; CHECK-NEXT:    movl %r9d, %ebx
+; CHECK-NEXT:    shrl $21, %ebx
+; CHECK-NEXT:    movl %ebx, %ebp
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    testl $983040, %r9d # imm = 0xF0000
+; CHECK-NEXT:    setne %r14b
+; CHECK-NEXT:    orl %ebp, %r14d
+; CHECK-NEXT:    shrl $20, %r9d
+; CHECK-NEXT:    andl %r14d, %r9d
+; CHECK-NEXT:    addl %ebx, %r9d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $4, %r9d
+; CHECK-NEXT:    cmovgel %ecx, %r9d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    leal -112(%r11,%rbx), %ebp
+; CHECK-NEXT:    addl %ebx, %r11d
+; CHECK-NEXT:    leal -448(,%r11,4), %r11d
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    orl %r11d, %ecx
+; CHECK-NEXT:    testl %ebp, %ebp
+; CHECK-NEXT:    cmovlel %eax, %ecx
+; CHECK-NEXT:    cmpl $4, %r9d
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    cmpl $30, %ebp
+; CHECK-NEXT:    sete %r9b
+; CHECK-NEXT:    andb %al, %r9b
+; CHECK-NEXT:    cmpl $31, %ebp
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %r9b, %al
+; CHECK-NEXT:    leal 124(%rdx), %r9d
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    cmovnel %r9d, %ecx
+; CHECK-NEXT:    testb %dil, %r10b
+; CHECK-NEXT:    cmovnel %edx, %ecx
+; CHECK-NEXT:    cmpl $255, %r8d
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    testb %dil, %al
+; CHECK-NEXT:    cmovnel %r9d, %ecx
+; CHECK-NEXT:    testb %sil, %al
+; CHECK-NEXT:    movl $126, %eax
+; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}
+
+; f64 -> i8 (Float8E5M2)
+define i8 @to_f8e5m2_from_f64(double %x) {
+; CHECK-LABEL: to_f8e5m2_from_f64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    .cfi_offset %rbx, -48
+; CHECK-NEXT:    .cfi_offset %r12, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movq %xmm0, %rsi
+; CHECK-NEXT:    movabsq $4503599627370495, %rax # imm = 0xFFFFFFFFFFFFF
+; CHECK-NEXT:    movq %rsi, %rdx
+; CHECK-NEXT:    andq %rax, %rdx
+; CHECK-NEXT:    bsrq %rdx, %rdi
+; CHECK-NEXT:    xorq $63, %rdi
+; CHECK-NEXT:    leaq -11(%rdi), %rcx
+; CHECK-NEXT:    movq %rdx, %r10
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
+; CHECK-NEXT:    shlq %cl, %r10
+; CHECK-NEXT:    andq %rax, %r10
+; CHECK-NEXT:    movl $12, %ebx
+; CHECK-NEXT:    subq %rdi, %rbx
+; CHECK-NEXT:    testq %rdx, %rdx
+; CHECK-NEXT:    sete %r8b
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movq %rsi, %r9
+; CHECK-NEXT:    shrq $52, %r9
+; CHECK-NEXT:    andl $2047, %r9d # imm = 0x7FF
+; CHECK-NEXT:    sete %r11b
+; CHECK-NEXT:    testb %dil, %r11b
+; CHECK-NEXT:    cmoveq %rdx, %r10
+; CHECK-NEXT:    cmoveq %r9, %rbx
+; CHECK-NEXT:    movl $1059, %ecx # imm = 0x423
+; CHECK-NEXT:    subq %rbx, %rcx
+; CHECK-NEXT:    cmpq $63, %rcx
+; CHECK-NEXT:    movl $63, %eax
+; CHECK-NEXT:    cmovbq %rcx, %rax
+; CHECK-NEXT:    cmpq $1, %rax
+; CHECK-NEXT:    movq %rax, %rdx
+; CHECK-NEXT:    adcq $0, %rdx
+; CHECK-NEXT:    decl %edx
+; CHECK-NEXT:    movl $1, %r15d
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shlq %cl, %r15
+; CHECK-NEXT:    decq %r15
+; CHECK-NEXT:    movabsq $4503599627370496, %r14 # imm = 0x10000000000000
+; CHECK-NEXT:    orq %r10, %r14
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    testq %r15, %r14
+; CHECK-NEXT:    setne %bpl
+; CHECK-NEXT:    movq %r14, %r15
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrq %cl, %r15
+; CHECK-NEXT:    movl %r15d, %r12d
+; CHECK-NEXT:    andl $1, %r12d
+; CHECK-NEXT:    orl %ebp, %r12d
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrq %cl, %r14
+; CHECK-NEXT:    andl %r12d, %r14d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpq $1, %rax
+; CHECK-NEXT:    cmovbq %rcx, %r14
+; CHECK-NEXT:    addq %r15, %r14
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpq $4, %r14
+; CHECK-NEXT:    cmovgeq %rcx, %r14
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    shrq $63, %rsi
+; CHECK-NEXT:    shll $7, %esi
+; CHECK-NEXT:    leal (%rsi,%rax,4), %eax
+; CHECK-NEXT:    orq %r14, %rax
+; CHECK-NEXT:    movq %r10, %rdx
+; CHECK-NEXT:    shrq $50, %rdx
+; CHECK-NEXT:    movl %edx, %ebp
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    movq %r10, %r15
+; CHECK-NEXT:    shlq $15, %r15
+; CHECK-NEXT:    setne %r14b
+; CHECK-NEXT:    orl %ebp, %r14d
+; CHECK-NEXT:    shrq $49, %r10
+; CHECK-NEXT:    andl %r14d, %r10d
+; CHECK-NEXT:    addq %rdx, %r10
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    cmpq $4, %r10
+; CHECK-NEXT:    cmovgeq %rcx, %r10
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    leaq -1008(%rbx,%rdx), %r14
+; CHECK-NEXT:    addq %rdx, %rbx
+; CHECK-NEXT:    leaq -4032(,%rbx,4), %rdx
+; CHECK-NEXT:    movq %rsi, %rcx
+; CHECK-NEXT:    orq %r10, %rcx
+; CHECK-NEXT:    orq %rdx, %rcx
+; CHECK-NEXT:    testq %r14, %r14
+; CHECK-NEXT:    cmovleq %rax, %rcx
+; CHECK-NEXT:    cmpq $4, %r10
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    cmpq $30, %r14
+; CHECK-NEXT:    sete %dl
+; CHECK-NEXT:    andb %al, %dl
+; CHECK-NEXT:    cmpq $31, %r14
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %dl, %al
+; CHECK-NEXT:    leaq 124(%rsi), %rdx
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    cmovneq %rdx, %rcx
+; CHECK-NEXT:    testb %r8b, %r11b
+; CHECK-NEXT:    cmovneq %rsi, %rcx
+; CHECK-NEXT:    cmpq $2047, %r9 # imm = 0x7FF
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    testb %r8b, %al
+; CHECK-NEXT:    cmovneq %rdx, %rcx
+; CHECK-NEXT:    testb %dil, %al
+; CHECK-NEXT:    movl $126, %eax
+; CHECK-NEXT:    cmoveq %rcx, %rax
+; CHECK-NEXT:    # kill: def $al killed $al killed $rax
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret i8 %r
+}

>From cc09573aa8acd954aaabd65de36d2146595a82b1 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Wed, 22 Apr 2026 23:01:40 +0200
Subject: [PATCH 2/9] format

---
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 160 ++++++++----------
 .../SelectionDAG/LegalizeFloatTypes.cpp       |   6 +-
 .../SelectionDAG/LegalizeVectorTypes.cpp      |  23 ++-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |   7 +-
 4 files changed, 88 insertions(+), 108 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 7dcc3a1f1c753..22de6665cadc5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3869,11 +3869,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     SDValue SrcMantField = DAG.getNode(ISD::AND, dl, IntVT, Src,
                                        DAG.getConstant(SrcMantMask, dl, IntVT));
 
-    SDValue SrcExpField = DAG.getNode(
-        ISD::AND, dl, IntVT,
-        DAG.getNode(ISD::SRL, dl, IntVT, Src,
-                    DAG.getShiftAmountConstant(SrcMant, IntVT, dl)),
-        DAG.getConstant(SrcExpMask, dl, IntVT));
+    SDValue SrcExpField =
+        DAG.getNode(ISD::AND, dl, IntVT,
+                    DAG.getNode(ISD::SRL, dl, IntVT, Src,
+                                DAG.getShiftAmountConstant(SrcMant, IntVT, dl)),
+                    DAG.getConstant(SrcExpMask, dl, IntVT));
 
     SDValue SignBit =
         DAG.getNode(ISD::SRL, dl, IntVT, Src,
@@ -3897,8 +3897,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     SDValue IsInf =
         DAG.getNode(ISD::AND, dl, SetCCVT, IsExpAllOnes, IsMantZero);
     // Zero = exp == 0 && mant == 0.
-    SDValue IsZero =
-        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantZero);
+    SDValue IsZero = DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantZero);
     // Source denorm = exp == 0 && mant != 0.
     SDValue IsSrcDenorm =
         DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantNonZero);
@@ -3922,8 +3921,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
                     DAG.getConstant(SrcMantMask, dl, IntVT));
 
     // effective_exp = 1 - NormShift.
-    SDValue DenormSrcExp =
-        DAG.getNode(ISD::SUB, dl, IntVT, One, NormShift);
+    SDValue DenormSrcExp = DAG.getNode(ISD::SUB, dl, IntVT, One, NormShift);
 
     // Select between normal and denorm source.
     SDValue EffSrcExp =
@@ -3984,8 +3982,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     if (SrcMant > DstMant) {
       const unsigned Shift = SrcMant - DstMant;
       SDValue ShiftConst = DAG.getShiftAmountConstant(Shift, IntVT, dl);
-      TruncMant =
-          DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant, ShiftConst);
+      TruncMant = DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant, ShiftConst);
 
       // Check bit at position Shift - 1 aka the round bit.
       SDValue RoundBit;
@@ -4006,8 +4003,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
         StickyBits = DAG.getNode(ISD::AND, dl, IntVT, EffSrcMant,
                                  DAG.getConstant(StickyMask, dl, IntVT));
         StickyBits = DAG.getSetCC(dl, SetCCVT, StickyBits, Zero, ISD::SETNE);
-        StickyBits =
-            DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, StickyBits);
+        StickyBits = DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, StickyBits);
       } else {
         StickyBits = Zero;
       }
@@ -4025,62 +4021,56 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     }
 
     // Apply rounding.
-    SDValue RoundedMant =
-        DAG.getNode(ISD::ADD, dl, IntVT, TruncMant, RoundUp);
+    SDValue RoundedMant = DAG.getNode(ISD::ADD, dl, IntVT, TruncMant, RoundUp);
 
     // Handle mantissa overflow from rounding.
     // If rounded_mant > DstMantMask, carry into exponent.
-    SDValue MantOverflow = DAG.getSetCC(
-        dl, SetCCVT, RoundedMant,
-        DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
+    SDValue MantOverflow =
+        DAG.getSetCC(dl, SetCCVT, RoundedMant,
+                     DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
     // On overflow: mant = 0, exp += 1.
-    SDValue AdjMant =
-        DAG.getSelect(dl, IntVT, MantOverflow, Zero, RoundedMant);
-    SDValue AdjExp = DAG.getNode(
-        ISD::ADD, dl, IntVT, NewExp,
-        DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, MantOverflow));
+    SDValue AdjMant = DAG.getSelect(dl, IntVT, MantOverflow, Zero, RoundedMant);
+    SDValue AdjExp =
+        DAG.getNode(ISD::ADD, dl, IntVT, NewExp,
+                    DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, MantOverflow));
 
     // Precompute sign shifted to MSB of destination.
-    SDValue SignShifted = DAG.getNode(
-        ISD::SHL, dl, IntVT, SignBit,
-        DAG.getShiftAmountConstant(DstBits - 1, IntVT, dl));
+    SDValue SignShifted =
+        DAG.getNode(ISD::SHL, dl, IntVT, SignBit,
+                    DAG.getShiftAmountConstant(DstBits - 1, IntVT, dl));
 
     // Destination denormal conversion (when new_exp <= 0).
     // Shift the mantissa right by 1 - new_exp additional bits and set the
     // exponent field to 0.
-    SDValue ExpIsNeg =
-        DAG.getSetCC(dl, SetCCVT, AdjExp,
-                     DAG.getConstant(1, dl, IntVT), ISD::SETLT);
+    SDValue ExpIsNeg = DAG.getSetCC(dl, SetCCVT, AdjExp,
+                                    DAG.getConstant(1, dl, IntVT), ISD::SETLT);
 
     SDValue DenormResult;
     {
       // denorm_shift = 1 - NewExp.
-      SDValue DenormShift =
-          DAG.getNode(ISD::SUB, dl, IntVT, One, NewExp);
+      SDValue DenormShift = DAG.getNode(ISD::SUB, dl, IntVT, One, NewExp);
 
       // full_src_mant = (1 << SrcMant) | EffSrcMant.
-      SDValue ImplicitOne = DAG.getNode(
-          ISD::SHL, dl, IntVT, One,
-          DAG.getShiftAmountConstant(SrcMant, IntVT, dl));
+      SDValue ImplicitOne =
+          DAG.getNode(ISD::SHL, dl, IntVT, One,
+                      DAG.getShiftAmountConstant(SrcMant, IntVT, dl));
       SDValue FullSrcMant =
           DAG.getNode(ISD::OR, dl, IntVT, EffSrcMant, ImplicitOne);
 
       // Total right shift = (SrcMant - DstMant) + DenormShift
       SDValue TotalShift;
       if (SrcMant >= DstMant) {
-        TotalShift =
-            DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
-                        DAG.getConstant(SrcMant - DstMant, dl, IntVT));
+        TotalShift = DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
+                                 DAG.getConstant(SrcMant - DstMant, dl, IntVT));
       } else {
-        TotalShift =
-            DAG.getNode(ISD::SUB, dl, IntVT, DenormShift,
-                        DAG.getConstant(DstMant - SrcMant, dl, IntVT));
+        TotalShift = DAG.getNode(ISD::SUB, dl, IntVT, DenormShift,
+                                 DAG.getConstant(DstMant - SrcMant, dl, IntVT));
       }
 
       // Clamp total shift to avoid UB, then trancate denorm mantissa.
       SDValue MaxShift = DAG.getConstant(SrcBits - 1, dl, IntVT);
-      SDValue ClampedShift = DAG.getNode(ISD::UMIN, dl, IntVT, TotalShift,
-                                         MaxShift);
+      SDValue ClampedShift =
+          DAG.getNode(ISD::UMIN, dl, IntVT, TotalShift, MaxShift);
       SDValue DenormTruncMant =
           DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, ClampedShift);
 
@@ -4092,8 +4082,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
         // shift nodes with invalid shift amounts.
         SDValue SafeShift =
             DAG.getNode(ISD::UMAX, dl, IntVT, ClampedShift, One);
-        SDValue RoundBitPos =
-            DAG.getNode(ISD::SUB, dl, IntVT, SafeShift, One);
+        SDValue RoundBitPos = DAG.getNode(ISD::SUB, dl, IntVT, SafeShift, One);
         SDValue DenormRoundBit = DAG.getNode(
             ISD::AND, dl, IntVT,
             DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, RoundBitPos), One);
@@ -4105,23 +4094,21 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
             DAG.getNode(ISD::SHL, dl, IntVT, One, RoundBitPos), One);
         SDValue DenormStickyBits =
             DAG.getNode(ISD::AND, dl, IntVT, FullSrcMant, StickyMask);
-        SDValue HasSticky =
-            DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT,
-                        DAG.getSetCC(dl, SetCCVT, DenormStickyBits, Zero,
-                                     ISD::SETNE));
+        SDValue HasSticky = DAG.getNode(
+            ISD::ZERO_EXTEND, dl, IntVT,
+            DAG.getSetCC(dl, SetCCVT, DenormStickyBits, Zero, ISD::SETNE));
 
         SDValue DenormLSB =
             DAG.getNode(ISD::AND, dl, IntVT, DenormTruncMant, One);
 
-        DenormRoundUp =
-            ComputeRoundUp(DenormRoundBit, HasSticky, DenormLSB);
+        DenormRoundUp = ComputeRoundUp(DenormRoundBit, HasSticky, DenormLSB);
 
         // Only apply rounding if TotalShift >= 1 (i.e., there are bits to
         // round).
         SDValue ShiftGEOne =
             DAG.getSetCC(dl, SetCCVT, ClampedShift, One, ISD::SETUGE);
-        DenormRoundUp = DAG.getSelect(dl, IntVT, ShiftGEOne, DenormRoundUp,
-                                      Zero);
+        DenormRoundUp =
+            DAG.getSelect(dl, IntVT, ShiftGEOne, DenormRoundUp, Zero);
       }
 
       SDValue DenormRoundedMant =
@@ -4129,18 +4116,18 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
 
       // If rounding caused overflow into the normal range, then we get the
       // smallest normal number.
-      SDValue DenormMantOF = DAG.getSetCC(
-          dl, SetCCVT, DenormRoundedMant,
-          DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
-      SDValue DenormFinalMant = DAG.getSelect(
-          dl, IntVT, DenormMantOF, Zero, DenormRoundedMant);
-      SDValue DenormFinalExp = DAG.getSelect(
-          dl, IntVT, DenormMantOF, One, Zero);
+      SDValue DenormMantOF =
+          DAG.getSetCC(dl, SetCCVT, DenormRoundedMant,
+                       DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
+      SDValue DenormFinalMant =
+          DAG.getSelect(dl, IntVT, DenormMantOF, Zero, DenormRoundedMant);
+      SDValue DenormFinalExp =
+          DAG.getSelect(dl, IntVT, DenormMantOF, One, Zero);
 
       // Assemble: sign | (exp << DstMant) | mant
-      SDValue DenormExpShifted = DAG.getNode(
-          ISD::SHL, dl, IntVT, DenormFinalExp,
-          DAG.getShiftAmountConstant(DstMant, IntVT, dl));
+      SDValue DenormExpShifted =
+          DAG.getNode(ISD::SHL, dl, IntVT, DenormFinalExp,
+                      DAG.getShiftAmountConstant(DstMant, IntVT, dl));
       DenormResult = DAG.getNode(
           ISD::OR, dl, IntVT,
           DAG.getNode(ISD::OR, dl, IntVT, SignShifted, DenormExpShifted),
@@ -4152,22 +4139,21 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     }
 
     // Exponent overflow detection.
-    SDValue ExpOF = DAG.getSetCC(
-        dl, SetCCVT, AdjExp,
-        DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETGT);
+    SDValue ExpOF =
+        DAG.getSetCC(dl, SetCCVT, AdjExp,
+                     DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETGT);
 
     // Also check if AdjExp == DstExpMaxNormal and mantissa overflow into
     // a value that exceeds the max allowed mantissa at that exponent.
-    SDValue ExpAtMax = DAG.getSetCC(
-        dl, SetCCVT, AdjExp,
-        DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETEQ);
+    SDValue ExpAtMax =
+        DAG.getSetCC(dl, SetCCVT, AdjExp,
+                     DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETEQ);
     SDValue MantExceedsMax = DAG.getSetCC(
-        dl, SetCCVT, AdjMant,
-        DAG.getConstant(DstMaxMantAtMaxExp, dl, IntVT), ISD::SETGT);
+        dl, SetCCVT, AdjMant, DAG.getConstant(DstMaxMantAtMaxExp, dl, IntVT),
+        ISD::SETGT);
     SDValue ExpMantOF =
         DAG.getNode(ISD::AND, dl, SetCCVT, ExpAtMax, MantExceedsMax);
-    SDValue IsOverflow =
-        DAG.getNode(ISD::OR, dl, SetCCVT, ExpOF, ExpMantOF);
+    SDValue IsOverflow = DAG.getNode(ISD::OR, dl, SetCCVT, ExpOF, ExpMantOF);
 
     // Build overflow result.
     SDValue OverflowResult;
@@ -4177,24 +4163,22 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
       // sign | (DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp
       uint64_t MaxFinite =
           ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
-      OverflowResult =
-          DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
-                      DAG.getConstant(MaxFinite, dl, IntVT));
+      OverflowResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                                   DAG.getConstant(MaxFinite, dl, IntVT));
     } else if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
       // Produce infinity.
       uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
-      OverflowResult =
-          DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
-                      DAG.getConstant(InfBits, dl, IntVT));
+      OverflowResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                                   DAG.getConstant(InfBits, dl, IntVT));
     } else {
       // Emit poison if no Inf in format and not saturating.
       OverflowResult = DAG.getPOISON(IntVT);
     }
 
     // Assemble normal result: sign | (AdjExp << DstMant) | AdjMant
-    SDValue NormExpShifted = DAG.getNode(
-        ISD::SHL, dl, IntVT, AdjExp,
-        DAG.getShiftAmountConstant(DstMant, IntVT, dl));
+    SDValue NormExpShifted =
+        DAG.getNode(ISD::SHL, dl, IntVT, AdjExp,
+                    DAG.getShiftAmountConstant(DstMant, IntVT, dl));
     SDValue NormResult = DAG.getNode(
         ISD::OR, dl, IntVT,
         DAG.getNode(ISD::OR, dl, IntVT, SignShifted, NormExpShifted), AdjMant);
@@ -4204,15 +4188,13 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
       // Produce canonical NaN.
       const uint64_t QNaNBit = (DstMant > 0) ? (1ULL << (DstMant - 1)) : 0;
-      NaNResult =
-          DAG.getConstant(((uint64_t)DstExpMax << DstMant) | QNaNBit, dl,
-                          IntVT);
+      NaNResult = DAG.getConstant(((uint64_t)DstExpMax << DstMant) | QNaNBit,
+                                  dl, IntVT);
     } else if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
                DstNanEnc == fltNanEncoding::AllOnes) {
       // E4M3FN-style: NaN is exp=all-ones, mant=all-ones.
-      NaNResult =
-          DAG.getConstant(((uint64_t)DstExpMax << DstMant) | DstMantMask, dl,
-                          IntVT);
+      NaNResult = DAG.getConstant(
+          ((uint64_t)DstExpMax << DstMant) | DstMantMask, dl, IntVT);
     } else {
       // NaN -> poison for finite only values.
       NaNResult = DAG.getPOISON(IntVT);
@@ -4239,8 +4221,8 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     SDValue ZeroResult = SignShifted;
 
     // Final selection in an order: NaN takes priority, then Inf, then Zero.
-    SDValue FiniteResult = DAG.getSelect(dl, IntVT, ExpIsNeg, DenormResult,
-                                         NormResult);
+    SDValue FiniteResult =
+        DAG.getSelect(dl, IntVT, ExpIsNeg, DenormResult, NormResult);
     FiniteResult =
         DAG.getSelect(dl, IntVT, IsOverflow, OverflowResult, FiniteResult);
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 65a031027b4b1..102e05358b902 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -3195,7 +3195,8 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
   case ISD::FP_TO_UINT_SAT:
                         Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
   case ISD::CONVERT_TO_ARBITRARY_FP:
-                        Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(N); break;
+    Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(N);
+    break;
   case ISD::STRICT_FP_EXTEND:
   case ISD::FP_EXTEND:  Res = SoftPromoteHalfOp_FP_EXTEND(N); break;
   case ISD::SELECT_CC:  Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break;
@@ -3314,8 +3315,7 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
 // TODO: CONVERT_TO_ARBITRARY_FP also needs SoftenFloatOperand and
 // ExpandFloatOperand handlers for targets with software float or ppcf128
 // source types. Same gap exists for CONVERT_FROM_ARBITRARY_FP.
-SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
-    SDNode *N) {
+SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(SDNode *N) {
   EVT RVT = N->getValueType(0);
   SDValue Op = N->getOperand(0);
   EVT SVT = Op.getValueType();
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 7a14d855e275c..e57e8736e869a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -895,10 +895,9 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
     assert(N->getValueType(0).getVectorNumElements() == 1 &&
            "Unexpected vector type!");
     SDValue Elt = GetScalarizedVector(N->getOperand(0));
-    SDValue Op = DAG.getNode(N->getOpcode(), SDLoc(N),
-                             N->getValueType(0).getScalarType(), Elt,
-                             N->getOperand(1), N->getOperand(2),
-                             N->getOperand(3));
+    SDValue Op = DAG.getNode(
+        N->getOpcode(), SDLoc(N), N->getValueType(0).getScalarType(), Elt,
+        N->getOperand(1), N->getOperand(2), N->getOperand(3));
     Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Op);
     break;
   }
@@ -2930,10 +2929,10 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
   const SDNodeFlags Flags = N->getFlags();
   unsigned Opcode = N->getOpcode();
   if (Opcode == ISD::CONVERT_TO_ARBITRARY_FP) {
-    Lo = DAG.getNode(Opcode, dl, LoVT, Lo, N->getOperand(1),
-                     N->getOperand(2), N->getOperand(3), Flags);
-    Hi = DAG.getNode(Opcode, dl, HiVT, Hi, N->getOperand(1),
-                     N->getOperand(2), N->getOperand(3), Flags);
+    Lo = DAG.getNode(Opcode, dl, LoVT, Lo, N->getOperand(1), N->getOperand(2),
+                     N->getOperand(3), Flags);
+    Hi = DAG.getNode(Opcode, dl, HiVT, Hi, N->getOperand(1), N->getOperand(2),
+                     N->getOperand(3), Flags);
     return;
   }
   if (N->getNumOperands() <= 2) {
@@ -5913,8 +5912,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
     if (N->getNumOperands() == 1)
       return DAG.getNode(Opcode, DL, VT, Op, Flags);
     if (Opcode == ISD::CONVERT_TO_ARBITRARY_FP)
-      return DAG.getNode(Opcode, DL, VT, Op, N->getOperand(1),
-                         N->getOperand(2), N->getOperand(3), Flags);
+      return DAG.getNode(Opcode, DL, VT, Op, N->getOperand(1), N->getOperand(2),
+                         N->getOperand(3), Flags);
     return DAG.getNode(Opcode, DL, VT, Op, N->getOperand(1), Flags);
   };
 
@@ -7697,8 +7696,8 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
   // Helper to build a convert node with all scalar trailing operands.
   auto MakeConvertNode = [&](EVT VT, SDValue Op) -> SDValue {
     if (Opcode == ISD::CONVERT_TO_ARBITRARY_FP)
-      return DAG.getNode(Opcode, dl, VT, Op, N->getOperand(1),
-                         N->getOperand(2), N->getOperand(3));
+      return DAG.getNode(Opcode, dl, VT, Op, N->getOperand(1), N->getOperand(2),
+                         N->getOperand(3));
     if (Opcode == ISD::FP_ROUND || Opcode == ISD::CONVERT_FROM_ARBITRARY_FP)
       return DAG.getNode(Opcode, dl, VT, Op, N->getOperand(1));
     return DAG.getNode(Opcode, dl, VT, Op);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index cc15e0c85148d..f9b1ade811585 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7213,8 +7213,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
     Metadata *RoundMD =
         cast<MetadataAsValue>(I.getArgOperand(2))->getMetadata();
     StringRef RoundStr = cast<MDString>(RoundMD)->getString();
-    std::optional<RoundingMode> RoundMode =
-        convertStrToRoundingMode(RoundStr);
+    std::optional<RoundingMode> RoundMode = convertStrToRoundingMode(RoundStr);
     if (!RoundMode || *RoundMode == RoundingMode::Dynamic) {
       DAG.getContext()->emitError(
           "convert_to_arbitrary_fp: unsupported rounding mode '" + RoundStr +
@@ -7233,8 +7232,8 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
     SDValue RoundConst =
         DAG.getTargetConstant(static_cast<int>(*RoundMode), sdl, MVT::i32);
     SDValue SatConst = DAG.getTargetConstant(Saturate, sdl, MVT::i32);
-    setValue(&I, DAG.getNode(ISD::CONVERT_TO_ARBITRARY_FP, sdl, DstVT,
-                             FloatVal, SemConst, RoundConst, SatConst));
+    setValue(&I, DAG.getNode(ISD::CONVERT_TO_ARBITRARY_FP, sdl, DstVT, FloatVal,
+                             SemConst, RoundConst, SatConst));
     return;
   }
   case Intrinsic::set_rounding:

>From 1db39a0b72f180b6a6d0d7d13ba437cb5cf48ecd Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Wed, 22 Apr 2026 23:17:03 +0200
Subject: [PATCH 3/9] add emitError and guard setOperationAction from
 clangformat

---
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 24 ++++++++++++++++---
 llvm/lib/CodeGen/TargetLoweringBase.cpp       |  2 ++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 22de6665cadc5..0d05d20f64151 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3817,6 +3817,24 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     if (!Results.empty())
       break;
 
+    // Supported rounding modes.
+    switch (RoundMode) {
+    case RoundingMode::NearestTiesToEven:
+    case RoundingMode::TowardZero:
+    case RoundingMode::TowardPositive:
+    case RoundingMode::TowardNegative:
+    case RoundingMode::NearestTiesToAway:
+      break;
+    default:
+      DAG.getContext()->emitError(
+          "CONVERT_TO_ARBITRARY_FP: unsupported rounding mode (enum " +
+          Twine(static_cast<int>(RoundMode)) + ")");
+      Results.push_back(DAG.getPOISON(ResVT));
+      break;
+    }
+    if (!Results.empty())
+      break;
+
     // Destination format parameters.
     const fltSemantics &DstSem = APFloatBase::EnumToSemantics(Sem);
     const unsigned DstBits = APFloat::getSizeInBits(DstSem);
@@ -3971,9 +3989,9 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
             DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsNegative);
         return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
       }
-      if (RoundMode == RoundingMode::NearestTiesToAway)
-        return RoundBit;
-      llvm_unreachable("Unsupported rounding mode");
+      assert(RoundMode == RoundingMode::NearestTiesToAway &&
+             "Unsupported rounding mode; should have been rejected above");
+      return RoundBit;
     };
 
     // Round mantissa from SrcMant bits to DstMant bits.
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index fbc821a42d899..d589c9615e4c3 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1120,6 +1120,7 @@ void TargetLoweringBase::initActions() {
     // Most backends expect to see the node which just returns the value loaded.
     setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Expand);
 
+    // clang-format off
     // These operations default to expand.
     setOperationAction({ISD::FGETSIGN,       ISD::CONCAT_VECTORS,
                         ISD::FMINNUM,        ISD::FMAXNUM,
@@ -1152,6 +1153,7 @@ void TargetLoweringBase::initActions() {
                         ISD::FMULADD,        ISD::CONVERT_FROM_ARBITRARY_FP,
                         ISD::CONVERT_TO_ARBITRARY_FP},
                        VT, Expand);
+    // clang-format on
 
     // Overflow operations default to expand
     setOperationAction({ISD::SADDO, ISD::SSUBO, ISD::UADDO, ISD::USUBO,

>From 175d7e83b1ce2a878671fc6ef2562025a0273f2a Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Thu, 23 Apr 2026 08:30:35 -0500
Subject: [PATCH 4/9] add assertions

---
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp        | 12 +++++++-----
 .../lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp |  9 ++-------
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 0d05d20f64151..1dec23430b6af 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3555,6 +3555,8 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     // Float8E3M4, Float8E5M2FNUZ, Float8E4M3FNUZ, Float8E4M3B11FNUZ,
     // Float8E8M0FNU.
     EVT DstVT = Node->getValueType(0);
+    assert(!DstVT.isVector() &&
+           "Vector apfloat conversions are handled in LegalizeVectorOps");
 
     SDValue IntVal = Node->getOperand(0);
     const uint64_t SemEnum = Node->getConstantOperandVal(1);
@@ -3791,6 +3793,8 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     // Float8E3M4, Float8E5M2FNUZ, Float8E4M3FNUZ, Float8E4M3B11FNUZ,
     // Float8E8M0FNU.
     EVT ResVT = Node->getValueType(0);
+    assert(!ResVT.isVector() &&
+           "Vector apfloat conversions are handled in LegalizeVectorOps");
 
     SDValue FloatVal = Node->getOperand(0);
     const uint64_t SemEnum = Node->getConstantOperandVal(1);
@@ -3848,11 +3852,9 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     const fltNanEncoding DstNanEnc = DstSem.nanEncoding;
 
     // Compute the maximum normal exponent for the destination format.
-    unsigned DstExpMaxNormal;
-    if (DstNFBehavior == fltNonfiniteBehavior::IEEE754)
-      DstExpMaxNormal = DstExpMax - 1;
-    else
-      DstExpMaxNormal = DstExpMax;
+    const unsigned DstExpMaxNormal =
+        DstNFBehavior == fltNonfiniteBehavior::IEEE754 ? DstExpMax - 1
+                                                       : DstExpMax;
 
     // For NanOnly formats the max exponent field for finite values
     // is DstExpMax, but the encoding with exp = DstExpMax and
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index f9b1ade811585..96386b9ac5343 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7214,13 +7214,8 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
         cast<MetadataAsValue>(I.getArgOperand(2))->getMetadata();
     StringRef RoundStr = cast<MDString>(RoundMD)->getString();
     std::optional<RoundingMode> RoundMode = convertStrToRoundingMode(RoundStr);
-    if (!RoundMode || *RoundMode == RoundingMode::Dynamic) {
-      DAG.getContext()->emitError(
-          "convert_to_arbitrary_fp: unsupported rounding mode '" + RoundStr +
-          "'");
-      setValue(&I, DAG.getPOISON(DstVT));
-      return;
-    }
+    assert(RoundMode && *RoundMode != RoundingMode::Dynamic &&
+           "Dynamic rounding mode should have been rejected by the verifier");
 
     uint64_t Saturate =
         cast<ConstantInt>(I.getArgOperand(3))->getZExtValue() ? 1 : 0;

>From 8409fcf7ef2ef298655b653fbd28200f0cbb72d3 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Mon, 4 May 2026 00:24:54 +0200
Subject: [PATCH 5/9] Remake lowering using frexp and is_fpclass

---
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp |   95 +-
 .../CodeGen/AMDGPU/float-to-arbitrary-fp.ll   | 1268 +++++-------
 .../CodeGen/NVPTX/float-to-arbitrary-fp.ll    | 1564 ++++++---------
 .../X86/float-to-arbitrary-fp-error.ll        |    1 +
 .../test/CodeGen/X86/float-to-arbitrary-fp.ll | 1715 ++++++-----------
 5 files changed, 1752 insertions(+), 2891 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 1dec23430b6af..5c6e10f4d3e8e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3866,16 +3866,15 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
         DstNanEnc == fltNanEncoding::AllOnes)
       DstMaxMantAtMaxExp = DstMantMask - 1;
 
+    // FIXME: ConstantFP inputs may not fully fold through this expansion.
+
     // Source format parameters.
     EVT SrcVT = FloatVal.getValueType();
     const fltSemantics &SrcSem = SrcVT.getFltSemantics();
     const unsigned SrcBits = APFloat::getSizeInBits(SrcSem);
     const unsigned SrcPrecision = APFloat::semanticsPrecision(SrcSem);
     const unsigned SrcMant = SrcPrecision - 1;
-    const unsigned SrcExpBits = SrcBits - SrcMant - 1;
-    const int SrcBias = 1 - APFloat::semanticsMinExponent(SrcSem);
     const uint64_t SrcMantMask = (1ULL << SrcMant) - 1;
-    const uint64_t SrcExpMask = (1ULL << SrcExpBits) - 1;
 
     // Work in the source integer type.
     EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), SrcBits);
@@ -3884,77 +3883,37 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     SDValue Zero = DAG.getConstant(0, dl, IntVT);
     SDValue One = DAG.getConstant(1, dl, IntVT);
 
-    // Bitcast source float to integer and extract bit fields.
+    // Bitcast source float to integer to extract the sign bit.
     SDValue Src = DAG.getNode(ISD::BITCAST, dl, IntVT, FloatVal);
-    SDValue SrcMantField = DAG.getNode(ISD::AND, dl, IntVT, Src,
-                                       DAG.getConstant(SrcMantMask, dl, IntVT));
-
-    SDValue SrcExpField =
-        DAG.getNode(ISD::AND, dl, IntVT,
-                    DAG.getNode(ISD::SRL, dl, IntVT, Src,
-                                DAG.getShiftAmountConstant(SrcMant, IntVT, dl)),
-                    DAG.getConstant(SrcExpMask, dl, IntVT));
-
     SDValue SignBit =
         DAG.getNode(ISD::SRL, dl, IntVT, Src,
                     DAG.getShiftAmountConstant(SrcBits - 1, IntVT, dl));
 
-    // Classify the input value.
-    SDValue SrcExpAllOnes = DAG.getConstant(SrcExpMask, dl, IntVT);
-    SDValue IsExpAllOnes =
-        DAG.getSetCC(dl, SetCCVT, SrcExpField, SrcExpAllOnes, ISD::SETEQ);
-    SDValue IsExpZero =
-        DAG.getSetCC(dl, SetCCVT, SrcExpField, Zero, ISD::SETEQ);
-    SDValue IsMantZero =
-        DAG.getSetCC(dl, SetCCVT, SrcMantField, Zero, ISD::SETEQ);
-    SDValue IsMantNonZero =
-        DAG.getSetCC(dl, SetCCVT, SrcMantField, Zero, ISD::SETNE);
-
-    // If source is IEEE fp, tehn NaN = exp_all_ones && mant != 0.
-    SDValue IsNaN =
-        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpAllOnes, IsMantNonZero);
-    // Inf = exp_all_ones && mant == 0.
-    SDValue IsInf =
-        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpAllOnes, IsMantZero);
-    // Zero = exp == 0 && mant == 0.
-    SDValue IsZero = DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantZero);
-    // Source denorm = exp == 0 && mant != 0.
-    SDValue IsSrcDenorm =
-        DAG.getNode(ISD::AND, dl, SetCCVT, IsExpZero, IsMantNonZero);
-
-    // Source denormal normalization.
-    // For a source denormal, the true exponent is (1 - SrcBias) and the
-    // mantissa has no implicit leading 1. Normalize by finding the position
-    // of the leading 1 in the mantissa.
-    SDValue LeadingZeros =
-        DAG.getNode(ISD::CTLZ_ZERO_UNDEF, dl, IntVT, SrcMantField);
-
-    // normShift = LeadingZeros - (SrcBits - 1 - SrcMant).
-    const unsigned LZOffset = SrcBits - 1 - SrcMant;
-    SDValue NormShift = DAG.getNode(ISD::SUB, dl, IntVT, LeadingZeros,
-                                    DAG.getConstant(LZOffset, dl, IntVT));
-
-    // Normalized mantissa.
-    SDValue NormMant =
-        DAG.getNode(ISD::AND, dl, IntVT,
-                    DAG.getNode(ISD::SHL, dl, IntVT, SrcMantField, NormShift),
-                    DAG.getConstant(SrcMantMask, dl, IntVT));
-
-    // effective_exp = 1 - NormShift.
-    SDValue DenormSrcExp = DAG.getNode(ISD::SUB, dl, IntVT, One, NormShift);
-
-    // Select between normal and denorm source.
-    SDValue EffSrcExp =
-        DAG.getSelect(dl, IntVT, IsSrcDenorm, DenormSrcExp, SrcExpField);
-    SDValue EffSrcMant =
-        DAG.getSelect(dl, IntVT, IsSrcDenorm, NormMant, SrcMantField);
-
-    // Compute new biased exponent for destination.
-    // new_exp = src_exp - SrcBias + DstBias
-    const int BiasAdjust = DstBias - SrcBias;
+    // Classify the input.
+    SDValue IsNaN = DAG.getNode(ISD::IS_FPCLASS, dl, SetCCVT, FloatVal,
+                                DAG.getTargetConstant(fcNan, dl, MVT::i32));
+    SDValue IsInf = DAG.getNode(ISD::IS_FPCLASS, dl, SetCCVT, FloatVal,
+                                DAG.getTargetConstant(fcInf, dl, MVT::i32));
+    SDValue IsZero = DAG.getNode(ISD::IS_FPCLASS, dl, SetCCVT, FloatVal,
+                                 DAG.getTargetConstant(fcZero, dl, MVT::i32));
+
+    // Split into a normalized fraction and unbiased exponent. FFREXP normalizes
+    // source denormals automatically. The result is unspecified for Inf/NaN,
+    // but those inputs are detected above and override the final result.
+    EVT FrexpExpVT = MVT::i32;
+    SDValue Frexp = DAG.getNode(ISD::FFREXP, dl,
+                                DAG.getVTList(SrcVT, FrexpExpVT), FloatVal);
+    SDValue FrexpFrac = Frexp.getValue(0);
+    SDValue FrexpExp = Frexp.getValue(1);
+
+    SDValue FrexpFracInt = DAG.getNode(ISD::BITCAST, dl, IntVT, FrexpFrac);
+    SDValue EffSrcMant = DAG.getNode(ISD::AND, dl, IntVT, FrexpFracInt,
+                                     DAG.getConstant(SrcMantMask, dl, IntVT));
+
+    SDValue FrexpExpExt = DAG.getSExtOrTrunc(FrexpExp, dl, IntVT);
     SDValue NewExp = DAG.getNode(
-        ISD::ADD, dl, IntVT, EffSrcExp,
-        DAG.getConstant(APInt(SrcBits, BiasAdjust, true), dl, IntVT));
+        ISD::ADD, dl, IntVT, FrexpExpExt,
+        DAG.getConstant(APInt(SrcBits, DstBias - 1, true), dl, IntVT));
 
     // Compute rounding increment given the round bit, sticky bits, and LSB
     // of the truncated mantissa.
diff --git a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
index 45639b9d50ca9..630365dfcab62 100644
--- a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
@@ -16,408 +16,114 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
 ; Layout: sign(1) exp(5) mant(2), bias=15
 ; Supports: Inf, NaN, signed zero, denormals
 
-; Float8E5M2 normal: f32 1.0 -> 0_01111_00 = 0x3C
-define i8 @to_f8e5m2_normal() {
-; CHECK-LABEL: to_f8e5m2_normal:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 60
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 zero: f32 0.0 -> 0_00000_00 = 0x00
-define i8 @to_f8e5m2_zero() {
-; CHECK-LABEL: to_f8e5m2_zero:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 negative zero: f32 -0.0 -> 1_00000_00 = 0x80
-define i8 @to_f8e5m2_neg_zero() {
-; CHECK-LABEL: to_f8e5m2_neg_zero:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x80
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float -0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 +Inf: f32 Inf -> 0_11111_00 = 0x7C
-define i8 @to_f8e5m2_inf() {
-; CHECK-LABEL: to_f8e5m2_inf:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7c
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 NaN: f32 NaN -> qNaN
-define i8 @to_f8e5m2_nan() {
-; CHECK-LABEL: to_f8e5m2_nan:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7e
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 max: 57344.0 -> 0_11110_11 = 0x7B
-define i8 @to_f8e5m2_max() {
-; CHECK-LABEL: to_f8e5m2_max:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7b
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 57344.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 overflow (no saturation): 100000.0 -> Inf = 0x7C
-define i8 @to_f8e5m2_overflow() {
-; CHECK-LABEL: to_f8e5m2_overflow:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7c
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 overflow with saturation: 100000.0 -> max = 0x7B
-define i8 @to_f8e5m2_overflow_sat() {
-; CHECK-LABEL: to_f8e5m2_overflow_sat:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7b
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 true)
-  ret i8 %r
-}
-
-; Float8E5M2 denorm: very small value -> dst denorm
-define i8 @to_f8e5m2_denorm() {
-  ; 2^(-16) = 0x37800000 -> smallest E5M2 denorm 0_00000_01 = 0x01
-; CHECK-LABEL: to_f8e5m2_denorm:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 1
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x3EF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
 ; Float8E5M2 runtime arg test
 define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-LABEL: to_f8e5m2_dynamic:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffff, v0
-; CHECK-NEXT:    v_ffbh_u32_e32 v3, v1
-; CHECK-NEXT:    v_bfe_u32 v2, v0, 23, 8
-; CHECK-NEXT:    v_add_u32_e32 v4, -8, v3
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v1
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v2
-; CHECK-NEXT:    v_lshlrev_b32_e32 v4, v4, v1
-; CHECK-NEXT:    v_and_b32_e32 v4, 0x7fffff, v4
-; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
-; CHECK-NEXT:    v_and_b32_e32 v6, 0xfffff, v4
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[6:7], 0, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v5, 21, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
-; CHECK-NEXT:    v_and_or_b32 v6, v5, 1, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v7, 20, v4
-; CHECK-NEXT:    v_and_b32_e32 v6, v7, v6
-; CHECK-NEXT:    v_add_u32_e32 v5, v5, v6
-; CHECK-NEXT:    v_sub_u32_e32 v3, 9, v3
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[6:7], 3, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v6, 0xffffff90
-; CHECK-NEXT:    v_addc_co_u32_e64 v6, s[4:5], v3, v6, s[6:7]
-; CHECK-NEXT:    v_sub_u32_e32 v3, 0x86, v3
-; CHECK-NEXT:    v_min_u32_e32 v3, 31, v3
-; CHECK-NEXT:    v_or_b32_e32 v4, 0x800000, v4
-; CHECK-NEXT:    v_sub_u32_e64 v9, v3, 1 clamp
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v3, v0
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v1, v0
+; CHECK-NEXT:    v_sub_u32_e32 v4, 8, v3
+; CHECK-NEXT:    v_and_b32_e32 v2, 0x7fffff, v1
+; CHECK-NEXT:    v_min_u32_e32 v4, 31, v4
+; CHECK-NEXT:    v_or_b32_e32 v2, 0x800000, v2
+; CHECK-NEXT:    v_sub_u32_e64 v6, v4, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v7, v2, 0, v6
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v4, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v7, v5, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v2, v6, v2
+; CHECK-NEXT:    v_and_b32_e32 v2, v2, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v4
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc
+; CHECK-NEXT:    v_add_u32_e32 v2, v5, v2
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v2
 ; CHECK-NEXT:    s_movk_i32 s4, 0x80
-; CHECK-NEXT:    v_bfe_u32 v10, v4, 0, v9
-; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v3, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
-; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v4, v9, v4
-; CHECK-NEXT:    v_and_b32_e32 v4, v4, v10
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, v4, s[4:5]
-; CHECK-NEXT:    v_add_u32_e32 v3, v8, v3
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[6:7]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 2, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, s[4:5]
-; CHECK-NEXT:    v_or3_b32 v7, v0, v7, v5
-; CHECK-NEXT:    v_or3_b32 v3, v0, v4, v3
-; CHECK-NEXT:    v_cmp_gt_i32_e64 s[4:5], 1, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v7, v3, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v5
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], 30, v6
-; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 30, v6
-; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v0
-; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, v4, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
-; CHECK-NEXT:    s_movk_i32 s6, 0xff
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v1
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], s6, v2
-; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
-; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v5, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v2, v5, v4, v2
+; CHECK-NEXT:    v_and_b32_e32 v4, 0xfffff, v1
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v6, v1, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v4, v6, 1, v4
+; CHECK-NEXT:    v_lshrrev_b32_e32 v1, 20, v1
+; CHECK-NEXT:    v_and_b32_e32 v1, v1, v4
+; CHECK-NEXT:    v_add_u32_e32 v1, v6, v1
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v1, v1, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v3, vcc, 14, v3, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v4, 2, v3
+; CHECK-NEXT:    v_or3_b32 v4, v5, v4, v1
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v4, v2, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v1
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v3
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v3
+; CHECK-NEXT:    v_or_b32_e32 v1, 0x7c, v5
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x60
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v1, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v3
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x204
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v5, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, 3
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
 }
 
-; Float8E4M3FN (NanOnly, NanEncoding=AllOnes)
-; Layout: sign(1) exp(4) mant(3), maxExp=8, minExp=-6, bias=7
-; Only 0_1111_111 and 1_1111_111 are NaN; all other exp=15 values are finite.
-
-; Float8E4M3FN normal: f32 1.0 -> 0_0111_000 = 0x38
-define i8 @to_f8e4m3fn_normal() {
-; CHECK-LABEL: to_f8e4m3fn_normal:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 56
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN max: 448.0 -> 0_1111_110 = 0x7E
-define i8 @to_f8e4m3fn_max() {
-; CHECK-LABEL: to_f8e4m3fn_max:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7e
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 448.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN NaN: f32 NaN -> 0_1111_111 = 0x7F
-define i8 @to_f8e4m3fn_nan() {
-; CHECK-LABEL: to_f8e4m3fn_nan:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7f
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN overflow with saturation: 1000.0 -> max = 0x7E
-define i8 @to_f8e4m3fn_overflow_sat() {
-; CHECK-LABEL: to_f8e4m3fn_overflow_sat:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0x7e
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1000.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 true)
-  ret i8 %r
-}
-
-; Float6E3M2FN (FiniteOnly)
-; Layout: sign(1) exp(3) mant(2), bias=3, maxExp=4
-; No Inf, no NaN. All bit patterns are finite.
-
-; Float6E3M2FN normal: f32 1.0 -> 0_011_00 = 0x0C
-define i6 @to_f6e3m2fn_normal() {
-; CHECK-LABEL: to_f6e3m2fn_normal:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 12
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN max: 28.0 -> 0_111_11 = 0x1F
-define i6 @to_f6e3m2fn_max() {
-; CHECK-LABEL: to_f6e3m2fn_max:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 31
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 28.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN zero: f32 0.0 -> 0_000_00 = 0x00
-define i6 @to_f6e3m2fn_zero() {
-; CHECK-LABEL: to_f6e3m2fn_zero:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 0
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 0.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN negative: f32 -1.0 -> 1_011_00
-define i6 @to_f6e3m2fn_negative() {
-; CHECK-LABEL: to_f6e3m2fn_negative:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 44
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float -1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E2M3FN (FiniteOnly)
-; Layout: sign(1) exp(2) mant(3), bias=1, maxExp=2
-; No Inf, no NaN. All bit patterns are finite.
-
-; Float6E2M3FN normal: f32 1.0 -> 0_01_000 = 0x08
-define i6 @to_f6e2m3fn_normal() {
-; CHECK-LABEL: to_f6e2m3fn_normal:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 8
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E2M3FN max: 7.5 -> 0_11_111 = 0x1F
-define i6 @to_f6e2m3fn_max() {
-; CHECK-LABEL: to_f6e2m3fn_max:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 31
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 7.5, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float4E2M1FN (FiniteOnly)
-; Layout: sign(1) exp(2) mant(1), bias=1, maxExp=2
-; No Inf, no NaN.
-
-; Float4E2M1FN normal: f32 1.0 -> 0_01_0 = 0x2
-define i4 @to_f4e2m1fn_normal() {
-; CHECK-LABEL: to_f4e2m1fn_normal:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 2
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 1.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
-; Float4E2M1FN max: 6.0 -> 0_11_1 = 0x7
-define i4 @to_f4e2m1fn_max() {
-; CHECK-LABEL: to_f4e2m1fn_max:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 7
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 6.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
-; Float4E2M1FN denorm: 0.5 -> 0_00_1 = 0x1
-define i4 @to_f4e2m1fn_denorm() {
-; CHECK-LABEL: to_f4e2m1fn_denorm:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 1
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 0.5, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
 ; Rounding mode tests
 
-; Round to nearest
-define i8 @to_f8e5m2_round_nearest() {
-; CHECK-LABEL: to_f8e5m2_round_nearest:
-; CHECK:       ; %bb.0:
-; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v0, 62
-; CHECK-NEXT:    s_setpc_b64 s[30:31]
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.5, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
 ; Round toward zero with runtime arg
 define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-LABEL: to_f8e5m2_round_towardzero:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffff, v0
-; CHECK-NEXT:    v_bfe_u32 v2, v0, 23, 8
-; CHECK-NEXT:    v_ffbh_u32_e32 v3, v1
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v1
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v2
-; CHECK-NEXT:    v_add_u32_e32 v4, -8, v3
-; CHECK-NEXT:    v_lshlrev_b32_e32 v4, v4, v1
-; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
-; CHECK-NEXT:    v_sub_u32_e32 v3, 9, v3
-; CHECK-NEXT:    v_and_b32_e32 v4, 0x7fffff, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
-; CHECK-NEXT:    v_sub_u32_e32 v6, 0x86, v3
-; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v4
-; CHECK-NEXT:    v_min_u32_e32 v6, 31, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 4, s[4:5]
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v1, v0
+; CHECK-NEXT:    v_bfe_u32 v2, v1, 21, 2
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v2
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v4, v0
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v5, vcc, 14, v4, vcc
+; CHECK-NEXT:    v_and_b32_e32 v1, 0x7fffff, v1
+; CHECK-NEXT:    v_sub_u32_e32 v4, 8, v4
+; CHECK-NEXT:    v_or_b32_e32 v1, 0x800000, v1
+; CHECK-NEXT:    v_min_u32_e32 v4, 31, v4
+; CHECK-NEXT:    v_lshrrev_b32_e32 v1, v4, v1
 ; CHECK-NEXT:    s_movk_i32 s4, 0x80
-; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
-; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 21, v4
-; CHECK-NEXT:    v_or3_b32 v5, v0, v6, v5
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v4
-; CHECK-NEXT:    v_mov_b32_e32 v6, 0xffffff90
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, s[4:5]
-; CHECK-NEXT:    v_addc_co_u32_e64 v3, s[4:5], v3, v6, s[4:5]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v6, 2, v3
-; CHECK-NEXT:    v_or3_b32 v6, v0, v6, v4
-; CHECK-NEXT:    v_cmp_gt_i32_e64 s[4:5], 1, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v6, v5, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 3, v4
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], 30, v3
-; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 30, v3
-; CHECK-NEXT:    v_or_b32_e32 v3, 0x7c, v0
-; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, v5, v3, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v5
-; CHECK-NEXT:    s_movk_i32 s6, 0xff
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v4, v0, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v1
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[6:7], s6, v2
-; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v3, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
-; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v1
+; CHECK-NEXT:    v_and_b32_sdwa v3, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_lshlrev_b32_e32 v6, 2, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v1, v1, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, vcc
+; CHECK-NEXT:    v_or3_b32 v6, v3, v6, v2
+; CHECK-NEXT:    v_or3_b32 v1, v3, v4, v1
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v6, v1, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v2
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v5
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v5
+; CHECK-NEXT:    v_or_b32_e32 v2, 0x7c, v3
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0x60
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v4
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v3, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x204
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, 3
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
   ret i8 %r
@@ -428,207 +134,167 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-LABEL: to_f4e2m1fn_v4f32:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v0
-; CHECK-NEXT:    v_ffbh_u32_e32 v4, v5
-; CHECK-NEXT:    v_bfe_u32 v6, v0, 23, 8
-; CHECK-NEXT:    v_add_u32_e32 v7, -8, v4
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
-; CHECK-NEXT:    v_lshlrev_b32_e32 v7, v7, v5
-; CHECK-NEXT:    v_and_b32_e32 v7, 0x7fffff, v7
-; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v5, v7, vcc
-; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v7
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 22, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v9, v9, v8
-; CHECK-NEXT:    v_lshrrev_b32_e32 v10, 21, v7
-; CHECK-NEXT:    v_and_b32_e32 v9, v10, v9
-; CHECK-NEXT:    v_add_u32_e32 v8, v8, v9
-; CHECK-NEXT:    v_sub_u32_e32 v4, 9, v4
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v8
-; CHECK-NEXT:    v_cndmask_b32_e32 v9, v6, v4, vcc
-; CHECK-NEXT:    v_mov_b32_e32 v4, 0xffffff82
-; CHECK-NEXT:    v_addc_co_u32_e64 v10, vcc, v9, v4, s[4:5]
-; CHECK-NEXT:    v_sub_u32_e32 v9, 0x95, v9
-; CHECK-NEXT:    v_min_u32_e32 v9, 31, v9
-; CHECK-NEXT:    v_or_b32_e32 v7, 0x800000, v7
-; CHECK-NEXT:    v_sub_u32_e64 v12, v9, 1 clamp
-; CHECK-NEXT:    v_lshrrev_b32_e32 v0, 28, v0
-; CHECK-NEXT:    v_bfe_u32 v13, v7, 0, v12
-; CHECK-NEXT:    v_cndmask_b32_e64 v8, v8, 0, s[4:5]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v11, 1, v10
-; CHECK-NEXT:    v_and_b32_e32 v0, 8, v0
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v13
-; CHECK-NEXT:    v_or3_b32 v8, v0, v11, v8
-; CHECK-NEXT:    v_lshrrev_b32_e32 v11, v9, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v13, v11, 1, v13
-; CHECK-NEXT:    v_lshrrev_b32_e32 v7, v12, v7
-; CHECK-NEXT:    v_and_b32_e32 v7, v7, v13
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v7, vcc
-; CHECK-NEXT:    v_add_u32_e32 v7, v11, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 2, vcc
-; CHECK-NEXT:    v_or3_b32 v7, v0, v9, v7
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v10
-; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v8, v7, vcc
-; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v1
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v7, v0, vcc
-; CHECK-NEXT:    v_ffbh_u32_e32 v7, v5
-; CHECK-NEXT:    v_bfe_u32 v6, v1, 23, 8
-; CHECK-NEXT:    v_add_u32_e32 v8, -8, v7
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
-; CHECK-NEXT:    v_lshlrev_b32_e32 v8, v8, v5
-; CHECK-NEXT:    v_and_b32_e32 v8, 0x7fffff, v8
-; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v8, v5, v8, vcc
-; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v8
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 22, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v10, v10, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v11, 21, v8
-; CHECK-NEXT:    v_and_b32_e32 v10, v11, v10
-; CHECK-NEXT:    v_add_u32_e32 v9, v9, v10
-; CHECK-NEXT:    v_sub_u32_e32 v7, 9, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v9
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v6, v7, vcc
-; CHECK-NEXT:    v_addc_co_u32_e64 v10, vcc, v7, v4, s[4:5]
-; CHECK-NEXT:    v_sub_u32_e32 v7, 0x95, v7
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v0
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v0
+; CHECK-NEXT:    v_sub_u32_e32 v7, 23, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
 ; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
-; CHECK-NEXT:    v_or_b32_e32 v8, 0x800000, v8
-; CHECK-NEXT:    v_sub_u32_e64 v12, v7, 1 clamp
-; CHECK-NEXT:    v_lshrrev_b32_e32 v1, 28, v1
-; CHECK-NEXT:    v_bfe_u32 v13, v8, 0, v12
-; CHECK-NEXT:    v_cndmask_b32_e64 v9, v9, 0, s[4:5]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v11, 1, v10
-; CHECK-NEXT:    v_and_b32_e32 v1, 8, v1
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v13
-; CHECK-NEXT:    v_or3_b32 v9, v1, v11, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v11, v7, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v13, v11, 1, v13
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v12, v8
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v13
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
 ; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v8, vcc
-; CHECK-NEXT:    v_add_u32_e32 v7, v11, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 28, v0
+; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 2, vcc
+; CHECK-NEXT:    v_and_b32_e32 v8, 8, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
+; CHECK-NEXT:    v_or_b32_e32 v9, v9, v4
+; CHECK-NEXT:    v_and_b32_e32 v7, v7, v9
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v7
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 0, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v5, 0x60
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v5
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v4, v8, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v1
+; CHECK-NEXT:    v_sub_u32_e32 v8, 23, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 28, v1
+; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
 ; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
-; CHECK-NEXT:    v_or3_b32 v7, v1, v8, v7
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v10
-; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v9, v7, vcc
-; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v2
-; CHECK-NEXT:    v_cndmask_b32_e32 v1, v7, v1, vcc
-; CHECK-NEXT:    v_ffbh_u32_e32 v7, v5
-; CHECK-NEXT:    v_bfe_u32 v6, v2, 23, 8
-; CHECK-NEXT:    v_add_u32_e32 v8, -8, v7
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
-; CHECK-NEXT:    v_lshlrev_b32_e32 v8, v8, v5
-; CHECK-NEXT:    v_and_b32_e32 v8, 0x7fffff, v8
-; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v8, v5, v8, vcc
-; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v8
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 22, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v10, v10, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v11, 21, v8
-; CHECK-NEXT:    v_and_b32_e32 v10, v11, v10
-; CHECK-NEXT:    v_add_u32_e32 v9, v9, v10
-; CHECK-NEXT:    v_sub_u32_e32 v7, 9, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v9
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v6, v7, vcc
-; CHECK-NEXT:    v_addc_co_u32_e64 v10, vcc, v7, v4, s[4:5]
-; CHECK-NEXT:    v_sub_u32_e32 v7, 0x95, v7
-; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
-; CHECK-NEXT:    v_or_b32_e32 v8, 0x800000, v8
-; CHECK-NEXT:    v_sub_u32_e64 v12, v7, 1 clamp
-; CHECK-NEXT:    v_lshrrev_b32_e32 v2, 28, v2
-; CHECK-NEXT:    v_bfe_u32 v13, v8, 0, v12
-; CHECK-NEXT:    v_cndmask_b32_e64 v9, v9, 0, s[4:5]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v11, 1, v10
-; CHECK-NEXT:    v_and_b32_e32 v2, 8, v2
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v13
-; CHECK-NEXT:    v_or3_b32 v9, v2, v11, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v11, v7, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v13, v11, 1, v13
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v12, v8
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v13
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v8, vcc
-; CHECK-NEXT:    v_add_u32_e32 v7, v11, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_and_b32_e32 v9, 8, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
+; CHECK-NEXT:    v_or_b32_e32 v10, v10, v4
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v10
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v8
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 0, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 1, v7
+; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v1, v5
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v4, v9, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v2
+; CHECK-NEXT:    v_sub_u32_e32 v8, 23, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 28, v2
+; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
 ; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
-; CHECK-NEXT:    v_or3_b32 v7, v2, v8, v7
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v10
-; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v9, v7, vcc
-; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v3
-; CHECK-NEXT:    v_cndmask_b32_e32 v2, v7, v2, vcc
-; CHECK-NEXT:    v_ffbh_u32_e32 v7, v5
-; CHECK-NEXT:    v_bfe_u32 v6, v3, 23, 8
-; CHECK-NEXT:    v_add_u32_e32 v8, -8, v7
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v6
-; CHECK-NEXT:    v_lshlrev_b32_e32 v8, v8, v5
-; CHECK-NEXT:    v_and_b32_e32 v8, 0x7fffff, v8
-; CHECK-NEXT:    s_and_b64 vcc, s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v8, v5, v8, vcc
-; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v8
-; CHECK-NEXT:    v_cmp_ne_u32_e64 s[4:5], 0, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 22, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v10, v10, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v11, 21, v8
-; CHECK-NEXT:    v_and_b32_e32 v10, v11, v10
-; CHECK-NEXT:    v_add_u32_e32 v9, v9, v10
-; CHECK-NEXT:    v_sub_u32_e32 v7, 9, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e64 s[4:5], 1, v9
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, v6, v7, vcc
-; CHECK-NEXT:    v_addc_co_u32_e64 v4, vcc, v7, v4, s[4:5]
-; CHECK-NEXT:    v_sub_u32_e32 v7, 0x95, v7
-; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
-; CHECK-NEXT:    v_or_b32_e32 v8, 0x800000, v8
-; CHECK-NEXT:    v_sub_u32_e64 v11, v7, 1 clamp
-; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 28, v3
-; CHECK-NEXT:    v_bfe_u32 v12, v8, 0, v11
-; CHECK-NEXT:    v_cndmask_b32_e64 v9, v9, 0, s[4:5]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v10, 1, v4
-; CHECK-NEXT:    v_and_b32_e32 v3, 8, v3
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v12
-; CHECK-NEXT:    v_or3_b32 v9, v3, v10, v9
-; CHECK-NEXT:    v_lshrrev_b32_e32 v10, v7, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v12, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v12, v10, 1, v12
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v11, v8
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v12
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
-; CHECK-NEXT:    v_cndmask_b32_e32 v7, 0, v8, vcc
-; CHECK-NEXT:    v_add_u32_e32 v7, v10, v7
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, v7, 0, vcc
+; CHECK-NEXT:    v_and_b32_e32 v9, 8, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
+; CHECK-NEXT:    v_or_b32_e32 v10, v10, v4
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v10
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v8
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 0, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 1, v7
+; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v2, v5
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v4, v9, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v3
+; CHECK-NEXT:    v_sub_u32_e32 v8, 23, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 28, v3
+; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
 ; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
-; CHECK-NEXT:    v_or3_b32 v7, v3, v8, v7
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v4
-; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_cndmask_b32_e32 v4, v9, v7, vcc
-; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v5
-; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v3, vcc
+; CHECK-NEXT:    v_and_b32_e32 v9, 8, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
+; CHECK-NEXT:    v_or_b32_e32 v10, v10, v4
+; CHECK-NEXT:    v_and_b32_e32 v8, v8, v10
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v8
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 0, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 1, v7
+; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v3, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v9, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
   ret <4 x i4> %r
@@ -639,78 +305,68 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f16:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_and_b32_e32 v1, 0x3ff, v0
-; CHECK-NEXT:    v_lshlrev_b32_e32 v3, 16, v1
-; CHECK-NEXT:    v_ffbh_u32_e32 v3, v3
-; CHECK-NEXT:    v_bfe_u32 v2, v0, 10, 5
-; CHECK-NEXT:    v_add_u16_e32 v4, -5, v3
-; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v1
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v2
-; CHECK-NEXT:    v_lshlrev_b16_e32 v4, v4, v1
-; CHECK-NEXT:    v_and_b32_e32 v4, 0x3ff, v4
-; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
-; CHECK-NEXT:    v_and_b32_e32 v6, 0x7f, v4
-; CHECK-NEXT:    v_mov_b32_e32 v5, 1
-; CHECK-NEXT:    v_cmp_ne_u16_e64 s[6:7], 0, v6
-; CHECK-NEXT:    v_and_b32_sdwa v5, v4, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_lshrrev_b16_e32 v6, 7, v4
-; CHECK-NEXT:    v_and_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_add_u16_sdwa v5, v4, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[6:7], 3, v5
-; CHECK-NEXT:    v_sub_u16_e32 v3, 6, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
-; CHECK-NEXT:    v_add_u16_e32 v6, v3, v6
-; CHECK-NEXT:    v_sub_u16_e32 v3, 9, v3
-; CHECK-NEXT:    v_min_u16_e32 v3, 15, v3
-; CHECK-NEXT:    v_sub_u16_e64 v10, v3, 1 clamp
-; CHECK-NEXT:    v_lshlrev_b16_e64 v11, v10, 1
-; CHECK-NEXT:    v_or_b32_e32 v4, 0x400, v4
-; CHECK-NEXT:    v_add_u16_e32 v11, -1, v11
+; CHECK-NEXT:    v_frexp_exp_i16_f16_e32 v4, v0
+; CHECK-NEXT:    v_sub_u16_e32 v5, -5, v4
+; CHECK-NEXT:    v_min_u16_e32 v5, 15, v5
+; CHECK-NEXT:    v_frexp_mant_f16_e32 v1, v0
+; CHECK-NEXT:    v_sub_u16_e64 v8, v5, 1 clamp
+; CHECK-NEXT:    v_and_b32_e32 v2, 0x3ff, v1
+; CHECK-NEXT:    v_lshlrev_b16_e64 v9, v8, 1
+; CHECK-NEXT:    v_or_b32_e32 v3, 0x400, v2
+; CHECK-NEXT:    v_add_u16_e32 v9, -1, v9
+; CHECK-NEXT:    v_and_b32_e32 v9, v3, v9
+; CHECK-NEXT:    v_lshrrev_b16_e32 v6, v5, v3
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v9
+; CHECK-NEXT:    v_and_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v7, v9, v7
+; CHECK-NEXT:    v_lshrrev_b16_e32 v3, v8, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v7
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; CHECK-NEXT:    v_add_u16_e32 v3, v6, v3
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v3
 ; CHECK-NEXT:    s_movk_i32 s4, 0x80
-; CHECK-NEXT:    v_and_b32_e32 v11, v4, v11
-; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
-; CHECK-NEXT:    v_lshrrev_b16_e32 v8, v3, v4
-; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v11
-; CHECK-NEXT:    v_and_b32_e32 v9, 1, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v9, v11, v9
-; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v10, v4
-; CHECK-NEXT:    v_and_b32_e32 v4, v4, v9
-; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, v4, s[4:5]
-; CHECK-NEXT:    v_add_u16_e32 v3, v8, v3
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v3
-; CHECK-NEXT:    v_lshlrev_b16_e32 v7, 2, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v7, v0, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v4, v0, v4
-; CHECK-NEXT:    v_or_b32_e32 v7, v7, v5
-; CHECK-NEXT:    v_or_b32_e32 v3, v4, v3
-; CHECK-NEXT:    v_cmp_gt_i16_e64 s[4:5], 1, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v7, v3, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v5
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], 30, v6
-; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 30, v6
-; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v0
-; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, v4, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v1
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], 31, v2
-; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
-; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v6, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0x7f, v1
+; CHECK-NEXT:    v_or_b32_e32 v3, v5, v3
+; CHECK-NEXT:    v_mov_b32_e32 v5, 1
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v7
+; CHECK-NEXT:    v_and_b32_sdwa v5, v2, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v7, v5
+; CHECK-NEXT:    v_lshrrev_b16_e32 v1, 7, v1
+; CHECK-NEXT:    v_and_b32_e32 v1, v1, v5
+; CHECK-NEXT:    v_add_u16_sdwa v1, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, 0, 1, vcc
+; CHECK-NEXT:    v_add_u16_e32 v2, v4, v2
+; CHECK-NEXT:    v_add_u16_e32 v2, 14, v2
+; CHECK-NEXT:    v_lshlrev_b16_e32 v4, 2, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v1, v1, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v4, v6, v4
+; CHECK-NEXT:    v_or_b32_e32 v4, v4, v1
+; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, 1, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v3, vcc
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v1
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 30, v2
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 30, v2
+; CHECK-NEXT:    v_or_b32_e32 v1, 0x7c, v6
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v1, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x60
+; CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v3
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x204
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
+; CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
+; CHECK-NEXT:    v_cmp_class_f16_e64 vcc, v0, 3
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -721,80 +377,78 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-LABEL: to_f8e5m2_from_bf16:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_and_b32_e32 v1, 0x7f, v0
-; CHECK-NEXT:    v_lshlrev_b32_e32 v3, 16, v1
-; CHECK-NEXT:    v_ffbh_u32_e32 v3, v3
-; CHECK-NEXT:    v_bfe_u32 v2, v0, 7, 8
-; CHECK-NEXT:    v_add_u16_e32 v4, -8, v3
-; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v1
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v2
-; CHECK-NEXT:    v_lshlrev_b16_e32 v4, v4, v1
-; CHECK-NEXT:    v_and_b32_e32 v4, 0x7f, v4
-; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, v1, v4, s[4:5]
-; CHECK-NEXT:    v_and_b32_e32 v7, 15, v4
-; CHECK-NEXT:    v_lshrrev_b16_e32 v5, 5, v4
-; CHECK-NEXT:    v_cmp_ne_u16_e64 s[6:7], 0, v7
-; CHECK-NEXT:    v_and_b32_e32 v6, 1, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v6, v7, v6
-; CHECK-NEXT:    v_lshrrev_b16_e32 v7, 4, v4
-; CHECK-NEXT:    v_and_b32_e32 v6, v7, v6
-; CHECK-NEXT:    v_add_u16_e32 v5, v5, v6
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[6:7], 3, v5
-; CHECK-NEXT:    v_sub_u16_e32 v3, 9, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, s[6:7]
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v2, v3, s[4:5]
-; CHECK-NEXT:    v_add_u16_e32 v6, v3, v6
-; CHECK-NEXT:    v_sub_u16_e32 v3, 0x76, v3
-; CHECK-NEXT:    v_min_u16_e32 v3, 15, v3
-; CHECK-NEXT:    v_sub_u16_e64 v10, v3, 1 clamp
-; CHECK-NEXT:    v_lshlrev_b16_e64 v11, v10, 1
-; CHECK-NEXT:    v_or_b32_e32 v4, 0x80, v4
-; CHECK-NEXT:    v_add_u16_e32 v11, -1, v11
+; CHECK-NEXT:    v_lshlrev_b32_e32 v1, 16, v0
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v2, v1
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v1, v1
+; CHECK-NEXT:    v_bfe_u32 v3, v2, 16, 1
+; CHECK-NEXT:    s_movk_i32 s4, 0x7fff
+; CHECK-NEXT:    v_sub_u16_e32 v5, -8, v1
+; CHECK-NEXT:    v_add3_u32 v3, v3, v2, s4
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x400000, v2
+; CHECK-NEXT:    v_cmp_u_f32_e32 vcc, v2, v2
+; CHECK-NEXT:    v_min_u16_e32 v5, 15, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v4, vcc
+; CHECK-NEXT:    s_movk_i32 s4, 0x7f
+; CHECK-NEXT:    v_sub_u16_e64 v8, v5, 1 clamp
+; CHECK-NEXT:    v_and_b32_sdwa v3, v2, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
+; CHECK-NEXT:    v_lshlrev_b16_e64 v9, v8, 1
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x80, v3
+; CHECK-NEXT:    v_add_u16_e32 v9, -1, v9
+; CHECK-NEXT:    v_and_b32_e32 v9, v4, v9
+; CHECK-NEXT:    v_lshrrev_b16_e32 v6, v5, v4
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v9
+; CHECK-NEXT:    v_and_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v7, v9, v7
+; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v8, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v7
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, 0, v4, vcc
+; CHECK-NEXT:    v_add_u16_e32 v4, v6, v4
 ; CHECK-NEXT:    s_movk_i32 s4, 0x80
-; CHECK-NEXT:    v_and_b32_e32 v11, v4, v11
-; CHECK-NEXT:    v_and_b32_sdwa v0, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
-; CHECK-NEXT:    v_lshrrev_b16_e32 v8, v3, v4
-; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v11
-; CHECK-NEXT:    v_and_b32_e32 v9, 1, v8
-; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v9, v11, v9
-; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v10, v4
-; CHECK-NEXT:    v_and_b32_e32 v4, v4, v9
-; CHECK-NEXT:    v_cmp_ne_u16_e64 s[4:5], 0, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, v4, s[4:5]
-; CHECK-NEXT:    v_add_u16_e32 v3, v8, v3
-; CHECK-NEXT:    v_add_u16_e32 v6, 0xff90, v6
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v3
-; CHECK-NEXT:    v_lshlrev_b16_e32 v7, 2, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 4, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v7, v0, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v4, v0, v4
-; CHECK-NEXT:    v_or_b32_e32 v7, v7, v5
-; CHECK-NEXT:    v_or_b32_e32 v3, v4, v3
-; CHECK-NEXT:    v_cmp_gt_i16_e64 s[4:5], 1, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v7, v3, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 3, v5
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], 30, v6
-; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i16_e64 s[4:5], 30, v6
-; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v0
-; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
-; CHECK-NEXT:    v_or_b32_e32 v5, v2, v1
-; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, v4, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v5
-; CHECK-NEXT:    s_movk_i32 s6, 0xff
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v3, v0, s[4:5]
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 0, v1
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[6:7], s6, v2
-; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v4, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
-; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v4
+; CHECK-NEXT:    v_mov_b32_e32 v7, 15
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v6, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_and_b32_sdwa v7, v2, v7 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_lshrrev_b16_e32 v3, 5, v3
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v7
+; CHECK-NEXT:    v_or_b32_e32 v4, v5, v4
+; CHECK-NEXT:    v_and_b32_e32 v5, 1, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v7, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v2, 20, v2
+; CHECK-NEXT:    v_and_b32_e32 v2, v2, v5
+; CHECK-NEXT:    v_add_u16_e32 v2, v3, v2
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, 1, vcc
+; CHECK-NEXT:    v_add_u16_e32 v1, v1, v3
+; CHECK-NEXT:    v_add_u16_e32 v1, 14, v1
+; CHECK-NEXT:    v_lshlrev_b16_e32 v3, 2, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v3, v6, v3
+; CHECK-NEXT:    v_or_b32_e32 v3, v3, v2
+; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, 1, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v4, vcc
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v2
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 30, v1
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 30, v1
+; CHECK-NEXT:    v_or_b32_e32 v1, 0x7c, v6
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v1, vcc
+; CHECK-NEXT:    v_cmp_eq_u16_e32 vcc, 0, v0
+; CHECK-NEXT:    s_movk_i32 s4, 0x7f80
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
+; CHECK-NEXT:    v_cmp_eq_u16_e32 vcc, s4, v0
+; CHECK-NEXT:    s_movk_i32 s4, 0x7f81
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
+; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, s4, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -805,100 +459,82 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f64:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:    v_mov_b32_e32 v2, v1
-; CHECK-NEXT:    v_and_b32_e32 v1, 0xfffff, v2
-; CHECK-NEXT:    v_ffbh_u32_e32 v5, v0
-; CHECK-NEXT:    v_bfe_u32 v3, v2, 20, 11
-; CHECK-NEXT:    v_mov_b32_e32 v4, 0
-; CHECK-NEXT:    v_add_u32_e32 v5, 32, v5
-; CHECK-NEXT:    v_ffbh_u32_e32 v6, v1
-; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[0:1]
-; CHECK-NEXT:    v_cmp_eq_u64_e64 s[4:5], 0, v[3:4]
-; CHECK-NEXT:    v_min_u32_e32 v9, v5, v6
-; CHECK-NEXT:    v_sub_co_u32_e64 v5, s[6:7], 12, v9
-; CHECK-NEXT:    v_subb_co_u32_e64 v6, s[6:7], 0, 0, s[6:7]
-; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v14, v3, v5, s[4:5]
-; CHECK-NEXT:    s_movk_i32 s6, 0x423
-; CHECK-NEXT:    v_cndmask_b32_e64 v13, 0, v6, s[4:5]
-; CHECK-NEXT:    v_sub_co_u32_e64 v5, s[6:7], s6, v14
-; CHECK-NEXT:    v_subb_co_u32_e64 v6, s[6:7], 0, v13, s[6:7]
-; CHECK-NEXT:    v_cmp_gt_u64_e64 s[6:7], 63, v[5:6]
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, v6, s[6:7]
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, 63, v5, s[6:7]
-; CHECK-NEXT:    v_cmp_lt_u64_e64 s[6:7], 1, v[5:6]
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, 1, v5, s[6:7]
-; CHECK-NEXT:    v_add_u32_e32 v15, -1, v7
-; CHECK-NEXT:    v_lshlrev_b64 v[7:8], v15, 1
-; CHECK-NEXT:    v_add_co_u32_e64 v9, s[6:7], -11, v9
-; CHECK-NEXT:    v_lshlrev_b64 v[9:10], v9, v[0:1]
-; CHECK-NEXT:    v_add_co_u32_e64 v11, s[6:7], -1, v7
-; CHECK-NEXT:    v_addc_co_u32_e64 v12, s[6:7], -1, v8, s[6:7]
-; CHECK-NEXT:    v_and_b32_e32 v8, 0xfffff, v10
-; CHECK-NEXT:    v_cndmask_b32_e64 v16, v1, v8, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, v0, v9, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v8, 0x100000, v16
-; CHECK-NEXT:    v_and_b32_e32 v10, v8, v12
-; CHECK-NEXT:    v_and_b32_e32 v9, v7, v11
-; CHECK-NEXT:    v_lshrrev_b64 v[11:12], v5, v[7:8]
-; CHECK-NEXT:    v_cmp_ne_u64_e64 s[4:5], 0, v[9:10]
-; CHECK-NEXT:    v_and_b32_e32 v17, 1, v11
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, s[4:5]
-; CHECK-NEXT:    v_lshrrev_b64 v[8:9], v15, v[7:8]
-; CHECK-NEXT:    v_or_b32_e32 v9, v10, v17
-; CHECK-NEXT:    v_cmp_ne_u64_e64 s[4:5], 0, v[5:6]
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v9
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, v8, s[4:5]
-; CHECK-NEXT:    v_add_co_u32_e64 v5, s[4:5], v11, v5
-; CHECK-NEXT:    v_addc_co_u32_e64 v6, s[4:5], 0, v12, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 3, v[5:6]
-; CHECK-NEXT:    v_and_b32_e32 v8, 0x1ffff, v16
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 4, s[4:5]
+; CHECK-NEXT:    v_frexp_exp_i32_f64_e32 v12, v[0:1]
+; CHECK-NEXT:    v_frexp_mant_f64_e32 v[2:3], v[0:1]
 ; CHECK-NEXT:    s_movk_i32 s4, 0x80
-; CHECK-NEXT:    v_and_b32_sdwa v2, v2, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
-; CHECK-NEXT:    v_cmp_ne_u64_e64 s[4:5], 0, v[7:8]
-; CHECK-NEXT:    v_or3_b32 v9, v2, v6, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 1, s[4:5]
-; CHECK-NEXT:    v_bfe_u32 v6, v16, 18, 1
-; CHECK-NEXT:    v_or_b32_e32 v5, v5, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v6, 17, v16
-; CHECK-NEXT:    v_and_b32_e32 v5, v6, v5
-; CHECK-NEXT:    v_lshrrev_b32_e32 v6, 18, v16
-; CHECK-NEXT:    v_add_co_u32_e64 v5, s[4:5], v6, v5
-; CHECK-NEXT:    v_addc_co_u32_e64 v6, s[4:5], 0, 0, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 3, v[5:6]
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, s[4:5]
-; CHECK-NEXT:    v_add_co_u32_e64 v7, s[6:7], v14, v7
-; CHECK-NEXT:    v_addc_co_u32_e64 v8, s[6:7], 0, v13, s[6:7]
-; CHECK-NEXT:    s_movk_i32 s6, 0xfc10
-; CHECK-NEXT:    v_add_co_u32_e64 v7, s[6:7], s6, v7
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, s[4:5]
-; CHECK-NEXT:    v_addc_co_u32_e64 v8, s[6:7], -1, v8, s[6:7]
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 3, v[5:6]
-; CHECK-NEXT:    v_cmp_eq_u64_e64 s[6:7], 30, v[7:8]
-; CHECK-NEXT:    v_lshlrev_b32_e32 v10, 2, v7
-; CHECK-NEXT:    v_cmp_gt_i64_e64 s[8:9], 1, v[7:8]
-; CHECK-NEXT:    s_and_b64 s[6:7], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cmp_lt_i64_e64 s[4:5], 30, v[7:8]
-; CHECK-NEXT:    v_or3_b32 v10, v10, v2, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, v10, v9, s[8:9]
-; CHECK-NEXT:    v_or_b32_e32 v7, 0x7c, v2
-; CHECK-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
-; CHECK-NEXT:    v_cndmask_b32_e64 v8, v5, v7, s[4:5]
-; CHECK-NEXT:    v_or_b32_e32 v5, v3, v0
-; CHECK-NEXT:    v_mov_b32_e32 v6, v1
-; CHECK-NEXT:    s_mov_b64 s[6:7], 0x7ff
-; CHECK-NEXT:    v_cmp_eq_u64_e64 s[4:5], 0, v[0:1]
-; CHECK-NEXT:    v_cmp_eq_u64_e64 s[6:7], s[6:7], v[3:4]
-; CHECK-NEXT:    v_cmp_eq_u64_e64 s[8:9], 0, v[5:6]
-; CHECK-NEXT:    s_and_b64 s[4:5], s[6:7], s[4:5]
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v8, v2, s[8:9]
-; CHECK-NEXT:    v_cndmask_b32_e64 v0, v0, v7, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v1, 0x7e
-; CHECK-NEXT:    s_and_b64 vcc, s[6:7], vcc
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v0, v1, vcc
+; CHECK-NEXT:    v_ashrrev_i32_e32 v13, 31, v12
+; CHECK-NEXT:    v_sub_co_u32_e32 v4, vcc, 37, v12
+; CHECK-NEXT:    v_subb_co_u32_e32 v5, vcc, 0, v13, vcc
+; CHECK-NEXT:    v_cmp_gt_u64_e32 vcc, 63, v[4:5]
+; CHECK-NEXT:    v_and_b32_e32 v15, 0xfffff, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, 63, v4, vcc
+; CHECK-NEXT:    v_cmp_lt_u64_e32 vcc, 1, v[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 1, v4, vcc
+; CHECK-NEXT:    v_add_u32_e32 v14, -1, v6
+; CHECK-NEXT:    v_lshlrev_b64 v[6:7], v14, 1
+; CHECK-NEXT:    v_add_co_u32_e32 v8, vcc, -1, v6
+; CHECK-NEXT:    v_addc_co_u32_e32 v9, vcc, -1, v7, vcc
+; CHECK-NEXT:    v_or_b32_e32 v7, 0x100000, v15
+; CHECK-NEXT:    v_mov_b32_e32 v6, v2
+; CHECK-NEXT:    v_and_b32_e32 v9, v7, v9
+; CHECK-NEXT:    v_and_b32_e32 v8, v2, v8
+; CHECK-NEXT:    v_lshrrev_b64 v[10:11], v4, v[6:7]
+; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[8:9]
+; CHECK-NEXT:    v_and_b32_e32 v9, 1, v10
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_lshrrev_b64 v[6:7], v14, v[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v7, v8, v9
+; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[4:5]
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, 0, v6, vcc
+; CHECK-NEXT:    v_add_co_u32_e32 v4, vcc, v10, v4
+; CHECK-NEXT:    v_addc_co_u32_e32 v5, vcc, 0, v11, vcc
+; CHECK-NEXT:    v_cmp_lt_i64_e32 vcc, 3, v[4:5]
+; CHECK-NEXT:    v_and_b32_sdwa v8, v1, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 4, vcc
+; CHECK-NEXT:    v_or3_b32 v9, v8, v5, v4
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x1ffff, v3
+; CHECK-NEXT:    v_mov_b32_e32 v4, v2
+; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[4:5]
+; CHECK-NEXT:    v_bfe_u32 v4, v15, 18, 1
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v2, v2, v4
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 17, v3
+; CHECK-NEXT:    v_and_b32_e32 v2, v4, v2
+; CHECK-NEXT:    v_bfe_u32 v3, v3, 18, 2
+; CHECK-NEXT:    v_add_co_u32_e32 v2, vcc, v3, v2
+; CHECK-NEXT:    v_addc_co_u32_e64 v3, s[4:5], 0, 0, vcc
+; CHECK-NEXT:    v_cmp_lt_i64_e32 vcc, 3, v[2:3]
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 1, vcc
+; CHECK-NEXT:    v_add_co_u32_e64 v4, s[4:5], v12, v4
+; CHECK-NEXT:    v_addc_co_u32_e64 v5, s[4:5], 0, v13, s[4:5]
+; CHECK-NEXT:    v_add_co_u32_e64 v4, s[4:5], 14, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e64 v5, s[4:5], 0, v5, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
+; CHECK-NEXT:    v_lshlrev_b64 v[6:7], 2, v[4:5]
+; CHECK-NEXT:    v_cmp_lt_i64_e32 vcc, 3, v[2:3]
+; CHECK-NEXT:    v_cmp_eq_u64_e64 s[4:5], 30, v[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v6, v6, v8
+; CHECK-NEXT:    v_cmp_gt_i64_e64 s[6:7], 1, v[4:5]
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i64_e32 vcc, 30, v[4:5]
+; CHECK-NEXT:    v_or_b32_e32 v6, v6, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v6, v9, s[6:7]
+; CHECK-NEXT:    v_or_b32_e32 v3, 0x7c, v8
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0x60
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
+; CHECK-NEXT:    v_cmp_class_f64_e32 vcc, v[0:1], v4
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0x204
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v8, vcc
+; CHECK-NEXT:    v_cmp_class_f64_e32 vcc, v[0:1], v4
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
+; CHECK-NEXT:    v_cmp_class_f64_e64 vcc, v[0:1], 3
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x7e
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v3, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
diff --git a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
index 0c98d9ca21713..0c53acb05b3a3 100644
--- a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
@@ -16,472 +16,158 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
 ; Layout: sign(1) exp(5) mant(2), bias=15
 ; Supports: Inf, NaN, signed zero, denormals
 
-; Float8E5M2 normal: f32 1.0 -> 0_01111_00 = 0x3C
-define i8 @to_f8e5m2_normal() {
-; CHECK-LABEL: to_f8e5m2_normal(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 60;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 zero: f32 0.0 -> 0_00000_00 = 0x00
-define i8 @to_f8e5m2_zero() {
-; CHECK-LABEL: to_f8e5m2_zero(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 0;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 negative zero: f32 -0.0 -> 1_00000_00 = 0x80
-define i8 @to_f8e5m2_neg_zero() {
-; CHECK-LABEL: to_f8e5m2_neg_zero(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 128;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float -0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 +Inf: f32 Inf -> 0_11111_00 = 0x7C
-define i8 @to_f8e5m2_inf() {
-; CHECK-LABEL: to_f8e5m2_inf(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 124;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 NaN: f32 NaN -> qNaN
-define i8 @to_f8e5m2_nan() {
-; CHECK-LABEL: to_f8e5m2_nan(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 126;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 max: 57344.0 -> 0_11110_11 = 0x7B
-define i8 @to_f8e5m2_max() {
-; CHECK-LABEL: to_f8e5m2_max(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 123;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 57344.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 overflow (no saturation): 100000.0 -> Inf = 0x7C
-define i8 @to_f8e5m2_overflow() {
-; CHECK-LABEL: to_f8e5m2_overflow(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 124;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 overflow with saturation: 100000.0 -> max = 0x7B
-define i8 @to_f8e5m2_overflow_sat() {
-; CHECK-LABEL: to_f8e5m2_overflow_sat(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 123;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 true)
-  ret i8 %r
-}
-
-; Float8E5M2 denorm: very small value -> dst denorm
-define i8 @to_f8e5m2_denorm() {
-  ; 2^(-16) = 0x37800000 -> smallest E5M2 denorm 0_00000_01 = 0x01
-; CHECK-LABEL: to_f8e5m2_denorm(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 1;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x3EF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
 ; Float8E5M2 runtime arg test
 define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-LABEL: to_f8e5m2_dynamic(
 ; CHECK:       {
-; CHECK-NEXT:    .reg .pred %p<16>;
-; CHECK-NEXT:    .reg .b32 %r<60>;
+; CHECK-NEXT:    .reg .pred %p<15>;
+; CHECK-NEXT:    .reg .b32 %r<63>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e5m2_dynamic_param_0];
-; CHECK-NEXT:    and.b32 %r2, %r1, 8388607;
-; CHECK-NEXT:    setp.ne.b32 %p1, %r2, 0;
-; CHECK-NEXT:    bfe.u32 %r3, %r1, 23, 8;
-; CHECK-NEXT:    setp.eq.b32 %p2, %r3, 0;
-; CHECK-NEXT:    and.pred %p3, %p2, %p1;
-; CHECK-NEXT:    clz.b32 %r4, %r2;
-; CHECK-NEXT:    add.s32 %r5, %r4, -8;
-; CHECK-NEXT:    shl.b32 %r6, %r2, %r5;
-; CHECK-NEXT:    and.b32 %r7, %r6, 8388607;
-; CHECK-NEXT:    selp.b32 %r8, %r7, %r2, %p3;
-; CHECK-NEXT:    bfe.u32 %r9, %r8, 21, 1;
-; CHECK-NEXT:    and.b32 %r10, %r8, 1048575;
-; CHECK-NEXT:    setp.ne.b32 %p4, %r10, 0;
-; CHECK-NEXT:    selp.b32 %r11, 1, 0, %p4;
-; CHECK-NEXT:    or.b32 %r12, %r11, %r9;
-; CHECK-NEXT:    shr.u32 %r13, %r8, 20;
-; CHECK-NEXT:    and.b32 %r14, %r13, %r12;
-; CHECK-NEXT:    shr.u32 %r15, %r8, 21;
-; CHECK-NEXT:    add.s32 %r16, %r15, %r14;
-; CHECK-NEXT:    setp.gt.s32 %p5, %r16, 3;
-; CHECK-NEXT:    selp.b32 %r17, 0, %r16, %p5;
-; CHECK-NEXT:    selp.b32 %r18, 1, 0, %p5;
-; CHECK-NEXT:    sub.s32 %r19, 9, %r4;
-; CHECK-NEXT:    selp.b32 %r20, %r19, %r3, %p3;
-; CHECK-NEXT:    add.s32 %r21, %r20, %r18;
-; CHECK-NEXT:    add.s32 %r22, %r21, -112;
-; CHECK-NEXT:    shl.b32 %r23, %r22, 2;
-; CHECK-NEXT:    shr.u32 %r24, %r1, 24;
-; CHECK-NEXT:    and.b32 %r25, %r24, 128;
-; CHECK-NEXT:    or.b32 %r26, %r25, %r23;
-; CHECK-NEXT:    or.b32 %r27, %r26, %r17;
-; CHECK-NEXT:    or.b32 %r28, %r8, 8388608;
-; CHECK-NEXT:    sub.s32 %r29, 134, %r20;
-; CHECK-NEXT:    min.u32 %r30, %r29, 31;
-; CHECK-NEXT:    shr.u32 %r31, %r28, %r30;
-; CHECK-NEXT:    and.b32 %r32, %r31, 1;
-; CHECK-NEXT:    max.u32 %r33, %r30, 1;
-; CHECK-NEXT:    add.s32 %r34, %r33, -1;
-; CHECK-NEXT:    mov.b32 %r35, 1;
-; CHECK-NEXT:    shl.b32 %r36, %r35, %r34;
-; CHECK-NEXT:    add.s32 %r37, %r36, -1;
-; CHECK-NEXT:    and.b32 %r38, %r28, %r37;
-; CHECK-NEXT:    setp.ne.b32 %p6, %r38, 0;
-; CHECK-NEXT:    selp.b32 %r39, 1, 0, %p6;
-; CHECK-NEXT:    or.b32 %r40, %r39, %r32;
-; CHECK-NEXT:    shr.u32 %r41, %r28, %r34;
-; CHECK-NEXT:    and.b32 %r42, %r41, %r40;
-; CHECK-NEXT:    setp.ne.b32 %p7, %r30, 0;
-; CHECK-NEXT:    selp.b32 %r43, %r42, 0, %p7;
-; CHECK-NEXT:    add.s32 %r44, %r31, %r43;
-; CHECK-NEXT:    setp.gt.s32 %p8, %r44, 3;
-; CHECK-NEXT:    selp.b32 %r45, 0, %r44, %p8;
-; CHECK-NEXT:    selp.b32 %r46, 4, 0, %p8;
-; CHECK-NEXT:    or.b32 %r47, %r25, %r46;
-; CHECK-NEXT:    or.b32 %r48, %r47, %r45;
-; CHECK-NEXT:    setp.lt.s32 %p9, %r22, 1;
-; CHECK-NEXT:    selp.b32 %r49, %r48, %r27, %p9;
-; CHECK-NEXT:    setp.gt.s32 %p10, %r17, 3;
-; CHECK-NEXT:    or.b32 %r50, %r25, 124;
-; CHECK-NEXT:    selp.b32 %r51, %r50, %r49, %p10;
-; CHECK-NEXT:    setp.eq.b32 %p11, %r22, 30;
-; CHECK-NEXT:    selp.b32 %r52, %r51, %r49, %p11;
-; CHECK-NEXT:    setp.gt.s32 %p12, %r22, 30;
-; CHECK-NEXT:    selp.b32 %r53, %r50, %r52, %p12;
-; CHECK-NEXT:    or.b32 %r54, %r3, %r2;
-; CHECK-NEXT:    setp.eq.b32 %p13, %r54, 0;
-; CHECK-NEXT:    selp.b32 %r55, %r25, %r53, %p13;
-; CHECK-NEXT:    setp.eq.b32 %p14, %r2, 0;
-; CHECK-NEXT:    selp.b32 %r56, %r50, %r55, %p14;
-; CHECK-NEXT:    setp.eq.b32 %p15, %r3, 255;
-; CHECK-NEXT:    selp.b32 %r57, %r56, %r55, %p15;
-; CHECK-NEXT:    selp.b32 %r58, 126, %r57, %p1;
-; CHECK-NEXT:    selp.b32 %r59, %r58, %r57, %p15;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r59;
+; CHECK-NEXT:    mul.rn.f32 %r2, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r3, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r3, 8388608;
+; CHECK-NEXT:    selp.b32 %r4, %r2, %r1, %p1;
+; CHECK-NEXT:    and.b32 %r5, %r4, -2139095041;
+; CHECK-NEXT:    or.b32 %r6, %r5, 1056964608;
+; CHECK-NEXT:    add.s32 %r7, %r3, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r7, -2139095039;
+; CHECK-NEXT:    selp.f32 %r8, %r1, %r6, %p2;
+; CHECK-NEXT:    and.b32 %r9, %r8, 8388607;
+; CHECK-NEXT:    or.b32 %r10, %r9, 8388608;
+; CHECK-NEXT:    and.b32 %r11, %r2, 2139095040;
+; CHECK-NEXT:    selp.b32 %r12, %r11, %r3, %p1;
+; CHECK-NEXT:    shr.u32 %r13, %r12, 23;
+; CHECK-NEXT:    selp.b32 %r14, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r15, %r13, %r14;
+; CHECK-NEXT:    add.s32 %r16, %r15, -126;
+; CHECK-NEXT:    selp.b32 %r17, 0, %r16, %p2;
+; CHECK-NEXT:    sub.s32 %r18, 8, %r17;
+; CHECK-NEXT:    min.u32 %r19, %r18, 31;
+; CHECK-NEXT:    shr.u32 %r20, %r10, %r19;
+; CHECK-NEXT:    and.b32 %r21, %r20, 1;
+; CHECK-NEXT:    max.u32 %r22, %r19, 1;
+; CHECK-NEXT:    add.s32 %r23, %r22, -1;
+; CHECK-NEXT:    mov.b32 %r24, 1;
+; CHECK-NEXT:    shl.b32 %r25, %r24, %r23;
+; CHECK-NEXT:    add.s32 %r26, %r25, -1;
+; CHECK-NEXT:    and.b32 %r27, %r10, %r26;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r27, 0;
+; CHECK-NEXT:    selp.b32 %r28, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r29, %r28, %r21;
+; CHECK-NEXT:    shr.u32 %r30, %r10, %r23;
+; CHECK-NEXT:    and.b32 %r31, %r30, %r29;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r19, 0;
+; CHECK-NEXT:    selp.b32 %r32, %r31, 0, %p4;
+; CHECK-NEXT:    add.s32 %r33, %r20, %r32;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r33, 3;
+; CHECK-NEXT:    selp.b32 %r34, 0, %r33, %p5;
+; CHECK-NEXT:    selp.b32 %r35, 4, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r36, %r1, 24;
+; CHECK-NEXT:    and.b32 %r37, %r36, 128;
+; CHECK-NEXT:    or.b32 %r38, %r37, %r35;
+; CHECK-NEXT:    or.b32 %r39, %r38, %r34;
+; CHECK-NEXT:    bfe.u32 %r40, %r9, 21, 1;
+; CHECK-NEXT:    and.b32 %r41, %r8, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r41, 0;
+; CHECK-NEXT:    selp.b32 %r42, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r43, %r42, %r40;
+; CHECK-NEXT:    shr.u32 %r44, %r8, 20;
+; CHECK-NEXT:    and.b32 %r45, %r44, %r43;
+; CHECK-NEXT:    bfe.u32 %r46, %r8, 21, 2;
+; CHECK-NEXT:    add.s32 %r47, %r46, %r45;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r47, 3;
+; CHECK-NEXT:    selp.b32 %r48, 0, %r47, %p7;
+; CHECK-NEXT:    selp.b32 %r49, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r50, %r17, %r49;
+; CHECK-NEXT:    add.s32 %r51, %r50, 14;
+; CHECK-NEXT:    shl.b32 %r52, %r51, 2;
+; CHECK-NEXT:    or.b32 %r53, %r37, %r52;
+; CHECK-NEXT:    or.b32 %r54, %r53, %r48;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r51, 1;
+; CHECK-NEXT:    selp.b32 %r55, %r39, %r54, %p8;
+; CHECK-NEXT:    setp.gt.s32 %p9, %r48, 3;
+; CHECK-NEXT:    or.b32 %r56, %r37, 124;
+; CHECK-NEXT:    selp.b32 %r57, %r56, %r55, %p9;
+; CHECK-NEXT:    setp.eq.b32 %p10, %r51, 30;
+; CHECK-NEXT:    selp.b32 %r58, %r57, %r55, %p10;
+; CHECK-NEXT:    setp.gt.s32 %p11, %r51, 30;
+; CHECK-NEXT:    selp.b32 %r59, %r56, %r58, %p11;
+; CHECK-NEXT:    setp.eq.b32 %p12, %r3, 0;
+; CHECK-NEXT:    selp.b32 %r60, %r37, %r59, %p12;
+; CHECK-NEXT:    setp.eq.b32 %p13, %r3, 2139095040;
+; CHECK-NEXT:    selp.b32 %r61, %r56, %r60, %p13;
+; CHECK-NEXT:    setp.gt.s32 %p14, %r3, 2139095040;
+; CHECK-NEXT:    selp.b32 %r62, 126, %r61, %p14;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r62;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
 }
 
-; Float8E4M3FN (NanOnly, NanEncoding=AllOnes)
-; Layout: sign(1) exp(4) mant(3), maxExp=8, minExp=-6, bias=7
-; Only 0_1111_111 and 1_1111_111 are NaN; all other exp=15 values are finite.
-
-; Float8E4M3FN normal: f32 1.0 -> 0_0111_000 = 0x38
-define i8 @to_f8e4m3fn_normal() {
-; CHECK-LABEL: to_f8e4m3fn_normal(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 56;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN max: 448.0 -> 0_1111_110 = 0x7E
-define i8 @to_f8e4m3fn_max() {
-; CHECK-LABEL: to_f8e4m3fn_max(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 126;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 448.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN NaN: f32 NaN -> 0_1111_111 = 0x7F
-define i8 @to_f8e4m3fn_nan() {
-; CHECK-LABEL: to_f8e4m3fn_nan(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 127;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN overflow with saturation: 1000.0 -> max = 0x7E
-define i8 @to_f8e4m3fn_overflow_sat() {
-; CHECK-LABEL: to_f8e4m3fn_overflow_sat(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 126;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1000.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 true)
-  ret i8 %r
-}
-
-; Float6E3M2FN (FiniteOnly)
-; Layout: sign(1) exp(3) mant(2), bias=3, maxExp=4
-; No Inf, no NaN. All bit patterns are finite.
-
-; Float6E3M2FN normal: f32 1.0 -> 0_011_00 = 0x0C
-define i6 @to_f6e3m2fn_normal() {
-; CHECK-LABEL: to_f6e3m2fn_normal(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 12;
-; CHECK-NEXT:    ret;
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN max: 28.0 -> 0_111_11 = 0x1F
-define i6 @to_f6e3m2fn_max() {
-; CHECK-LABEL: to_f6e3m2fn_max(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 31;
-; CHECK-NEXT:    ret;
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 28.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN zero: f32 0.0 -> 0_000_00 = 0x00
-define i6 @to_f6e3m2fn_zero() {
-; CHECK-LABEL: to_f6e3m2fn_zero(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 0;
-; CHECK-NEXT:    ret;
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 0.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN negative: f32 -1.0 -> 1_011_00
-define i6 @to_f6e3m2fn_negative() {
-; CHECK-LABEL: to_f6e3m2fn_negative(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 44;
-; CHECK-NEXT:    ret;
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float -1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E2M3FN (FiniteOnly)
-; Layout: sign(1) exp(2) mant(3), bias=1, maxExp=2
-; No Inf, no NaN. All bit patterns are finite.
-
-; Float6E2M3FN normal: f32 1.0 -> 0_01_000 = 0x08
-define i6 @to_f6e2m3fn_normal() {
-; CHECK-LABEL: to_f6e2m3fn_normal(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 8;
-; CHECK-NEXT:    ret;
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E2M3FN max: 7.5 -> 0_11_111 = 0x1F
-define i6 @to_f6e2m3fn_max() {
-; CHECK-LABEL: to_f6e2m3fn_max(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 31;
-; CHECK-NEXT:    ret;
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 7.5, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float4E2M1FN (FiniteOnly)
-; Layout: sign(1) exp(2) mant(1), bias=1, maxExp=2
-; No Inf, no NaN.
-
-; Float4E2M1FN normal: f32 1.0 -> 0_01_0 = 0x2
-define i4 @to_f4e2m1fn_normal() {
-; CHECK-LABEL: to_f4e2m1fn_normal(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 2;
-; CHECK-NEXT:    ret;
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 1.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
-; Float4E2M1FN max: 6.0 -> 0_11_1 = 0x7
-define i4 @to_f4e2m1fn_max() {
-; CHECK-LABEL: to_f4e2m1fn_max(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 7;
-; CHECK-NEXT:    ret;
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 6.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
-; Float4E2M1FN denorm: 0.5 -> 0_00_1 = 0x1
-define i4 @to_f4e2m1fn_denorm() {
-; CHECK-LABEL: to_f4e2m1fn_denorm(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 1;
-; CHECK-NEXT:    ret;
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 0.5, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
 ; Rounding mode tests
 
-; Round to nearest
-define i8 @to_f8e5m2_round_nearest() {
-; CHECK-LABEL: to_f8e5m2_round_nearest(
-; CHECK:       {
-; CHECK-EMPTY:
-; CHECK-EMPTY:
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    st.param.b32 [func_retval0], 62;
-; CHECK-NEXT:    ret;
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.5, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
 ; Round toward zero with runtime arg
 define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-LABEL: to_f8e5m2_round_towardzero(
 ; CHECK:       {
-; CHECK-NEXT:    .reg .pred %p<13>;
-; CHECK-NEXT:    .reg .b32 %r<40>;
+; CHECK-NEXT:    .reg .pred %p<12>;
+; CHECK-NEXT:    .reg .b32 %r<41>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e5m2_round_towardzero_param_0];
-; CHECK-NEXT:    and.b32 %r2, %r1, 8388607;
-; CHECK-NEXT:    setp.ne.b32 %p1, %r2, 0;
-; CHECK-NEXT:    bfe.u32 %r3, %r1, 23, 8;
-; CHECK-NEXT:    setp.eq.b32 %p2, %r3, 0;
-; CHECK-NEXT:    and.pred %p3, %p2, %p1;
-; CHECK-NEXT:    clz.b32 %r4, %r2;
-; CHECK-NEXT:    add.s32 %r5, %r4, -8;
-; CHECK-NEXT:    shl.b32 %r6, %r2, %r5;
-; CHECK-NEXT:    and.b32 %r7, %r6, 8388607;
-; CHECK-NEXT:    selp.b32 %r8, %r7, %r2, %p3;
-; CHECK-NEXT:    or.b32 %r9, %r8, 8388608;
-; CHECK-NEXT:    sub.s32 %r10, 9, %r4;
-; CHECK-NEXT:    selp.b32 %r11, %r10, %r3, %p3;
-; CHECK-NEXT:    sub.s32 %r12, 134, %r11;
-; CHECK-NEXT:    min.u32 %r13, %r12, 31;
-; CHECK-NEXT:    shr.u32 %r14, %r9, %r13;
-; CHECK-NEXT:    setp.gt.s32 %p4, %r14, 3;
-; CHECK-NEXT:    selp.b32 %r15, 0, %r14, %p4;
-; CHECK-NEXT:    selp.b32 %r16, 4, 0, %p4;
-; CHECK-NEXT:    shr.u32 %r17, %r1, 24;
-; CHECK-NEXT:    and.b32 %r18, %r17, 128;
-; CHECK-NEXT:    or.b32 %r19, %r18, %r16;
-; CHECK-NEXT:    or.b32 %r20, %r19, %r15;
-; CHECK-NEXT:    shr.u32 %r21, %r8, 21;
-; CHECK-NEXT:    setp.gt.s32 %p5, %r21, 3;
-; CHECK-NEXT:    selp.b32 %r22, 0, %r21, %p5;
-; CHECK-NEXT:    selp.b32 %r23, 1, 0, %p5;
-; CHECK-NEXT:    add.s32 %r24, %r11, %r23;
-; CHECK-NEXT:    add.s32 %r25, %r24, -112;
-; CHECK-NEXT:    shl.b32 %r26, %r25, 2;
-; CHECK-NEXT:    or.b32 %r27, %r18, %r26;
-; CHECK-NEXT:    or.b32 %r28, %r27, %r22;
-; CHECK-NEXT:    setp.lt.s32 %p6, %r25, 1;
-; CHECK-NEXT:    selp.b32 %r29, %r20, %r28, %p6;
-; CHECK-NEXT:    setp.gt.s32 %p7, %r22, 3;
-; CHECK-NEXT:    or.b32 %r30, %r18, 124;
-; CHECK-NEXT:    selp.b32 %r31, %r30, %r29, %p7;
-; CHECK-NEXT:    setp.eq.b32 %p8, %r25, 30;
-; CHECK-NEXT:    selp.b32 %r32, %r31, %r29, %p8;
-; CHECK-NEXT:    setp.gt.s32 %p9, %r25, 30;
-; CHECK-NEXT:    selp.b32 %r33, %r30, %r32, %p9;
-; CHECK-NEXT:    or.b32 %r34, %r3, %r2;
-; CHECK-NEXT:    setp.eq.b32 %p10, %r34, 0;
-; CHECK-NEXT:    selp.b32 %r35, %r18, %r33, %p10;
-; CHECK-NEXT:    setp.eq.b32 %p11, %r2, 0;
-; CHECK-NEXT:    selp.b32 %r36, %r30, %r35, %p11;
-; CHECK-NEXT:    setp.eq.b32 %p12, %r3, 255;
-; CHECK-NEXT:    selp.b32 %r37, %r36, %r35, %p12;
-; CHECK-NEXT:    selp.b32 %r38, 126, %r37, %p1;
-; CHECK-NEXT:    selp.b32 %r39, %r38, %r37, %p12;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r39;
+; CHECK-NEXT:    mul.rn.f32 %r2, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r3, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r3, 8388608;
+; CHECK-NEXT:    selp.b32 %r4, %r2, %r1, %p1;
+; CHECK-NEXT:    add.s32 %r5, %r3, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r5, -2139095039;
+; CHECK-NEXT:    selp.f32 %r6, %r1, %r4, %p2;
+; CHECK-NEXT:    bfe.u32 %r7, %r6, 21, 2;
+; CHECK-NEXT:    setp.gt.s32 %p3, %r7, 3;
+; CHECK-NEXT:    selp.b32 %r8, 0, %r7, %p3;
+; CHECK-NEXT:    and.b32 %r9, %r2, 2139095040;
+; CHECK-NEXT:    selp.b32 %r10, %r9, %r3, %p1;
+; CHECK-NEXT:    shr.u32 %r11, %r10, 23;
+; CHECK-NEXT:    selp.b32 %r12, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r13, %r11, %r12;
+; CHECK-NEXT:    add.s32 %r14, %r13, -126;
+; CHECK-NEXT:    selp.b32 %r15, 0, %r14, %p2;
+; CHECK-NEXT:    selp.b32 %r16, 1, 0, %p3;
+; CHECK-NEXT:    add.s32 %r17, %r15, %r16;
+; CHECK-NEXT:    add.s32 %r18, %r17, 14;
+; CHECK-NEXT:    shl.b32 %r19, %r18, 2;
+; CHECK-NEXT:    shr.u32 %r20, %r1, 24;
+; CHECK-NEXT:    and.b32 %r21, %r20, 128;
+; CHECK-NEXT:    or.b32 %r22, %r21, %r19;
+; CHECK-NEXT:    or.b32 %r23, %r22, %r8;
+; CHECK-NEXT:    and.b32 %r24, %r6, 8388607;
+; CHECK-NEXT:    or.b32 %r25, %r24, 8388608;
+; CHECK-NEXT:    sub.s32 %r26, 8, %r15;
+; CHECK-NEXT:    min.u32 %r27, %r26, 31;
+; CHECK-NEXT:    shr.u32 %r28, %r25, %r27;
+; CHECK-NEXT:    setp.gt.s32 %p4, %r28, 3;
+; CHECK-NEXT:    selp.b32 %r29, 0, %r28, %p4;
+; CHECK-NEXT:    selp.b32 %r30, 4, 0, %p4;
+; CHECK-NEXT:    or.b32 %r31, %r21, %r30;
+; CHECK-NEXT:    or.b32 %r32, %r31, %r29;
+; CHECK-NEXT:    setp.lt.s32 %p5, %r18, 1;
+; CHECK-NEXT:    selp.b32 %r33, %r32, %r23, %p5;
+; CHECK-NEXT:    setp.gt.s32 %p6, %r8, 3;
+; CHECK-NEXT:    or.b32 %r34, %r21, 124;
+; CHECK-NEXT:    selp.b32 %r35, %r34, %r33, %p6;
+; CHECK-NEXT:    setp.eq.b32 %p7, %r18, 30;
+; CHECK-NEXT:    selp.b32 %r36, %r35, %r33, %p7;
+; CHECK-NEXT:    setp.gt.s32 %p8, %r18, 30;
+; CHECK-NEXT:    selp.b32 %r37, %r34, %r36, %p8;
+; CHECK-NEXT:    setp.eq.b32 %p9, %r3, 0;
+; CHECK-NEXT:    selp.b32 %r38, %r21, %r37, %p9;
+; CHECK-NEXT:    setp.eq.b32 %p10, %r3, 2139095040;
+; CHECK-NEXT:    selp.b32 %r39, %r34, %r38, %p10;
+; CHECK-NEXT:    setp.gt.s32 %p11, %r3, 2139095040;
+; CHECK-NEXT:    selp.b32 %r40, 126, %r39, %p11;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r40;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
   ret i8 %r
@@ -491,250 +177,262 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-LABEL: to_f4e2m1fn_v4f32(
 ; CHECK:       {
-; CHECK-NEXT:    .reg .pred %p<41>;
-; CHECK-NEXT:    .reg .b32 %r<202>;
+; CHECK-NEXT:    .reg .pred %p<37>;
+; CHECK-NEXT:    .reg .b32 %r<218>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.v4.b32 {%r1, %r2, %r3, %r4}, [to_f4e2m1fn_v4f32_param_0];
-; CHECK-NEXT:    and.b32 %r5, %r4, 8388607;
-; CHECK-NEXT:    setp.ne.b32 %p1, %r5, 0;
-; CHECK-NEXT:    bfe.u32 %r6, %r4, 23, 8;
-; CHECK-NEXT:    setp.eq.b32 %p2, %r6, 0;
-; CHECK-NEXT:    and.pred %p3, %p2, %p1;
-; CHECK-NEXT:    clz.b32 %r7, %r5;
-; CHECK-NEXT:    add.s32 %r8, %r7, -8;
-; CHECK-NEXT:    shl.b32 %r9, %r5, %r8;
-; CHECK-NEXT:    and.b32 %r10, %r9, 8388607;
-; CHECK-NEXT:    selp.b32 %r11, %r10, %r5, %p3;
-; CHECK-NEXT:    shr.u32 %r12, %r11, 22;
-; CHECK-NEXT:    and.b32 %r13, %r11, 2097151;
-; CHECK-NEXT:    setp.ne.b32 %p4, %r13, 0;
-; CHECK-NEXT:    selp.b32 %r14, 1, 0, %p4;
-; CHECK-NEXT:    or.b32 %r15, %r14, %r12;
-; CHECK-NEXT:    shr.u32 %r16, %r11, 21;
-; CHECK-NEXT:    and.b32 %r17, %r16, %r15;
-; CHECK-NEXT:    add.s32 %r18, %r12, %r17;
-; CHECK-NEXT:    setp.gt.s32 %p5, %r18, 1;
-; CHECK-NEXT:    selp.b32 %r19, 0, %r18, %p5;
-; CHECK-NEXT:    selp.b32 %r20, 1, 0, %p5;
-; CHECK-NEXT:    sub.s32 %r21, 9, %r7;
-; CHECK-NEXT:    selp.b32 %r22, %r21, %r6, %p3;
-; CHECK-NEXT:    add.s32 %r23, %r22, %r20;
-; CHECK-NEXT:    add.s32 %r24, %r23, -126;
-; CHECK-NEXT:    shl.b32 %r25, %r24, 1;
-; CHECK-NEXT:    shr.u32 %r26, %r4, 28;
-; CHECK-NEXT:    and.b32 %r27, %r26, 8;
-; CHECK-NEXT:    or.b32 %r28, %r27, %r25;
-; CHECK-NEXT:    or.b32 %r29, %r28, %r19;
-; CHECK-NEXT:    or.b32 %r30, %r11, 8388608;
-; CHECK-NEXT:    sub.s32 %r31, 149, %r22;
-; CHECK-NEXT:    min.u32 %r32, %r31, 31;
-; CHECK-NEXT:    shr.u32 %r33, %r30, %r32;
-; CHECK-NEXT:    and.b32 %r34, %r33, 1;
-; CHECK-NEXT:    max.u32 %r35, %r32, 1;
-; CHECK-NEXT:    add.s32 %r36, %r35, -1;
-; CHECK-NEXT:    mov.b32 %r37, 1;
-; CHECK-NEXT:    shl.b32 %r38, %r37, %r36;
-; CHECK-NEXT:    add.s32 %r39, %r38, -1;
-; CHECK-NEXT:    and.b32 %r40, %r30, %r39;
-; CHECK-NEXT:    setp.ne.b32 %p6, %r40, 0;
-; CHECK-NEXT:    selp.b32 %r41, 1, 0, %p6;
-; CHECK-NEXT:    or.b32 %r42, %r41, %r34;
-; CHECK-NEXT:    shr.u32 %r43, %r30, %r36;
-; CHECK-NEXT:    and.b32 %r44, %r43, %r42;
-; CHECK-NEXT:    setp.ne.b32 %p7, %r32, 0;
-; CHECK-NEXT:    selp.b32 %r45, %r44, 0, %p7;
-; CHECK-NEXT:    add.s32 %r46, %r33, %r45;
-; CHECK-NEXT:    setp.gt.s32 %p8, %r46, 1;
-; CHECK-NEXT:    selp.b32 %r47, 0, %r46, %p8;
-; CHECK-NEXT:    selp.b32 %r48, 2, 0, %p8;
-; CHECK-NEXT:    or.b32 %r49, %r27, %r48;
-; CHECK-NEXT:    or.b32 %r50, %r49, %r47;
-; CHECK-NEXT:    setp.lt.s32 %p9, %r24, 1;
-; CHECK-NEXT:    selp.b32 %r51, %r50, %r29, %p9;
-; CHECK-NEXT:    or.b32 %r52, %r6, %r5;
-; CHECK-NEXT:    setp.eq.b32 %p10, %r52, 0;
-; CHECK-NEXT:    selp.b32 %r53, %r27, %r51, %p10;
-; CHECK-NEXT:    and.b32 %r54, %r3, 8388607;
-; CHECK-NEXT:    setp.ne.b32 %p11, %r54, 0;
-; CHECK-NEXT:    bfe.u32 %r55, %r3, 23, 8;
-; CHECK-NEXT:    setp.eq.b32 %p12, %r55, 0;
-; CHECK-NEXT:    and.pred %p13, %p12, %p11;
-; CHECK-NEXT:    clz.b32 %r56, %r54;
-; CHECK-NEXT:    add.s32 %r57, %r56, -8;
-; CHECK-NEXT:    shl.b32 %r58, %r54, %r57;
-; CHECK-NEXT:    and.b32 %r59, %r58, 8388607;
-; CHECK-NEXT:    selp.b32 %r60, %r59, %r54, %p13;
-; CHECK-NEXT:    shr.u32 %r61, %r60, 22;
-; CHECK-NEXT:    and.b32 %r62, %r60, 2097151;
-; CHECK-NEXT:    setp.ne.b32 %p14, %r62, 0;
-; CHECK-NEXT:    selp.b32 %r63, 1, 0, %p14;
-; CHECK-NEXT:    or.b32 %r64, %r63, %r61;
-; CHECK-NEXT:    shr.u32 %r65, %r60, 21;
-; CHECK-NEXT:    and.b32 %r66, %r65, %r64;
-; CHECK-NEXT:    add.s32 %r67, %r61, %r66;
-; CHECK-NEXT:    setp.gt.s32 %p15, %r67, 1;
-; CHECK-NEXT:    selp.b32 %r68, 0, %r67, %p15;
-; CHECK-NEXT:    selp.b32 %r69, 1, 0, %p15;
-; CHECK-NEXT:    sub.s32 %r70, 9, %r56;
-; CHECK-NEXT:    selp.b32 %r71, %r70, %r55, %p13;
-; CHECK-NEXT:    add.s32 %r72, %r71, %r69;
-; CHECK-NEXT:    add.s32 %r73, %r72, -126;
-; CHECK-NEXT:    shl.b32 %r74, %r73, 1;
-; CHECK-NEXT:    shr.u32 %r75, %r3, 28;
-; CHECK-NEXT:    and.b32 %r76, %r75, 8;
-; CHECK-NEXT:    or.b32 %r77, %r76, %r74;
-; CHECK-NEXT:    or.b32 %r78, %r77, %r68;
-; CHECK-NEXT:    or.b32 %r79, %r60, 8388608;
-; CHECK-NEXT:    sub.s32 %r80, 149, %r71;
-; CHECK-NEXT:    min.u32 %r81, %r80, 31;
-; CHECK-NEXT:    shr.u32 %r82, %r79, %r81;
-; CHECK-NEXT:    and.b32 %r83, %r82, 1;
-; CHECK-NEXT:    max.u32 %r84, %r81, 1;
-; CHECK-NEXT:    add.s32 %r85, %r84, -1;
-; CHECK-NEXT:    shl.b32 %r86, %r37, %r85;
-; CHECK-NEXT:    add.s32 %r87, %r86, -1;
-; CHECK-NEXT:    and.b32 %r88, %r79, %r87;
-; CHECK-NEXT:    setp.ne.b32 %p16, %r88, 0;
-; CHECK-NEXT:    selp.b32 %r89, 1, 0, %p16;
-; CHECK-NEXT:    or.b32 %r90, %r89, %r83;
-; CHECK-NEXT:    shr.u32 %r91, %r79, %r85;
-; CHECK-NEXT:    and.b32 %r92, %r91, %r90;
-; CHECK-NEXT:    setp.ne.b32 %p17, %r81, 0;
-; CHECK-NEXT:    selp.b32 %r93, %r92, 0, %p17;
-; CHECK-NEXT:    add.s32 %r94, %r82, %r93;
-; CHECK-NEXT:    setp.gt.s32 %p18, %r94, 1;
-; CHECK-NEXT:    selp.b32 %r95, 0, %r94, %p18;
-; CHECK-NEXT:    selp.b32 %r96, 2, 0, %p18;
-; CHECK-NEXT:    or.b32 %r97, %r76, %r96;
+; CHECK-NEXT:    mul.rn.f32 %r5, %r4, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r6, %r4, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r6, 8388608;
+; CHECK-NEXT:    selp.b32 %r7, %r5, %r4, %p1;
+; CHECK-NEXT:    and.b32 %r8, %r7, -2139095041;
+; CHECK-NEXT:    or.b32 %r9, %r8, 1056964608;
+; CHECK-NEXT:    add.s32 %r10, %r6, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r10, -2139095039;
+; CHECK-NEXT:    selp.f32 %r11, %r4, %r9, %p2;
+; CHECK-NEXT:    and.b32 %r12, %r11, 8388607;
+; CHECK-NEXT:    or.b32 %r13, %r12, 8388608;
+; CHECK-NEXT:    and.b32 %r14, %r5, 2139095040;
+; CHECK-NEXT:    selp.b32 %r15, %r14, %r6, %p1;
+; CHECK-NEXT:    shr.u32 %r16, %r15, 23;
+; CHECK-NEXT:    selp.b32 %r17, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r18, %r16, %r17;
+; CHECK-NEXT:    add.s32 %r19, %r18, -126;
+; CHECK-NEXT:    selp.b32 %r20, 0, %r19, %p2;
+; CHECK-NEXT:    sub.s32 %r21, 23, %r20;
+; CHECK-NEXT:    min.u32 %r22, %r21, 31;
+; CHECK-NEXT:    shr.u32 %r23, %r13, %r22;
+; CHECK-NEXT:    and.b32 %r24, %r23, 1;
+; CHECK-NEXT:    max.u32 %r25, %r22, 1;
+; CHECK-NEXT:    add.s32 %r26, %r25, -1;
+; CHECK-NEXT:    mov.b32 %r27, 1;
+; CHECK-NEXT:    shl.b32 %r28, %r27, %r26;
+; CHECK-NEXT:    add.s32 %r29, %r28, -1;
+; CHECK-NEXT:    and.b32 %r30, %r13, %r29;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r30, 0;
+; CHECK-NEXT:    selp.b32 %r31, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r32, %r31, %r24;
+; CHECK-NEXT:    shr.u32 %r33, %r13, %r26;
+; CHECK-NEXT:    and.b32 %r34, %r33, %r32;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r22, 0;
+; CHECK-NEXT:    selp.b32 %r35, %r34, 0, %p4;
+; CHECK-NEXT:    add.s32 %r36, %r23, %r35;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r36, 1;
+; CHECK-NEXT:    selp.b32 %r37, 0, %r36, %p5;
+; CHECK-NEXT:    selp.b32 %r38, 2, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r39, %r4, 28;
+; CHECK-NEXT:    and.b32 %r40, %r39, 8;
+; CHECK-NEXT:    or.b32 %r41, %r40, %r38;
+; CHECK-NEXT:    or.b32 %r42, %r41, %r37;
+; CHECK-NEXT:    bfe.u32 %r43, %r11, 22, 1;
+; CHECK-NEXT:    and.b32 %r44, %r11, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r44, 0;
+; CHECK-NEXT:    selp.b32 %r45, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r46, %r45, %r43;
+; CHECK-NEXT:    shr.u32 %r47, %r11, 21;
+; CHECK-NEXT:    and.b32 %r48, %r47, %r46;
+; CHECK-NEXT:    add.s32 %r49, %r43, %r48;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r49, 1;
+; CHECK-NEXT:    selp.b32 %r50, 0, %r49, %p7;
+; CHECK-NEXT:    selp.b32 %r51, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r52, %r20, %r51;
+; CHECK-NEXT:    shl.b32 %r53, %r52, 1;
+; CHECK-NEXT:    or.b32 %r54, %r40, %r53;
+; CHECK-NEXT:    or.b32 %r55, %r54, %r50;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r52, 1;
+; CHECK-NEXT:    selp.b32 %r56, %r42, %r55, %p8;
+; CHECK-NEXT:    setp.eq.b32 %p9, %r6, 0;
+; CHECK-NEXT:    selp.b32 %r57, %r40, %r56, %p9;
+; CHECK-NEXT:    mul.rn.f32 %r58, %r3, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r59, %r3, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p10, %r59, 8388608;
+; CHECK-NEXT:    selp.b32 %r60, %r58, %r3, %p10;
+; CHECK-NEXT:    and.b32 %r61, %r60, -2139095041;
+; CHECK-NEXT:    or.b32 %r62, %r61, 1056964608;
+; CHECK-NEXT:    add.s32 %r63, %r59, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p11, %r63, -2139095039;
+; CHECK-NEXT:    selp.f32 %r64, %r3, %r62, %p11;
+; CHECK-NEXT:    and.b32 %r65, %r64, 8388607;
+; CHECK-NEXT:    or.b32 %r66, %r65, 8388608;
+; CHECK-NEXT:    and.b32 %r67, %r58, 2139095040;
+; CHECK-NEXT:    selp.b32 %r68, %r67, %r59, %p10;
+; CHECK-NEXT:    shr.u32 %r69, %r68, 23;
+; CHECK-NEXT:    selp.b32 %r70, -25, 0, %p10;
+; CHECK-NEXT:    add.s32 %r71, %r69, %r70;
+; CHECK-NEXT:    add.s32 %r72, %r71, -126;
+; CHECK-NEXT:    selp.b32 %r73, 0, %r72, %p11;
+; CHECK-NEXT:    sub.s32 %r74, 23, %r73;
+; CHECK-NEXT:    min.u32 %r75, %r74, 31;
+; CHECK-NEXT:    shr.u32 %r76, %r66, %r75;
+; CHECK-NEXT:    and.b32 %r77, %r76, 1;
+; CHECK-NEXT:    max.u32 %r78, %r75, 1;
+; CHECK-NEXT:    add.s32 %r79, %r78, -1;
+; CHECK-NEXT:    shl.b32 %r80, %r27, %r79;
+; CHECK-NEXT:    add.s32 %r81, %r80, -1;
+; CHECK-NEXT:    and.b32 %r82, %r66, %r81;
+; CHECK-NEXT:    setp.ne.b32 %p12, %r82, 0;
+; CHECK-NEXT:    selp.b32 %r83, 1, 0, %p12;
+; CHECK-NEXT:    or.b32 %r84, %r83, %r77;
+; CHECK-NEXT:    shr.u32 %r85, %r66, %r79;
+; CHECK-NEXT:    and.b32 %r86, %r85, %r84;
+; CHECK-NEXT:    setp.ne.b32 %p13, %r75, 0;
+; CHECK-NEXT:    selp.b32 %r87, %r86, 0, %p13;
+; CHECK-NEXT:    add.s32 %r88, %r76, %r87;
+; CHECK-NEXT:    setp.gt.s32 %p14, %r88, 1;
+; CHECK-NEXT:    selp.b32 %r89, 0, %r88, %p14;
+; CHECK-NEXT:    selp.b32 %r90, 2, 0, %p14;
+; CHECK-NEXT:    shr.u32 %r91, %r3, 28;
+; CHECK-NEXT:    and.b32 %r92, %r91, 8;
+; CHECK-NEXT:    or.b32 %r93, %r92, %r90;
+; CHECK-NEXT:    or.b32 %r94, %r93, %r89;
+; CHECK-NEXT:    bfe.u32 %r95, %r64, 22, 1;
+; CHECK-NEXT:    and.b32 %r96, %r64, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p15, %r96, 0;
+; CHECK-NEXT:    selp.b32 %r97, 1, 0, %p15;
 ; CHECK-NEXT:    or.b32 %r98, %r97, %r95;
-; CHECK-NEXT:    setp.lt.s32 %p19, %r73, 1;
-; CHECK-NEXT:    selp.b32 %r99, %r98, %r78, %p19;
-; CHECK-NEXT:    or.b32 %r100, %r55, %r54;
-; CHECK-NEXT:    setp.eq.b32 %p20, %r100, 0;
-; CHECK-NEXT:    selp.b32 %r101, %r76, %r99, %p20;
-; CHECK-NEXT:    prmt.b32 %r102, %r101, %r53, 0x3340U;
-; CHECK-NEXT:    and.b32 %r103, %r2, 8388607;
-; CHECK-NEXT:    setp.ne.b32 %p21, %r103, 0;
-; CHECK-NEXT:    bfe.u32 %r104, %r2, 23, 8;
-; CHECK-NEXT:    setp.eq.b32 %p22, %r104, 0;
-; CHECK-NEXT:    and.pred %p23, %p22, %p21;
-; CHECK-NEXT:    clz.b32 %r105, %r103;
-; CHECK-NEXT:    add.s32 %r106, %r105, -8;
-; CHECK-NEXT:    shl.b32 %r107, %r103, %r106;
-; CHECK-NEXT:    and.b32 %r108, %r107, 8388607;
-; CHECK-NEXT:    selp.b32 %r109, %r108, %r103, %p23;
-; CHECK-NEXT:    shr.u32 %r110, %r109, 22;
-; CHECK-NEXT:    and.b32 %r111, %r109, 2097151;
-; CHECK-NEXT:    setp.ne.b32 %p24, %r111, 0;
-; CHECK-NEXT:    selp.b32 %r112, 1, 0, %p24;
-; CHECK-NEXT:    or.b32 %r113, %r112, %r110;
-; CHECK-NEXT:    shr.u32 %r114, %r109, 21;
-; CHECK-NEXT:    and.b32 %r115, %r114, %r113;
-; CHECK-NEXT:    add.s32 %r116, %r110, %r115;
-; CHECK-NEXT:    setp.gt.s32 %p25, %r116, 1;
-; CHECK-NEXT:    selp.b32 %r117, 0, %r116, %p25;
-; CHECK-NEXT:    selp.b32 %r118, 1, 0, %p25;
-; CHECK-NEXT:    sub.s32 %r119, 9, %r105;
-; CHECK-NEXT:    selp.b32 %r120, %r119, %r104, %p23;
-; CHECK-NEXT:    add.s32 %r121, %r120, %r118;
-; CHECK-NEXT:    add.s32 %r122, %r121, -126;
-; CHECK-NEXT:    shl.b32 %r123, %r122, 1;
-; CHECK-NEXT:    shr.u32 %r124, %r2, 28;
-; CHECK-NEXT:    and.b32 %r125, %r124, 8;
-; CHECK-NEXT:    or.b32 %r126, %r125, %r123;
-; CHECK-NEXT:    or.b32 %r127, %r126, %r117;
-; CHECK-NEXT:    or.b32 %r128, %r109, 8388608;
-; CHECK-NEXT:    sub.s32 %r129, 149, %r120;
-; CHECK-NEXT:    min.u32 %r130, %r129, 31;
-; CHECK-NEXT:    shr.u32 %r131, %r128, %r130;
-; CHECK-NEXT:    and.b32 %r132, %r131, 1;
-; CHECK-NEXT:    max.u32 %r133, %r130, 1;
+; CHECK-NEXT:    shr.u32 %r99, %r64, 21;
+; CHECK-NEXT:    and.b32 %r100, %r99, %r98;
+; CHECK-NEXT:    add.s32 %r101, %r95, %r100;
+; CHECK-NEXT:    setp.gt.s32 %p16, %r101, 1;
+; CHECK-NEXT:    selp.b32 %r102, 0, %r101, %p16;
+; CHECK-NEXT:    selp.b32 %r103, 1, 0, %p16;
+; CHECK-NEXT:    add.s32 %r104, %r73, %r103;
+; CHECK-NEXT:    shl.b32 %r105, %r104, 1;
+; CHECK-NEXT:    or.b32 %r106, %r92, %r105;
+; CHECK-NEXT:    or.b32 %r107, %r106, %r102;
+; CHECK-NEXT:    setp.lt.s32 %p17, %r104, 1;
+; CHECK-NEXT:    selp.b32 %r108, %r94, %r107, %p17;
+; CHECK-NEXT:    setp.eq.b32 %p18, %r59, 0;
+; CHECK-NEXT:    selp.b32 %r109, %r92, %r108, %p18;
+; CHECK-NEXT:    prmt.b32 %r110, %r109, %r57, 0x3340U;
+; CHECK-NEXT:    mul.rn.f32 %r111, %r2, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r112, %r2, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p19, %r112, 8388608;
+; CHECK-NEXT:    selp.b32 %r113, %r111, %r2, %p19;
+; CHECK-NEXT:    and.b32 %r114, %r113, -2139095041;
+; CHECK-NEXT:    or.b32 %r115, %r114, 1056964608;
+; CHECK-NEXT:    add.s32 %r116, %r112, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p20, %r116, -2139095039;
+; CHECK-NEXT:    selp.f32 %r117, %r2, %r115, %p20;
+; CHECK-NEXT:    and.b32 %r118, %r117, 8388607;
+; CHECK-NEXT:    or.b32 %r119, %r118, 8388608;
+; CHECK-NEXT:    and.b32 %r120, %r111, 2139095040;
+; CHECK-NEXT:    selp.b32 %r121, %r120, %r112, %p19;
+; CHECK-NEXT:    shr.u32 %r122, %r121, 23;
+; CHECK-NEXT:    selp.b32 %r123, -25, 0, %p19;
+; CHECK-NEXT:    add.s32 %r124, %r122, %r123;
+; CHECK-NEXT:    add.s32 %r125, %r124, -126;
+; CHECK-NEXT:    selp.b32 %r126, 0, %r125, %p20;
+; CHECK-NEXT:    sub.s32 %r127, 23, %r126;
+; CHECK-NEXT:    min.u32 %r128, %r127, 31;
+; CHECK-NEXT:    shr.u32 %r129, %r119, %r128;
+; CHECK-NEXT:    and.b32 %r130, %r129, 1;
+; CHECK-NEXT:    max.u32 %r131, %r128, 1;
+; CHECK-NEXT:    add.s32 %r132, %r131, -1;
+; CHECK-NEXT:    shl.b32 %r133, %r27, %r132;
 ; CHECK-NEXT:    add.s32 %r134, %r133, -1;
-; CHECK-NEXT:    shl.b32 %r135, %r37, %r134;
-; CHECK-NEXT:    add.s32 %r136, %r135, -1;
-; CHECK-NEXT:    and.b32 %r137, %r128, %r136;
-; CHECK-NEXT:    setp.ne.b32 %p26, %r137, 0;
-; CHECK-NEXT:    selp.b32 %r138, 1, 0, %p26;
-; CHECK-NEXT:    or.b32 %r139, %r138, %r132;
-; CHECK-NEXT:    shr.u32 %r140, %r128, %r134;
-; CHECK-NEXT:    and.b32 %r141, %r140, %r139;
-; CHECK-NEXT:    setp.ne.b32 %p27, %r130, 0;
-; CHECK-NEXT:    selp.b32 %r142, %r141, 0, %p27;
-; CHECK-NEXT:    add.s32 %r143, %r131, %r142;
-; CHECK-NEXT:    setp.gt.s32 %p28, %r143, 1;
-; CHECK-NEXT:    selp.b32 %r144, 0, %r143, %p28;
-; CHECK-NEXT:    selp.b32 %r145, 2, 0, %p28;
-; CHECK-NEXT:    or.b32 %r146, %r125, %r145;
-; CHECK-NEXT:    or.b32 %r147, %r146, %r144;
-; CHECK-NEXT:    setp.lt.s32 %p29, %r122, 1;
-; CHECK-NEXT:    selp.b32 %r148, %r147, %r127, %p29;
-; CHECK-NEXT:    or.b32 %r149, %r104, %r103;
-; CHECK-NEXT:    setp.eq.b32 %p30, %r149, 0;
-; CHECK-NEXT:    selp.b32 %r150, %r125, %r148, %p30;
-; CHECK-NEXT:    and.b32 %r151, %r1, 8388607;
-; CHECK-NEXT:    setp.ne.b32 %p31, %r151, 0;
-; CHECK-NEXT:    bfe.u32 %r152, %r1, 23, 8;
-; CHECK-NEXT:    setp.eq.b32 %p32, %r152, 0;
-; CHECK-NEXT:    and.pred %p33, %p32, %p31;
-; CHECK-NEXT:    clz.b32 %r153, %r151;
-; CHECK-NEXT:    add.s32 %r154, %r153, -8;
-; CHECK-NEXT:    shl.b32 %r155, %r151, %r154;
-; CHECK-NEXT:    and.b32 %r156, %r155, 8388607;
-; CHECK-NEXT:    selp.b32 %r157, %r156, %r151, %p33;
-; CHECK-NEXT:    shr.u32 %r158, %r157, 22;
-; CHECK-NEXT:    and.b32 %r159, %r157, 2097151;
-; CHECK-NEXT:    setp.ne.b32 %p34, %r159, 0;
-; CHECK-NEXT:    selp.b32 %r160, 1, 0, %p34;
-; CHECK-NEXT:    or.b32 %r161, %r160, %r158;
-; CHECK-NEXT:    shr.u32 %r162, %r157, 21;
-; CHECK-NEXT:    and.b32 %r163, %r162, %r161;
-; CHECK-NEXT:    add.s32 %r164, %r158, %r163;
-; CHECK-NEXT:    setp.gt.s32 %p35, %r164, 1;
-; CHECK-NEXT:    selp.b32 %r165, 0, %r164, %p35;
-; CHECK-NEXT:    selp.b32 %r166, 1, 0, %p35;
-; CHECK-NEXT:    sub.s32 %r167, 9, %r153;
-; CHECK-NEXT:    selp.b32 %r168, %r167, %r152, %p33;
-; CHECK-NEXT:    add.s32 %r169, %r168, %r166;
-; CHECK-NEXT:    add.s32 %r170, %r169, -126;
-; CHECK-NEXT:    shl.b32 %r171, %r170, 1;
-; CHECK-NEXT:    shr.u32 %r172, %r1, 28;
-; CHECK-NEXT:    and.b32 %r173, %r172, 8;
-; CHECK-NEXT:    or.b32 %r174, %r173, %r171;
-; CHECK-NEXT:    or.b32 %r175, %r174, %r165;
-; CHECK-NEXT:    or.b32 %r176, %r157, 8388608;
-; CHECK-NEXT:    sub.s32 %r177, 149, %r168;
-; CHECK-NEXT:    min.u32 %r178, %r177, 31;
-; CHECK-NEXT:    shr.u32 %r179, %r176, %r178;
-; CHECK-NEXT:    and.b32 %r180, %r179, 1;
-; CHECK-NEXT:    max.u32 %r181, %r178, 1;
-; CHECK-NEXT:    add.s32 %r182, %r181, -1;
-; CHECK-NEXT:    shl.b32 %r183, %r37, %r182;
+; CHECK-NEXT:    and.b32 %r135, %r119, %r134;
+; CHECK-NEXT:    setp.ne.b32 %p21, %r135, 0;
+; CHECK-NEXT:    selp.b32 %r136, 1, 0, %p21;
+; CHECK-NEXT:    or.b32 %r137, %r136, %r130;
+; CHECK-NEXT:    shr.u32 %r138, %r119, %r132;
+; CHECK-NEXT:    and.b32 %r139, %r138, %r137;
+; CHECK-NEXT:    setp.ne.b32 %p22, %r128, 0;
+; CHECK-NEXT:    selp.b32 %r140, %r139, 0, %p22;
+; CHECK-NEXT:    add.s32 %r141, %r129, %r140;
+; CHECK-NEXT:    setp.gt.s32 %p23, %r141, 1;
+; CHECK-NEXT:    selp.b32 %r142, 0, %r141, %p23;
+; CHECK-NEXT:    selp.b32 %r143, 2, 0, %p23;
+; CHECK-NEXT:    shr.u32 %r144, %r2, 28;
+; CHECK-NEXT:    and.b32 %r145, %r144, 8;
+; CHECK-NEXT:    or.b32 %r146, %r145, %r143;
+; CHECK-NEXT:    or.b32 %r147, %r146, %r142;
+; CHECK-NEXT:    bfe.u32 %r148, %r117, 22, 1;
+; CHECK-NEXT:    and.b32 %r149, %r117, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p24, %r149, 0;
+; CHECK-NEXT:    selp.b32 %r150, 1, 0, %p24;
+; CHECK-NEXT:    or.b32 %r151, %r150, %r148;
+; CHECK-NEXT:    shr.u32 %r152, %r117, 21;
+; CHECK-NEXT:    and.b32 %r153, %r152, %r151;
+; CHECK-NEXT:    add.s32 %r154, %r148, %r153;
+; CHECK-NEXT:    setp.gt.s32 %p25, %r154, 1;
+; CHECK-NEXT:    selp.b32 %r155, 0, %r154, %p25;
+; CHECK-NEXT:    selp.b32 %r156, 1, 0, %p25;
+; CHECK-NEXT:    add.s32 %r157, %r126, %r156;
+; CHECK-NEXT:    shl.b32 %r158, %r157, 1;
+; CHECK-NEXT:    or.b32 %r159, %r145, %r158;
+; CHECK-NEXT:    or.b32 %r160, %r159, %r155;
+; CHECK-NEXT:    setp.lt.s32 %p26, %r157, 1;
+; CHECK-NEXT:    selp.b32 %r161, %r147, %r160, %p26;
+; CHECK-NEXT:    setp.eq.b32 %p27, %r112, 0;
+; CHECK-NEXT:    selp.b32 %r162, %r145, %r161, %p27;
+; CHECK-NEXT:    mul.rn.f32 %r163, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r164, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p28, %r164, 8388608;
+; CHECK-NEXT:    selp.b32 %r165, %r163, %r1, %p28;
+; CHECK-NEXT:    and.b32 %r166, %r165, -2139095041;
+; CHECK-NEXT:    or.b32 %r167, %r166, 1056964608;
+; CHECK-NEXT:    add.s32 %r168, %r164, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p29, %r168, -2139095039;
+; CHECK-NEXT:    selp.f32 %r169, %r1, %r167, %p29;
+; CHECK-NEXT:    and.b32 %r170, %r169, 8388607;
+; CHECK-NEXT:    or.b32 %r171, %r170, 8388608;
+; CHECK-NEXT:    and.b32 %r172, %r163, 2139095040;
+; CHECK-NEXT:    selp.b32 %r173, %r172, %r164, %p28;
+; CHECK-NEXT:    shr.u32 %r174, %r173, 23;
+; CHECK-NEXT:    selp.b32 %r175, -25, 0, %p28;
+; CHECK-NEXT:    add.s32 %r176, %r174, %r175;
+; CHECK-NEXT:    add.s32 %r177, %r176, -126;
+; CHECK-NEXT:    selp.b32 %r178, 0, %r177, %p29;
+; CHECK-NEXT:    sub.s32 %r179, 23, %r178;
+; CHECK-NEXT:    min.u32 %r180, %r179, 31;
+; CHECK-NEXT:    shr.u32 %r181, %r171, %r180;
+; CHECK-NEXT:    and.b32 %r182, %r181, 1;
+; CHECK-NEXT:    max.u32 %r183, %r180, 1;
 ; CHECK-NEXT:    add.s32 %r184, %r183, -1;
-; CHECK-NEXT:    and.b32 %r185, %r176, %r184;
-; CHECK-NEXT:    setp.ne.b32 %p36, %r185, 0;
-; CHECK-NEXT:    selp.b32 %r186, 1, 0, %p36;
-; CHECK-NEXT:    or.b32 %r187, %r186, %r180;
-; CHECK-NEXT:    shr.u32 %r188, %r176, %r182;
-; CHECK-NEXT:    and.b32 %r189, %r188, %r187;
-; CHECK-NEXT:    setp.ne.b32 %p37, %r178, 0;
-; CHECK-NEXT:    selp.b32 %r190, %r189, 0, %p37;
-; CHECK-NEXT:    add.s32 %r191, %r179, %r190;
-; CHECK-NEXT:    setp.gt.s32 %p38, %r191, 1;
-; CHECK-NEXT:    selp.b32 %r192, 0, %r191, %p38;
-; CHECK-NEXT:    selp.b32 %r193, 2, 0, %p38;
-; CHECK-NEXT:    or.b32 %r194, %r173, %r193;
-; CHECK-NEXT:    or.b32 %r195, %r194, %r192;
-; CHECK-NEXT:    setp.lt.s32 %p39, %r170, 1;
-; CHECK-NEXT:    selp.b32 %r196, %r195, %r175, %p39;
-; CHECK-NEXT:    or.b32 %r197, %r152, %r151;
-; CHECK-NEXT:    setp.eq.b32 %p40, %r197, 0;
-; CHECK-NEXT:    selp.b32 %r198, %r173, %r196, %p40;
-; CHECK-NEXT:    prmt.b32 %r199, %r198, %r150, 0x3340U;
-; CHECK-NEXT:    prmt.b32 %r200, %r199, %r102, 0x5410U;
-; CHECK-NEXT:    st.param.b16 [func_retval0], %r200;
-; CHECK-NEXT:    shr.u32 %r201, %r200, 16;
-; CHECK-NEXT:    st.param.b16 [func_retval0+2], %r201;
+; CHECK-NEXT:    shl.b32 %r185, %r27, %r184;
+; CHECK-NEXT:    add.s32 %r186, %r185, -1;
+; CHECK-NEXT:    and.b32 %r187, %r171, %r186;
+; CHECK-NEXT:    setp.ne.b32 %p30, %r187, 0;
+; CHECK-NEXT:    selp.b32 %r188, 1, 0, %p30;
+; CHECK-NEXT:    or.b32 %r189, %r188, %r182;
+; CHECK-NEXT:    shr.u32 %r190, %r171, %r184;
+; CHECK-NEXT:    and.b32 %r191, %r190, %r189;
+; CHECK-NEXT:    setp.ne.b32 %p31, %r180, 0;
+; CHECK-NEXT:    selp.b32 %r192, %r191, 0, %p31;
+; CHECK-NEXT:    add.s32 %r193, %r181, %r192;
+; CHECK-NEXT:    setp.gt.s32 %p32, %r193, 1;
+; CHECK-NEXT:    selp.b32 %r194, 0, %r193, %p32;
+; CHECK-NEXT:    selp.b32 %r195, 2, 0, %p32;
+; CHECK-NEXT:    shr.u32 %r196, %r1, 28;
+; CHECK-NEXT:    and.b32 %r197, %r196, 8;
+; CHECK-NEXT:    or.b32 %r198, %r197, %r195;
+; CHECK-NEXT:    or.b32 %r199, %r198, %r194;
+; CHECK-NEXT:    bfe.u32 %r200, %r169, 22, 1;
+; CHECK-NEXT:    and.b32 %r201, %r169, 2097151;
+; CHECK-NEXT:    setp.ne.b32 %p33, %r201, 0;
+; CHECK-NEXT:    selp.b32 %r202, 1, 0, %p33;
+; CHECK-NEXT:    or.b32 %r203, %r202, %r200;
+; CHECK-NEXT:    shr.u32 %r204, %r169, 21;
+; CHECK-NEXT:    and.b32 %r205, %r204, %r203;
+; CHECK-NEXT:    add.s32 %r206, %r200, %r205;
+; CHECK-NEXT:    setp.gt.s32 %p34, %r206, 1;
+; CHECK-NEXT:    selp.b32 %r207, 0, %r206, %p34;
+; CHECK-NEXT:    selp.b32 %r208, 1, 0, %p34;
+; CHECK-NEXT:    add.s32 %r209, %r178, %r208;
+; CHECK-NEXT:    shl.b32 %r210, %r209, 1;
+; CHECK-NEXT:    or.b32 %r211, %r197, %r210;
+; CHECK-NEXT:    or.b32 %r212, %r211, %r207;
+; CHECK-NEXT:    setp.lt.s32 %p35, %r209, 1;
+; CHECK-NEXT:    selp.b32 %r213, %r199, %r212, %p35;
+; CHECK-NEXT:    setp.eq.b32 %p36, %r164, 0;
+; CHECK-NEXT:    selp.b32 %r214, %r197, %r213, %p36;
+; CHECK-NEXT:    prmt.b32 %r215, %r214, %r162, 0x3340U;
+; CHECK-NEXT:    prmt.b32 %r216, %r215, %r110, 0x5410U;
+; CHECK-NEXT:    st.param.b16 [func_retval0], %r216;
+; CHECK-NEXT:    shr.u32 %r217, %r216, 16;
+; CHECK-NEXT:    st.param.b16 [func_retval0+2], %r217;
 ; CHECK-NEXT:    ret;
   %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
   ret <4 x i4> %r
@@ -744,93 +442,94 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f16(
 ; CHECK:       {
-; CHECK-NEXT:    .reg .pred %p<16>;
-; CHECK-NEXT:    .reg .b16 %rs<60>;
-; CHECK-NEXT:    .reg .b32 %r<8>;
+; CHECK-NEXT:    .reg .pred %p<15>;
+; CHECK-NEXT:    .reg .b16 %rs<61>;
+; CHECK-NEXT:    .reg .b32 %r<9>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b16 %rs1, [to_f8e5m2_from_f16_param_0];
-; CHECK-NEXT:    and.b16 %rs2, %rs1, 1023;
-; CHECK-NEXT:    setp.ne.b16 %p1, %rs2, 0;
-; CHECK-NEXT:    shr.u16 %rs3, %rs1, 10;
-; CHECK-NEXT:    and.b16 %rs4, %rs3, 31;
-; CHECK-NEXT:    setp.eq.b16 %p2, %rs4, 0;
-; CHECK-NEXT:    and.pred %p3, %p2, %p1;
-; CHECK-NEXT:    cvt.u32.u16 %r1, %rs2;
-; CHECK-NEXT:    shl.b32 %r2, %r1, 16;
-; CHECK-NEXT:    clz.b32 %r3, %r2;
-; CHECK-NEXT:    cvt.u16.u32 %rs5, %r3;
-; CHECK-NEXT:    add.s16 %rs6, %rs5, -5;
-; CHECK-NEXT:    cvt.u32.u16 %r4, %rs6;
-; CHECK-NEXT:    shl.b16 %rs7, %rs2, %r4;
-; CHECK-NEXT:    and.b16 %rs8, %rs7, 1023;
-; CHECK-NEXT:    selp.b16 %rs9, %rs8, %rs2, %p3;
-; CHECK-NEXT:    shr.u16 %rs10, %rs9, 8;
-; CHECK-NEXT:    and.b16 %rs11, %rs10, 1;
-; CHECK-NEXT:    and.b16 %rs12, %rs9, 127;
-; CHECK-NEXT:    setp.ne.b16 %p4, %rs12, 0;
-; CHECK-NEXT:    selp.b16 %rs13, 1, 0, %p4;
-; CHECK-NEXT:    or.b16 %rs14, %rs13, %rs11;
-; CHECK-NEXT:    shr.u16 %rs15, %rs9, 7;
-; CHECK-NEXT:    and.b16 %rs16, %rs15, %rs14;
-; CHECK-NEXT:    add.s16 %rs17, %rs10, %rs16;
-; CHECK-NEXT:    setp.gt.s16 %p5, %rs17, 3;
-; CHECK-NEXT:    selp.b16 %rs18, 0, %rs17, %p5;
-; CHECK-NEXT:    selp.b16 %rs19, 1, 0, %p5;
-; CHECK-NEXT:    sub.s16 %rs20, 6, %rs5;
-; CHECK-NEXT:    selp.b16 %rs21, %rs20, %rs4, %p3;
-; CHECK-NEXT:    add.s16 %rs22, %rs21, %rs19;
-; CHECK-NEXT:    shl.b16 %rs23, %rs22, 2;
-; CHECK-NEXT:    shr.u16 %rs24, %rs1, 8;
-; CHECK-NEXT:    and.b16 %rs25, %rs24, 128;
-; CHECK-NEXT:    or.b16 %rs26, %rs25, %rs23;
-; CHECK-NEXT:    or.b16 %rs27, %rs26, %rs18;
-; CHECK-NEXT:    or.b16 %rs28, %rs9, 1024;
-; CHECK-NEXT:    sub.s16 %rs29, 9, %rs21;
-; CHECK-NEXT:    min.u16 %rs30, %rs29, 15;
-; CHECK-NEXT:    cvt.u32.u16 %r5, %rs30;
-; CHECK-NEXT:    shr.u16 %rs31, %rs28, %r5;
-; CHECK-NEXT:    and.b16 %rs32, %rs31, 1;
-; CHECK-NEXT:    max.u16 %rs33, %rs30, 1;
-; CHECK-NEXT:    add.s16 %rs34, %rs33, -1;
-; CHECK-NEXT:    cvt.u32.u16 %r6, %rs34;
-; CHECK-NEXT:    mov.b16 %rs35, 1;
-; CHECK-NEXT:    shl.b16 %rs36, %rs35, %r6;
-; CHECK-NEXT:    add.s16 %rs37, %rs36, -1;
-; CHECK-NEXT:    and.b16 %rs38, %rs28, %rs37;
-; CHECK-NEXT:    setp.ne.b16 %p6, %rs38, 0;
-; CHECK-NEXT:    selp.b16 %rs39, 1, 0, %p6;
-; CHECK-NEXT:    or.b16 %rs40, %rs39, %rs32;
-; CHECK-NEXT:    shr.u16 %rs41, %rs28, %r6;
-; CHECK-NEXT:    and.b16 %rs42, %rs41, %rs40;
-; CHECK-NEXT:    setp.ne.b16 %p7, %rs30, 0;
-; CHECK-NEXT:    selp.b16 %rs43, %rs42, 0, %p7;
-; CHECK-NEXT:    add.s16 %rs44, %rs31, %rs43;
-; CHECK-NEXT:    setp.gt.s16 %p8, %rs44, 3;
-; CHECK-NEXT:    selp.b16 %rs45, 0, %rs44, %p8;
-; CHECK-NEXT:    selp.b16 %rs46, 4, 0, %p8;
-; CHECK-NEXT:    or.b16 %rs47, %rs25, %rs46;
-; CHECK-NEXT:    or.b16 %rs48, %rs47, %rs45;
-; CHECK-NEXT:    setp.lt.s16 %p9, %rs22, 1;
-; CHECK-NEXT:    selp.b16 %rs49, %rs48, %rs27, %p9;
-; CHECK-NEXT:    setp.gt.s16 %p10, %rs18, 3;
-; CHECK-NEXT:    or.b16 %rs50, %rs25, 124;
-; CHECK-NEXT:    selp.b16 %rs51, %rs50, %rs49, %p10;
-; CHECK-NEXT:    setp.eq.b16 %p11, %rs22, 30;
-; CHECK-NEXT:    selp.b16 %rs52, %rs51, %rs49, %p11;
-; CHECK-NEXT:    setp.gt.s16 %p12, %rs22, 30;
-; CHECK-NEXT:    selp.b16 %rs53, %rs50, %rs52, %p12;
-; CHECK-NEXT:    or.b16 %rs54, %rs4, %rs2;
-; CHECK-NEXT:    setp.eq.b16 %p13, %rs54, 0;
-; CHECK-NEXT:    selp.b16 %rs55, %rs25, %rs53, %p13;
-; CHECK-NEXT:    setp.eq.b16 %p14, %rs2, 0;
-; CHECK-NEXT:    selp.b16 %rs56, %rs50, %rs55, %p14;
-; CHECK-NEXT:    setp.eq.b16 %p15, %rs4, 31;
-; CHECK-NEXT:    selp.b16 %rs57, %rs56, %rs55, %p15;
-; CHECK-NEXT:    selp.b16 %rs58, 126, %rs57, %p1;
-; CHECK-NEXT:    selp.b16 %rs59, %rs58, %rs57, %p15;
-; CHECK-NEXT:    cvt.u32.u16 %r7, %rs59;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r7;
+; CHECK-NEXT:    mov.b16 %rs2, 0x6C00;
+; CHECK-NEXT:    mul.rn.f16 %rs3, %rs1, %rs2;
+; CHECK-NEXT:    and.b16 %rs4, %rs1, 32767;
+; CHECK-NEXT:    setp.lt.u16 %p1, %rs4, 1024;
+; CHECK-NEXT:    selp.b16 %rs5, %rs3, %rs1, %p1;
+; CHECK-NEXT:    and.b16 %rs6, %rs5, -31745;
+; CHECK-NEXT:    or.b16 %rs7, %rs6, 14336;
+; CHECK-NEXT:    add.s16 %rs8, %rs4, -31744;
+; CHECK-NEXT:    setp.lt.u16 %p2, %rs8, -31743;
+; CHECK-NEXT:    selp.b16 %rs9, %rs1, %rs7, %p2;
+; CHECK-NEXT:    and.b16 %rs10, %rs9, 1023;
+; CHECK-NEXT:    or.b16 %rs11, %rs10, 1024;
+; CHECK-NEXT:    and.b16 %rs12, %rs3, 31744;
+; CHECK-NEXT:    selp.b16 %rs13, %rs12, %rs4, %p1;
+; CHECK-NEXT:    shr.u16 %rs14, %rs13, 10;
+; CHECK-NEXT:    cvt.u32.u16 %r1, %rs14;
+; CHECK-NEXT:    selp.b32 %r2, -12, 0, %p1;
+; CHECK-NEXT:    add.s32 %r3, %r1, %r2;
+; CHECK-NEXT:    add.s32 %r4, %r3, -14;
+; CHECK-NEXT:    selp.b32 %r5, 0, %r4, %p2;
+; CHECK-NEXT:    cvt.u16.u32 %rs15, %r5;
+; CHECK-NEXT:    sub.s16 %rs16, -5, %rs15;
+; CHECK-NEXT:    min.u16 %rs17, %rs16, 15;
+; CHECK-NEXT:    cvt.u32.u16 %r6, %rs17;
+; CHECK-NEXT:    shr.u16 %rs18, %rs11, %r6;
+; CHECK-NEXT:    and.b16 %rs19, %rs18, 1;
+; CHECK-NEXT:    max.u16 %rs20, %rs17, 1;
+; CHECK-NEXT:    add.s16 %rs21, %rs20, -1;
+; CHECK-NEXT:    cvt.u32.u16 %r7, %rs21;
+; CHECK-NEXT:    mov.b16 %rs22, 1;
+; CHECK-NEXT:    shl.b16 %rs23, %rs22, %r7;
+; CHECK-NEXT:    add.s16 %rs24, %rs23, -1;
+; CHECK-NEXT:    and.b16 %rs25, %rs11, %rs24;
+; CHECK-NEXT:    setp.ne.b16 %p3, %rs25, 0;
+; CHECK-NEXT:    selp.b16 %rs26, 1, 0, %p3;
+; CHECK-NEXT:    or.b16 %rs27, %rs26, %rs19;
+; CHECK-NEXT:    shr.u16 %rs28, %rs11, %r7;
+; CHECK-NEXT:    and.b16 %rs29, %rs28, %rs27;
+; CHECK-NEXT:    setp.ne.b16 %p4, %rs17, 0;
+; CHECK-NEXT:    selp.b16 %rs30, %rs29, 0, %p4;
+; CHECK-NEXT:    add.s16 %rs31, %rs18, %rs30;
+; CHECK-NEXT:    setp.gt.s16 %p5, %rs31, 3;
+; CHECK-NEXT:    selp.b16 %rs32, 0, %rs31, %p5;
+; CHECK-NEXT:    selp.b16 %rs33, 4, 0, %p5;
+; CHECK-NEXT:    shr.u16 %rs34, %rs1, 8;
+; CHECK-NEXT:    and.b16 %rs35, %rs34, 128;
+; CHECK-NEXT:    or.b16 %rs36, %rs35, %rs33;
+; CHECK-NEXT:    or.b16 %rs37, %rs36, %rs32;
+; CHECK-NEXT:    shr.u16 %rs38, %rs10, 8;
+; CHECK-NEXT:    and.b16 %rs39, %rs38, 1;
+; CHECK-NEXT:    and.b16 %rs40, %rs9, 127;
+; CHECK-NEXT:    setp.ne.b16 %p6, %rs40, 0;
+; CHECK-NEXT:    selp.b16 %rs41, 1, 0, %p6;
+; CHECK-NEXT:    or.b16 %rs42, %rs41, %rs39;
+; CHECK-NEXT:    shr.u16 %rs43, %rs9, 7;
+; CHECK-NEXT:    and.b16 %rs44, %rs43, %rs42;
+; CHECK-NEXT:    add.s16 %rs45, %rs38, %rs44;
+; CHECK-NEXT:    setp.gt.s16 %p7, %rs45, 3;
+; CHECK-NEXT:    selp.b16 %rs46, 0, %rs45, %p7;
+; CHECK-NEXT:    selp.b16 %rs47, 1, 0, %p7;
+; CHECK-NEXT:    add.s16 %rs48, %rs15, %rs47;
+; CHECK-NEXT:    add.s16 %rs49, %rs48, 14;
+; CHECK-NEXT:    shl.b16 %rs50, %rs49, 2;
+; CHECK-NEXT:    or.b16 %rs51, %rs35, %rs50;
+; CHECK-NEXT:    or.b16 %rs52, %rs51, %rs46;
+; CHECK-NEXT:    setp.lt.s16 %p8, %rs49, 1;
+; CHECK-NEXT:    selp.b16 %rs53, %rs37, %rs52, %p8;
+; CHECK-NEXT:    setp.gt.s16 %p9, %rs46, 3;
+; CHECK-NEXT:    or.b16 %rs54, %rs35, 124;
+; CHECK-NEXT:    selp.b16 %rs55, %rs54, %rs53, %p9;
+; CHECK-NEXT:    setp.eq.b16 %p10, %rs49, 30;
+; CHECK-NEXT:    selp.b16 %rs56, %rs55, %rs53, %p10;
+; CHECK-NEXT:    setp.gt.s16 %p11, %rs49, 30;
+; CHECK-NEXT:    selp.b16 %rs57, %rs54, %rs56, %p11;
+; CHECK-NEXT:    setp.eq.b16 %p12, %rs4, 0;
+; CHECK-NEXT:    selp.b16 %rs58, %rs35, %rs57, %p12;
+; CHECK-NEXT:    setp.eq.b16 %p13, %rs4, 31744;
+; CHECK-NEXT:    selp.b16 %rs59, %rs54, %rs58, %p13;
+; CHECK-NEXT:    setp.gt.s16 %p14, %rs4, 31744;
+; CHECK-NEXT:    selp.b16 %rs60, 126, %rs59, %p14;
+; CHECK-NEXT:    cvt.u32.u16 %r8, %rs60;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r8;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -841,93 +540,101 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-LABEL: to_f8e5m2_from_bf16(
 ; CHECK:       {
 ; CHECK-NEXT:    .reg .pred %p<16>;
-; CHECK-NEXT:    .reg .b16 %rs<61>;
-; CHECK-NEXT:    .reg .b32 %r<8>;
+; CHECK-NEXT:    .reg .b16 %rs<60>;
+; CHECK-NEXT:    .reg .b32 %r<17>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b16 %rs1, [to_f8e5m2_from_bf16_param_0];
-; CHECK-NEXT:    and.b16 %rs2, %rs1, 127;
-; CHECK-NEXT:    setp.ne.b16 %p1, %rs2, 0;
-; CHECK-NEXT:    shr.u16 %rs3, %rs1, 7;
-; CHECK-NEXT:    and.b16 %rs4, %rs3, 255;
-; CHECK-NEXT:    setp.eq.b16 %p2, %rs4, 0;
-; CHECK-NEXT:    and.pred %p3, %p2, %p1;
-; CHECK-NEXT:    cvt.u32.u16 %r1, %rs2;
+; CHECK-NEXT:    cvt.u32.u16 %r1, %rs1;
 ; CHECK-NEXT:    shl.b32 %r2, %r1, 16;
-; CHECK-NEXT:    clz.b32 %r3, %r2;
-; CHECK-NEXT:    cvt.u16.u32 %rs5, %r3;
-; CHECK-NEXT:    add.s16 %rs6, %rs5, -8;
-; CHECK-NEXT:    cvt.u32.u16 %r4, %rs6;
-; CHECK-NEXT:    shl.b16 %rs7, %rs2, %r4;
-; CHECK-NEXT:    and.b16 %rs8, %rs7, 127;
-; CHECK-NEXT:    selp.b16 %rs9, %rs8, %rs2, %p3;
-; CHECK-NEXT:    shr.u16 %rs10, %rs9, 5;
-; CHECK-NEXT:    and.b16 %rs11, %rs10, 1;
-; CHECK-NEXT:    and.b16 %rs12, %rs9, 15;
-; CHECK-NEXT:    setp.ne.b16 %p4, %rs12, 0;
-; CHECK-NEXT:    selp.b16 %rs13, 1, 0, %p4;
-; CHECK-NEXT:    or.b16 %rs14, %rs13, %rs11;
-; CHECK-NEXT:    shr.u16 %rs15, %rs9, 4;
-; CHECK-NEXT:    and.b16 %rs16, %rs15, %rs14;
-; CHECK-NEXT:    add.s16 %rs17, %rs10, %rs16;
-; CHECK-NEXT:    setp.gt.s16 %p5, %rs17, 3;
-; CHECK-NEXT:    selp.b16 %rs18, 0, %rs17, %p5;
-; CHECK-NEXT:    selp.b16 %rs19, 1, 0, %p5;
-; CHECK-NEXT:    sub.s16 %rs20, 9, %rs5;
-; CHECK-NEXT:    selp.b16 %rs21, %rs20, %rs4, %p3;
-; CHECK-NEXT:    add.s16 %rs22, %rs21, %rs19;
-; CHECK-NEXT:    add.s16 %rs23, %rs22, -112;
-; CHECK-NEXT:    shl.b16 %rs24, %rs23, 2;
-; CHECK-NEXT:    shr.u16 %rs25, %rs1, 8;
-; CHECK-NEXT:    and.b16 %rs26, %rs25, 128;
-; CHECK-NEXT:    or.b16 %rs27, %rs26, %rs24;
-; CHECK-NEXT:    or.b16 %rs28, %rs27, %rs18;
-; CHECK-NEXT:    or.b16 %rs29, %rs9, 128;
-; CHECK-NEXT:    sub.s16 %rs30, 118, %rs21;
-; CHECK-NEXT:    min.u16 %rs31, %rs30, 15;
-; CHECK-NEXT:    cvt.u32.u16 %r5, %rs31;
-; CHECK-NEXT:    shr.u16 %rs32, %rs29, %r5;
-; CHECK-NEXT:    and.b16 %rs33, %rs32, 1;
-; CHECK-NEXT:    max.u16 %rs34, %rs31, 1;
-; CHECK-NEXT:    add.s16 %rs35, %rs34, -1;
-; CHECK-NEXT:    cvt.u32.u16 %r6, %rs35;
-; CHECK-NEXT:    mov.b16 %rs36, 1;
-; CHECK-NEXT:    shl.b16 %rs37, %rs36, %r6;
-; CHECK-NEXT:    add.s16 %rs38, %rs37, -1;
-; CHECK-NEXT:    and.b16 %rs39, %rs29, %rs38;
-; CHECK-NEXT:    setp.ne.b16 %p6, %rs39, 0;
-; CHECK-NEXT:    selp.b16 %rs40, 1, 0, %p6;
-; CHECK-NEXT:    or.b16 %rs41, %rs40, %rs33;
-; CHECK-NEXT:    shr.u16 %rs42, %rs29, %r6;
+; CHECK-NEXT:    mul.rn.f32 %r3, %r2, 0f44000000;
+; CHECK-NEXT:    bfe.u32 %r4, %r3, 16, 1;
+; CHECK-NEXT:    add.s32 %r5, %r4, %r3;
+; CHECK-NEXT:    add.s32 %r6, %r5, 32767;
+; CHECK-NEXT:    setp.nan.f32 %p1, %r3, %r3;
+; CHECK-NEXT:    or.b32 %r7, %r3, 4194304;
+; CHECK-NEXT:    selp.b32 %r8, %r7, %r6, %p1;
+; CHECK-NEXT:    { .reg .b16 tmp; mov.b32 {tmp, %rs2}, %r8; }
+; CHECK-NEXT:    and.b16 %rs3, %rs1, 32767;
+; CHECK-NEXT:    setp.lt.u16 %p2, %rs3, 128;
+; CHECK-NEXT:    selp.b16 %rs4, %rs2, %rs1, %p2;
+; CHECK-NEXT:    and.b16 %rs5, %rs4, -32641;
+; CHECK-NEXT:    or.b16 %rs6, %rs5, 16128;
+; CHECK-NEXT:    add.s16 %rs7, %rs3, -32640;
+; CHECK-NEXT:    setp.lt.u16 %p3, %rs7, -32639;
+; CHECK-NEXT:    selp.b16 %rs8, %rs1, %rs6, %p3;
+; CHECK-NEXT:    and.b16 %rs9, %rs8, 127;
+; CHECK-NEXT:    or.b16 %rs10, %rs9, 128;
+; CHECK-NEXT:    and.b16 %rs11, %rs2, 32640;
+; CHECK-NEXT:    selp.b16 %rs12, %rs11, %rs3, %p2;
+; CHECK-NEXT:    shr.u16 %rs13, %rs12, 7;
+; CHECK-NEXT:    cvt.u32.u16 %r9, %rs13;
+; CHECK-NEXT:    selp.b32 %r10, -9, 0, %p2;
+; CHECK-NEXT:    add.s32 %r11, %r9, %r10;
+; CHECK-NEXT:    add.s32 %r12, %r11, -126;
+; CHECK-NEXT:    selp.b32 %r13, 0, %r12, %p3;
+; CHECK-NEXT:    cvt.u16.u32 %rs14, %r13;
+; CHECK-NEXT:    sub.s16 %rs15, -8, %rs14;
+; CHECK-NEXT:    min.u16 %rs16, %rs15, 15;
+; CHECK-NEXT:    cvt.u32.u16 %r14, %rs16;
+; CHECK-NEXT:    shr.u16 %rs17, %rs10, %r14;
+; CHECK-NEXT:    and.b16 %rs18, %rs17, 1;
+; CHECK-NEXT:    max.u16 %rs19, %rs16, 1;
+; CHECK-NEXT:    add.s16 %rs20, %rs19, -1;
+; CHECK-NEXT:    cvt.u32.u16 %r15, %rs20;
+; CHECK-NEXT:    mov.b16 %rs21, 1;
+; CHECK-NEXT:    shl.b16 %rs22, %rs21, %r15;
+; CHECK-NEXT:    add.s16 %rs23, %rs22, -1;
+; CHECK-NEXT:    and.b16 %rs24, %rs10, %rs23;
+; CHECK-NEXT:    setp.ne.b16 %p4, %rs24, 0;
+; CHECK-NEXT:    selp.b16 %rs25, 1, 0, %p4;
+; CHECK-NEXT:    or.b16 %rs26, %rs25, %rs18;
+; CHECK-NEXT:    shr.u16 %rs27, %rs10, %r15;
+; CHECK-NEXT:    and.b16 %rs28, %rs27, %rs26;
+; CHECK-NEXT:    setp.ne.b16 %p5, %rs16, 0;
+; CHECK-NEXT:    selp.b16 %rs29, %rs28, 0, %p5;
+; CHECK-NEXT:    add.s16 %rs30, %rs17, %rs29;
+; CHECK-NEXT:    setp.gt.s16 %p6, %rs30, 3;
+; CHECK-NEXT:    selp.b16 %rs31, 0, %rs30, %p6;
+; CHECK-NEXT:    selp.b16 %rs32, 4, 0, %p6;
+; CHECK-NEXT:    shr.u16 %rs33, %rs1, 8;
+; CHECK-NEXT:    and.b16 %rs34, %rs33, 128;
+; CHECK-NEXT:    or.b16 %rs35, %rs34, %rs32;
+; CHECK-NEXT:    or.b16 %rs36, %rs35, %rs31;
+; CHECK-NEXT:    shr.u16 %rs37, %rs9, 5;
+; CHECK-NEXT:    and.b16 %rs38, %rs37, 1;
+; CHECK-NEXT:    and.b16 %rs39, %rs8, 15;
+; CHECK-NEXT:    setp.ne.b16 %p7, %rs39, 0;
+; CHECK-NEXT:    selp.b16 %rs40, 1, 0, %p7;
+; CHECK-NEXT:    or.b16 %rs41, %rs40, %rs38;
+; CHECK-NEXT:    shr.u16 %rs42, %rs8, 4;
 ; CHECK-NEXT:    and.b16 %rs43, %rs42, %rs41;
-; CHECK-NEXT:    setp.ne.b16 %p7, %rs31, 0;
-; CHECK-NEXT:    selp.b16 %rs44, %rs43, 0, %p7;
-; CHECK-NEXT:    add.s16 %rs45, %rs32, %rs44;
-; CHECK-NEXT:    setp.gt.s16 %p8, %rs45, 3;
-; CHECK-NEXT:    selp.b16 %rs46, 0, %rs45, %p8;
-; CHECK-NEXT:    selp.b16 %rs47, 4, 0, %p8;
-; CHECK-NEXT:    or.b16 %rs48, %rs26, %rs47;
-; CHECK-NEXT:    or.b16 %rs49, %rs48, %rs46;
-; CHECK-NEXT:    setp.lt.s16 %p9, %rs23, 1;
-; CHECK-NEXT:    selp.b16 %rs50, %rs49, %rs28, %p9;
-; CHECK-NEXT:    setp.gt.s16 %p10, %rs18, 3;
-; CHECK-NEXT:    or.b16 %rs51, %rs26, 124;
-; CHECK-NEXT:    selp.b16 %rs52, %rs51, %rs50, %p10;
-; CHECK-NEXT:    setp.eq.b16 %p11, %rs23, 30;
-; CHECK-NEXT:    selp.b16 %rs53, %rs52, %rs50, %p11;
-; CHECK-NEXT:    setp.gt.s16 %p12, %rs23, 30;
-; CHECK-NEXT:    selp.b16 %rs54, %rs51, %rs53, %p12;
-; CHECK-NEXT:    or.b16 %rs55, %rs4, %rs2;
-; CHECK-NEXT:    setp.eq.b16 %p13, %rs55, 0;
-; CHECK-NEXT:    selp.b16 %rs56, %rs26, %rs54, %p13;
-; CHECK-NEXT:    setp.eq.b16 %p14, %rs2, 0;
-; CHECK-NEXT:    selp.b16 %rs57, %rs51, %rs56, %p14;
-; CHECK-NEXT:    setp.eq.b16 %p15, %rs4, 255;
-; CHECK-NEXT:    selp.b16 %rs58, %rs57, %rs56, %p15;
-; CHECK-NEXT:    selp.b16 %rs59, 126, %rs58, %p1;
-; CHECK-NEXT:    selp.b16 %rs60, %rs59, %rs58, %p15;
-; CHECK-NEXT:    cvt.u32.u16 %r7, %rs60;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r7;
+; CHECK-NEXT:    add.s16 %rs44, %rs37, %rs43;
+; CHECK-NEXT:    setp.gt.s16 %p8, %rs44, 3;
+; CHECK-NEXT:    selp.b16 %rs45, 0, %rs44, %p8;
+; CHECK-NEXT:    selp.b16 %rs46, 1, 0, %p8;
+; CHECK-NEXT:    add.s16 %rs47, %rs14, %rs46;
+; CHECK-NEXT:    add.s16 %rs48, %rs47, 14;
+; CHECK-NEXT:    shl.b16 %rs49, %rs48, 2;
+; CHECK-NEXT:    or.b16 %rs50, %rs34, %rs49;
+; CHECK-NEXT:    or.b16 %rs51, %rs50, %rs45;
+; CHECK-NEXT:    setp.lt.s16 %p9, %rs48, 1;
+; CHECK-NEXT:    selp.b16 %rs52, %rs36, %rs51, %p9;
+; CHECK-NEXT:    setp.gt.s16 %p10, %rs45, 3;
+; CHECK-NEXT:    or.b16 %rs53, %rs34, 124;
+; CHECK-NEXT:    selp.b16 %rs54, %rs53, %rs52, %p10;
+; CHECK-NEXT:    setp.eq.b16 %p11, %rs48, 30;
+; CHECK-NEXT:    selp.b16 %rs55, %rs54, %rs52, %p11;
+; CHECK-NEXT:    setp.gt.s16 %p12, %rs48, 30;
+; CHECK-NEXT:    selp.b16 %rs56, %rs53, %rs55, %p12;
+; CHECK-NEXT:    setp.eq.b16 %p13, %rs3, 0;
+; CHECK-NEXT:    selp.b16 %rs57, %rs34, %rs56, %p13;
+; CHECK-NEXT:    setp.eq.b16 %p14, %rs3, 32640;
+; CHECK-NEXT:    selp.b16 %rs58, %rs53, %rs57, %p14;
+; CHECK-NEXT:    setp.gt.s16 %p15, %rs3, 32640;
+; CHECK-NEXT:    selp.b16 %rs59, 126, %rs58, %p15;
+; CHECK-NEXT:    cvt.u32.u16 %r16, %rs59;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r16;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -937,91 +644,92 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f64(
 ; CHECK:       {
-; CHECK-NEXT:    .reg .pred %p<16>;
-; CHECK-NEXT:    .reg .b32 %r<5>;
-; CHECK-NEXT:    .reg .b64 %rd<61>;
+; CHECK-NEXT:    .reg .pred %p<15>;
+; CHECK-NEXT:    .reg .b32 %r<8>;
+; CHECK-NEXT:    .reg .b64 %rd<60>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b64 %rd1, [to_f8e5m2_from_f64_param_0];
-; CHECK-NEXT:    and.b64 %rd2, %rd1, 4503599627370495;
-; CHECK-NEXT:    setp.ne.b64 %p1, %rd2, 0;
-; CHECK-NEXT:    shr.u64 %rd3, %rd1, 52;
-; CHECK-NEXT:    and.b64 %rd4, %rd3, 2047;
-; CHECK-NEXT:    setp.eq.b64 %p2, %rd4, 0;
-; CHECK-NEXT:    and.pred %p3, %p2, %p1;
-; CHECK-NEXT:    clz.b64 %r1, %rd2;
-; CHECK-NEXT:    cvt.u64.u32 %rd5, %r1;
-; CHECK-NEXT:    add.s64 %rd6, %rd5, -11;
-; CHECK-NEXT:    cvt.u32.u64 %r2, %rd6;
-; CHECK-NEXT:    shl.b64 %rd7, %rd2, %r2;
-; CHECK-NEXT:    and.b64 %rd8, %rd7, 4503599627370495;
-; CHECK-NEXT:    selp.b64 %rd9, %rd8, %rd2, %p3;
-; CHECK-NEXT:    shr.u64 %rd10, %rd9, 50;
-; CHECK-NEXT:    and.b64 %rd11, %rd10, 1;
-; CHECK-NEXT:    and.b64 %rd12, %rd9, 562949953421311;
-; CHECK-NEXT:    setp.ne.b64 %p4, %rd12, 0;
-; CHECK-NEXT:    selp.b64 %rd13, 1, 0, %p4;
-; CHECK-NEXT:    or.b64 %rd14, %rd13, %rd11;
-; CHECK-NEXT:    shr.u64 %rd15, %rd9, 49;
-; CHECK-NEXT:    and.b64 %rd16, %rd15, %rd14;
-; CHECK-NEXT:    add.s64 %rd17, %rd10, %rd16;
-; CHECK-NEXT:    setp.gt.s64 %p5, %rd17, 3;
-; CHECK-NEXT:    selp.b64 %rd18, 0, %rd17, %p5;
-; CHECK-NEXT:    selp.b64 %rd19, 1, 0, %p5;
-; CHECK-NEXT:    sub.s64 %rd20, 12, %rd5;
-; CHECK-NEXT:    selp.b64 %rd21, %rd20, %rd4, %p3;
-; CHECK-NEXT:    add.s64 %rd22, %rd21, %rd19;
-; CHECK-NEXT:    add.s64 %rd23, %rd22, -1008;
-; CHECK-NEXT:    shl.b64 %rd24, %rd23, 2;
-; CHECK-NEXT:    shr.u64 %rd25, %rd1, 56;
-; CHECK-NEXT:    and.b64 %rd26, %rd25, 128;
-; CHECK-NEXT:    or.b64 %rd27, %rd26, %rd24;
-; CHECK-NEXT:    or.b64 %rd28, %rd27, %rd18;
-; CHECK-NEXT:    or.b64 %rd29, %rd9, 4503599627370496;
-; CHECK-NEXT:    sub.s64 %rd30, 1059, %rd21;
-; CHECK-NEXT:    min.u64 %rd31, %rd30, 63;
-; CHECK-NEXT:    cvt.u32.u64 %r3, %rd31;
-; CHECK-NEXT:    shr.u64 %rd32, %rd29, %r3;
-; CHECK-NEXT:    and.b64 %rd33, %rd32, 1;
-; CHECK-NEXT:    max.u64 %rd34, %rd31, 1;
-; CHECK-NEXT:    add.s64 %rd35, %rd34, -1;
-; CHECK-NEXT:    cvt.u32.u64 %r4, %rd35;
-; CHECK-NEXT:    mov.b64 %rd36, 1;
-; CHECK-NEXT:    shl.b64 %rd37, %rd36, %r4;
-; CHECK-NEXT:    add.s64 %rd38, %rd37, -1;
-; CHECK-NEXT:    and.b64 %rd39, %rd29, %rd38;
+; CHECK-NEXT:    mul.rn.f64 %rd2, %rd1, 0d4350000000000000;
+; CHECK-NEXT:    and.b64 %rd3, %rd1, 9223372036854775807;
+; CHECK-NEXT:    setp.lt.u64 %p1, %rd3, 4503599627370496;
+; CHECK-NEXT:    selp.b64 %rd4, %rd2, %rd1, %p1;
+; CHECK-NEXT:    and.b64 %rd5, %rd4, -9218868437227405313;
+; CHECK-NEXT:    or.b64 %rd6, %rd5, 4602678819172646912;
+; CHECK-NEXT:    add.s64 %rd7, %rd3, -9218868437227405312;
+; CHECK-NEXT:    setp.lt.u64 %p2, %rd7, -9218868437227405311;
+; CHECK-NEXT:    selp.f64 %rd8, %rd1, %rd6, %p2;
+; CHECK-NEXT:    and.b64 %rd9, %rd8, 4503599627370495;
+; CHECK-NEXT:    or.b64 %rd10, %rd9, 4503599627370496;
+; CHECK-NEXT:    and.b64 %rd11, %rd2, 9218868437227405312;
+; CHECK-NEXT:    selp.b64 %rd12, %rd11, %rd3, %p1;
+; CHECK-NEXT:    shr.u64 %rd13, %rd12, 52;
+; CHECK-NEXT:    cvt.u32.u64 %r1, %rd13;
+; CHECK-NEXT:    selp.b32 %r2, -54, 0, %p1;
+; CHECK-NEXT:    add.s32 %r3, %r1, %r2;
+; CHECK-NEXT:    add.s32 %r4, %r3, -1022;
+; CHECK-NEXT:    selp.b32 %r5, 0, %r4, %p2;
+; CHECK-NEXT:    cvt.s64.s32 %rd14, %r5;
+; CHECK-NEXT:    sub.s64 %rd15, 37, %rd14;
+; CHECK-NEXT:    min.u64 %rd16, %rd15, 63;
+; CHECK-NEXT:    cvt.u32.u64 %r6, %rd16;
+; CHECK-NEXT:    shr.u64 %rd17, %rd10, %r6;
+; CHECK-NEXT:    and.b64 %rd18, %rd17, 1;
+; CHECK-NEXT:    max.u64 %rd19, %rd16, 1;
+; CHECK-NEXT:    add.s64 %rd20, %rd19, -1;
+; CHECK-NEXT:    cvt.u32.u64 %r7, %rd20;
+; CHECK-NEXT:    mov.b64 %rd21, 1;
+; CHECK-NEXT:    shl.b64 %rd22, %rd21, %r7;
+; CHECK-NEXT:    add.s64 %rd23, %rd22, -1;
+; CHECK-NEXT:    and.b64 %rd24, %rd10, %rd23;
+; CHECK-NEXT:    setp.ne.b64 %p3, %rd24, 0;
+; CHECK-NEXT:    selp.b64 %rd25, 1, 0, %p3;
+; CHECK-NEXT:    or.b64 %rd26, %rd25, %rd18;
+; CHECK-NEXT:    shr.u64 %rd27, %rd10, %r7;
+; CHECK-NEXT:    and.b64 %rd28, %rd27, %rd26;
+; CHECK-NEXT:    setp.ne.b64 %p4, %rd16, 0;
+; CHECK-NEXT:    selp.b64 %rd29, %rd28, 0, %p4;
+; CHECK-NEXT:    add.s64 %rd30, %rd17, %rd29;
+; CHECK-NEXT:    setp.gt.s64 %p5, %rd30, 3;
+; CHECK-NEXT:    selp.b64 %rd31, 0, %rd30, %p5;
+; CHECK-NEXT:    selp.b64 %rd32, 4, 0, %p5;
+; CHECK-NEXT:    shr.u64 %rd33, %rd1, 56;
+; CHECK-NEXT:    and.b64 %rd34, %rd33, 128;
+; CHECK-NEXT:    or.b64 %rd35, %rd34, %rd32;
+; CHECK-NEXT:    or.b64 %rd36, %rd35, %rd31;
+; CHECK-NEXT:    bfe.u64 %rd37, %rd8, 50, 2;
+; CHECK-NEXT:    and.b64 %rd38, %rd37, 1;
+; CHECK-NEXT:    and.b64 %rd39, %rd8, 562949953421311;
 ; CHECK-NEXT:    setp.ne.b64 %p6, %rd39, 0;
 ; CHECK-NEXT:    selp.b64 %rd40, 1, 0, %p6;
-; CHECK-NEXT:    or.b64 %rd41, %rd40, %rd33;
-; CHECK-NEXT:    shr.u64 %rd42, %rd29, %r4;
+; CHECK-NEXT:    or.b64 %rd41, %rd40, %rd38;
+; CHECK-NEXT:    shr.u64 %rd42, %rd8, 49;
 ; CHECK-NEXT:    and.b64 %rd43, %rd42, %rd41;
-; CHECK-NEXT:    setp.ne.b64 %p7, %rd31, 0;
-; CHECK-NEXT:    selp.b64 %rd44, %rd43, 0, %p7;
-; CHECK-NEXT:    add.s64 %rd45, %rd32, %rd44;
-; CHECK-NEXT:    setp.gt.s64 %p8, %rd45, 3;
-; CHECK-NEXT:    selp.b64 %rd46, 0, %rd45, %p8;
-; CHECK-NEXT:    selp.b64 %rd47, 4, 0, %p8;
-; CHECK-NEXT:    or.b64 %rd48, %rd26, %rd47;
-; CHECK-NEXT:    or.b64 %rd49, %rd48, %rd46;
-; CHECK-NEXT:    setp.lt.s64 %p9, %rd23, 1;
-; CHECK-NEXT:    selp.b64 %rd50, %rd49, %rd28, %p9;
-; CHECK-NEXT:    setp.gt.s64 %p10, %rd18, 3;
-; CHECK-NEXT:    or.b64 %rd51, %rd26, 124;
-; CHECK-NEXT:    selp.b64 %rd52, %rd51, %rd50, %p10;
-; CHECK-NEXT:    setp.eq.b64 %p11, %rd23, 30;
-; CHECK-NEXT:    selp.b64 %rd53, %rd52, %rd50, %p11;
-; CHECK-NEXT:    setp.gt.s64 %p12, %rd23, 30;
-; CHECK-NEXT:    selp.b64 %rd54, %rd51, %rd53, %p12;
-; CHECK-NEXT:    or.b64 %rd55, %rd4, %rd2;
-; CHECK-NEXT:    setp.eq.b64 %p13, %rd55, 0;
-; CHECK-NEXT:    selp.b64 %rd56, %rd26, %rd54, %p13;
-; CHECK-NEXT:    setp.eq.b64 %p14, %rd2, 0;
-; CHECK-NEXT:    selp.b64 %rd57, %rd51, %rd56, %p14;
-; CHECK-NEXT:    setp.eq.b64 %p15, %rd4, 2047;
-; CHECK-NEXT:    selp.b64 %rd58, %rd57, %rd56, %p15;
-; CHECK-NEXT:    selp.b64 %rd59, 126, %rd58, %p1;
-; CHECK-NEXT:    selp.b64 %rd60, %rd59, %rd58, %p15;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %rd60;
+; CHECK-NEXT:    add.s64 %rd44, %rd37, %rd43;
+; CHECK-NEXT:    setp.gt.s64 %p7, %rd44, 3;
+; CHECK-NEXT:    selp.b64 %rd45, 0, %rd44, %p7;
+; CHECK-NEXT:    selp.b64 %rd46, 1, 0, %p7;
+; CHECK-NEXT:    add.s64 %rd47, %rd14, %rd46;
+; CHECK-NEXT:    add.s64 %rd48, %rd47, 14;
+; CHECK-NEXT:    shl.b64 %rd49, %rd48, 2;
+; CHECK-NEXT:    or.b64 %rd50, %rd34, %rd49;
+; CHECK-NEXT:    or.b64 %rd51, %rd50, %rd45;
+; CHECK-NEXT:    setp.lt.s64 %p8, %rd48, 1;
+; CHECK-NEXT:    selp.b64 %rd52, %rd36, %rd51, %p8;
+; CHECK-NEXT:    setp.gt.s64 %p9, %rd45, 3;
+; CHECK-NEXT:    or.b64 %rd53, %rd34, 124;
+; CHECK-NEXT:    selp.b64 %rd54, %rd53, %rd52, %p9;
+; CHECK-NEXT:    setp.eq.b64 %p10, %rd48, 30;
+; CHECK-NEXT:    selp.b64 %rd55, %rd54, %rd52, %p10;
+; CHECK-NEXT:    setp.gt.s64 %p11, %rd48, 30;
+; CHECK-NEXT:    selp.b64 %rd56, %rd53, %rd55, %p11;
+; CHECK-NEXT:    setp.eq.b64 %p12, %rd3, 0;
+; CHECK-NEXT:    selp.b64 %rd57, %rd34, %rd56, %p12;
+; CHECK-NEXT:    setp.eq.b64 %p13, %rd3, 9218868437227405312;
+; CHECK-NEXT:    selp.b64 %rd58, %rd53, %rd57, %p13;
+; CHECK-NEXT:    setp.gt.s64 %p14, %rd3, 9218868437227405312;
+; CHECK-NEXT:    selp.b64 %rd59, 126, %rd58, %p14;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %rd59;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll
index b1c5139ebede7..995d57d004acd 100644
--- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp-error.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: split-file %s %t
 ; RUN: not llc < %t/float8e4m3.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E4M3
 ; RUN: not llc < %t/float8e3m4.ll -mtriple=x86_64-unknown-unknown 2>&1 | FileCheck %s --check-prefix=E3M4
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
index 619e42ab03718..c835fbba2838a 100644
--- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
@@ -16,484 +16,172 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
 ; Layout: sign(1) exp(5) mant(2), bias=15
 ; Supports: Inf, NaN, signed zero, denormals
 
-; Float8E5M2 normal: f32 1.0 -> 0_01111_00 = 0x3C
-define i8 @to_f8e5m2_normal() {
-; CHECK-LABEL: to_f8e5m2_normal:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $60, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 zero: f32 0.0 -> 0_00000_00 = 0x00
-define i8 @to_f8e5m2_zero() {
-; CHECK-LABEL: to_f8e5m2_zero:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 negative zero: f32 -0.0 -> 1_00000_00 = 0x80
-define i8 @to_f8e5m2_neg_zero() {
-; CHECK-LABEL: to_f8e5m2_neg_zero:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $-128, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float -0.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 +Inf: f32 Inf -> 0_11111_00 = 0x7C
-define i8 @to_f8e5m2_inf() {
-; CHECK-LABEL: to_f8e5m2_inf:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $124, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 NaN: f32 NaN -> 0_11111_10 = 0x7E
-define i8 @to_f8e5m2_nan() {
-; CHECK-LABEL: to_f8e5m2_nan:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $126, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 max: 57344.0 -> 0_11110_11 = 0x7B
-define i8 @to_f8e5m2_max() {
-; CHECK-LABEL: to_f8e5m2_max:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $123, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 57344.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 overflow (no saturation): 100000.0 -> Inf = 0x7C
-define i8 @to_f8e5m2_overflow() {
-; CHECK-LABEL: to_f8e5m2_overflow:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $124, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E5M2 overflow with saturation: 100000.0 -> max = 0x7B
-define i8 @to_f8e5m2_overflow_sat() {
-; CHECK-LABEL: to_f8e5m2_overflow_sat:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $123, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 100000.0, metadata !"Float8E5M2", metadata !"round.tonearest", i1 true)
-  ret i8 %r
-}
-
-; Float8E5M2 denorm: very small value -> dst denorm
-define i8 @to_f8e5m2_denorm() {
-  ; 2^(-16) = 0x00010000 in f32 = 1.52587891e-5
-; CHECK-LABEL: to_f8e5m2_denorm:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $1, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x3EF0000000000000, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
 ; Float8E5M2 dynamic input
 define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-LABEL: to_f8e5m2_dynamic:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    pushq %rax
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    pushq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    pushq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    .cfi_offset %rbx, -40
-; CHECK-NEXT:    .cfi_offset %r14, -32
-; CHECK-NEXT:    .cfi_offset %r15, -24
-; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movd %xmm0, %edx
-; CHECK-NEXT:    movl %edx, %eax
-; CHECK-NEXT:    andl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-NEXT:    bsrl %eax, %ecx
-; CHECK-NEXT:    xorl $31, %ecx
-; CHECK-NEXT:    movl $9, %r11d
-; CHECK-NEXT:    subl %ecx, %r11d
-; CHECK-NEXT:    addl $-8, %ecx
-; CHECK-NEXT:    movl %eax, %r10d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r10d
-; CHECK-NEXT:    andl $8388607, %r10d # imm = 0x7FFFFF
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    sete %dil
-; CHECK-NEXT:    setne %sil
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    shrl $23, %ecx
-; CHECK-NEXT:    movzbl %cl, %r8d
-; CHECK-NEXT:    testl %r8d, %r8d
-; CHECK-NEXT:    sete %r9b
-; CHECK-NEXT:    testb %sil, %r9b
-; CHECK-NEXT:    cmovel %eax, %r10d
-; CHECK-NEXT:    cmovel %r8d, %r11d
-; CHECK-NEXT:    movl $134, %ecx
-; CHECK-NEXT:    subl %r11d, %ecx
+; CHECK-NEXT:    movd %xmm0, (%rsp) # 4-byte Folded Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx
+; CHECK-NEXT:    movl $8, %ecx
+; CHECK-NEXT:    subl %edx, %ecx
 ; CHECK-NEXT:    cmpl $31, %ecx
 ; CHECK-NEXT:    movl $31, %eax
 ; CHECK-NEXT:    cmovbl %ecx, %eax
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    leal 8388608(%r10), %ebx
-; CHECK-NEXT:    movl %ebx, %ebp
-; CHECK-NEXT:    shrl %cl, %ebp
-; CHECK-NEXT:    movl $1, %r14d
+; CHECK-NEXT:    movd %xmm0, %esi
+; CHECK-NEXT:    movl %esi, %edi
+; CHECK-NEXT:    andl $8388607, %edi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rdi), %r9d
+; CHECK-NEXT:    movl %r9d, %r8d
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    movl $1, %r10d
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r14d
-; CHECK-NEXT:    decl %r14d
-; CHECK-NEXT:    xorl %r15d, %r15d
-; CHECK-NEXT:    testl %r14d, %ebx
-; CHECK-NEXT:    setne %r15b
+; CHECK-NEXT:    shll %cl, %r10d
+; CHECK-NEXT:    decl %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl %r10d, %r9d
+; CHECK-NEXT:    setne %r11b
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %ebx
-; CHECK-NEXT:    movl %ebx, %r14d
-; CHECK-NEXT:    andl $1, %r14d
-; CHECK-NEXT:    orl %r15d, %r14d
-; CHECK-NEXT:    andl %ebp, %r14d
-; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    shrl %cl, %r9d
+; CHECK-NEXT:    movl %r9d, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    orl %r11d, %r10d
+; CHECK-NEXT:    andl %r8d, %r10d
+; CHECK-NEXT:    xorl %r8d, %r8d
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %ecx, %r14d
-; CHECK-NEXT:    addl %ebx, %r14d
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $4, %r14d
-; CHECK-NEXT:    cmovgel %ecx, %r14d
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    shrl $24, %edx
-; CHECK-NEXT:    andl $-128, %edx
-; CHECK-NEXT:    leal (%rdx,%rax,4), %eax
-; CHECK-NEXT:    orl %r14d, %eax
-; CHECK-NEXT:    movl %r10d, %ebx
-; CHECK-NEXT:    shrl $21, %ebx
-; CHECK-NEXT:    movl %ebx, %ebp
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    xorl %r14d, %r14d
-; CHECK-NEXT:    testl $1048575, %r10d # imm = 0xFFFFF
-; CHECK-NEXT:    setne %r14b
-; CHECK-NEXT:    orl %ebp, %r14d
-; CHECK-NEXT:    shrl $20, %r10d
-; CHECK-NEXT:    andl %r14d, %r10d
-; CHECK-NEXT:    addl %ebx, %r10d
-; CHECK-NEXT:    xorl %ebx, %ebx
-; CHECK-NEXT:    cmpl $4, %r10d
-; CHECK-NEXT:    cmovgel %ecx, %r10d
-; CHECK-NEXT:    setge %bl
-; CHECK-NEXT:    leal -112(%r11,%rbx), %ebp
-; CHECK-NEXT:    addl %ebx, %r11d
-; CHECK-NEXT:    leal -448(,%r11,4), %r11d
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    orl %r10d, %ecx
-; CHECK-NEXT:    orl %r11d, %ecx
-; CHECK-NEXT:    testl %ebp, %ebp
-; CHECK-NEXT:    cmovlel %eax, %ecx
+; CHECK-NEXT:    cmovbl %r8d, %r10d
+; CHECK-NEXT:    addl %r9d, %r10d
+; CHECK-NEXT:    xorl %r9d, %r9d
 ; CHECK-NEXT:    cmpl $4, %r10d
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    cmpl $30, %ebp
-; CHECK-NEXT:    sete %r10b
-; CHECK-NEXT:    andb %al, %r10b
-; CHECK-NEXT:    cmpl $31, %ebp
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    orb %r10b, %al
-; CHECK-NEXT:    leal 124(%rdx), %r10d
-; CHECK-NEXT:    testb %al, %al
-; CHECK-NEXT:    cmovnel %r10d, %ecx
-; CHECK-NEXT:    testb %dil, %r9b
-; CHECK-NEXT:    cmovnel %edx, %ecx
-; CHECK-NEXT:    cmpl $255, %r8d
-; CHECK-NEXT:    sete %al
-; CHECK-NEXT:    testb %dil, %al
-; CHECK-NEXT:    cmovnel %r10d, %ecx
-; CHECK-NEXT:    testb %sil, %al
+; CHECK-NEXT:    cmovgel %r8d, %r10d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    movd (%rsp), %xmm0 # 4-byte Folded Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl $24, %ecx
+; CHECK-NEXT:    andl $-128, %ecx
+; CHECK-NEXT:    leal (%rcx,%r9,4), %r9d
+; CHECK-NEXT:    orl %r10d, %r9d
+; CHECK-NEXT:    shrl $21, %edi
+; CHECK-NEXT:    movl %edi, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $1048575, %esi # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %r10d, %r11d
+; CHECK-NEXT:    shrl $20, %esi
+; CHECK-NEXT:    andl %r11d, %esi
+; CHECK-NEXT:    addl %edi, %esi
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $4, %esi
+; CHECK-NEXT:    cmovgel %r8d, %esi
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    leal (%rdx,%r10), %edi
+; CHECK-NEXT:    leal 56(,%rdi,4), %r8d
+; CHECK-NEXT:    movl %ecx, %edi
+; CHECK-NEXT:    orl %esi, %edi
+; CHECK-NEXT:    orl %r8d, %edi
+; CHECK-NEXT:    leal 14(%rdx,%r10), %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %r9d, %edi
+; CHECK-NEXT:    cmpl $4, %esi
+; CHECK-NEXT:    setge %sil
+; CHECK-NEXT:    cmpl $30, %edx
+; CHECK-NEXT:    sete %r8b
+; CHECK-NEXT:    andb %sil, %r8b
+; CHECK-NEXT:    cmpl $31, %edx
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    orb %r8b, %dl
+; CHECK-NEXT:    leal 124(%rcx), %esi
+; CHECK-NEXT:    testb %dl, %dl
+; CHECK-NEXT:    cmovnel %esi, %edi
+; CHECK-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-NEXT:    cmovel %ecx, %edi
+; CHECK-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-NEXT:    cmovel %esi, %edi
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    cmovlel %edi, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    popq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    popq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    popq %rcx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
 }
 
-; Float8E4M3FN
-; Layout: sign(1) exp(4) mant(3), bias=7
-; Supports: NaN (special encoding: 0_1111_111 only), no Inf, signed zero
-
-; Float8E4M3FN normal: f32 1.0 -> 0_0111_000 = 0x38
-define i8 @to_f8e4m3fn_normal() {
-; CHECK-LABEL: to_f8e4m3fn_normal:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $56, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN max: 448.0 -> 0_1111_110 = 0x7E
-define i8 @to_f8e4m3fn_max() {
-; CHECK-LABEL: to_f8e4m3fn_max:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $126, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 448.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN NaN: f32 NaN -> 0_1111_111 = 0x7F
-define i8 @to_f8e4m3fn_nan() {
-; CHECK-LABEL: to_f8e4m3fn_nan:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $127, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 0x7FF8000000000000, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
-; Float8E4M3FN overflow with saturation: large value -> max = 0x7E
-define i8 @to_f8e4m3fn_overflow_sat() {
-; CHECK-LABEL: to_f8e4m3fn_overflow_sat:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $126, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1000.0, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 true)
-  ret i8 %r
-}
-
-; Float6E3M2FN
-; Layout: sign(1) exp(3) mant(2), bias=3
-; Supports: no Inf, no NaN, signed zero (FiniteOnly)
-
-; Float6E3M2FN normal: f32 1.0 -> 0_011_00 = 0x0C
-define i6 @to_f6e3m2fn_normal() {
-; CHECK-LABEL: to_f6e3m2fn_normal:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $12, %al
-; CHECK-NEXT:    retq
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN max: 28.0 -> 0_111_11 = 0x1F
-define i6 @to_f6e3m2fn_max() {
-; CHECK-LABEL: to_f6e3m2fn_max:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $31, %al
-; CHECK-NEXT:    retq
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 28.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN zero: f32 0.0 -> 0_000_00 = 0x00
-define i6 @to_f6e3m2fn_zero() {
-; CHECK-LABEL: to_f6e3m2fn_zero:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    retq
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 0.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E3M2FN negative: f32 -2.0 -> 1_100_00 = 0x30
-define i6 @to_f6e3m2fn_negative() {
-; CHECK-LABEL: to_f6e3m2fn_negative:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $48, %al
-; CHECK-NEXT:    retq
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float -2.0, metadata !"Float6E3M2FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E2M3FN
-; Layout: sign(1) exp(2) mant(3), bias=1
-; Supports: no Inf, no NaN, signed zero (FiniteOnly)
-
-; Float6E2M3FN normal: f32 1.0 -> 0_01_000 = 0x08
-define i6 @to_f6e2m3fn_normal() {
-; CHECK-LABEL: to_f6e2m3fn_normal:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $8, %al
-; CHECK-NEXT:    retq
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 1.0, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float6E2M3FN max: 7.5 -> 0_11_111 = 0x1F
-define i6 @to_f6e2m3fn_max() {
-; CHECK-LABEL: to_f6e2m3fn_max:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $31, %al
-; CHECK-NEXT:    retq
-  %r = call i6 @llvm.convert.to.arbitrary.fp.i6.f32(float 7.5, metadata !"Float6E2M3FN", metadata !"round.tonearest", i1 false)
-  ret i6 %r
-}
-
-; Float4E2M1FN
-; Layout: sign(1) exp(2) mant(1), bias=1
-; Supports: no Inf, no NaN, signed zero (FiniteOnly)
-
-; Float4E2M1FN normal: f32 1.0 -> 0_01_0 = 0x2
-define i4 @to_f4e2m1fn_normal() {
-; CHECK-LABEL: to_f4e2m1fn_normal:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $2, %al
-; CHECK-NEXT:    retq
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 1.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
-; Float4E2M1FN max: 6.0 -> 0_11_1 = 0x7
-define i4 @to_f4e2m1fn_max() {
-; CHECK-LABEL: to_f4e2m1fn_max:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $7, %al
-; CHECK-NEXT:    retq
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 6.0, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
-; Float4E2M1FN denorm: 0.5 -> 0_00_1 = 0x1
-define i4 @to_f4e2m1fn_denorm() {
-; CHECK-LABEL: to_f4e2m1fn_denorm:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $1, %al
-; CHECK-NEXT:    retq
-  %r = call i4 @llvm.convert.to.arbitrary.fp.i4.f32(float 0.5, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
-  ret i4 %r
-}
-
 ; Rounding tests
 
-; Round to nearest even: 1.5 in f32 with E5M2 should round to 1.5 (0_01111_10 = 0x3E)
-define i8 @to_f8e5m2_round_nearest() {
-; CHECK-LABEL: to_f8e5m2_round_nearest:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    movb $62, %al
-; CHECK-NEXT:    retq
-  %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float 1.5, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
-  ret i8 %r
-}
-
 ; Round toward zero
 define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-LABEL: to_f8e5m2_round_towardzero:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    pushq %rax
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    pushq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    pushq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    .cfi_offset %rbx, -40
-; CHECK-NEXT:    .cfi_offset %r14, -32
-; CHECK-NEXT:    .cfi_offset %r15, -24
-; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    movl %eax, %r11d
-; CHECK-NEXT:    andl $8388607, %r11d # imm = 0x7FFFFF
-; CHECK-NEXT:    bsrl %r11d, %edx
-; CHECK-NEXT:    xorl $31, %edx
-; CHECK-NEXT:    leal -8(%rdx), %ecx
-; CHECK-NEXT:    movl %r11d, %r9d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r9d
-; CHECK-NEXT:    andl $8388607, %r9d # imm = 0x7FFFFF
-; CHECK-NEXT:    movl $9, %r10d
-; CHECK-NEXT:    subl %edx, %r10d
-; CHECK-NEXT:    testl %r11d, %r11d
-; CHECK-NEXT:    sete %sil
-; CHECK-NEXT:    setne %dl
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl $23, %ecx
-; CHECK-NEXT:    movzbl %cl, %edi
-; CHECK-NEXT:    testl %edi, %edi
-; CHECK-NEXT:    sete %r8b
-; CHECK-NEXT:    testb %dl, %r8b
-; CHECK-NEXT:    cmovel %edi, %r10d
-; CHECK-NEXT:    cmovel %r11d, %r9d
-; CHECK-NEXT:    movl %r9d, %r11d
-; CHECK-NEXT:    shrl $21, %r11d
-; CHECK-NEXT:    xorl %ebp, %ebp
-; CHECK-NEXT:    xorl %r14d, %r14d
-; CHECK-NEXT:    cmpl $4, %r11d
-; CHECK-NEXT:    cmovgel %ebp, %r11d
-; CHECK-NEXT:    setge %r14b
-; CHECK-NEXT:    leal (%r10,%r14), %ecx
-; CHECK-NEXT:    leal -448(,%rcx,4), %ebx
-; CHECK-NEXT:    shrl $24, %eax
-; CHECK-NEXT:    andl $-128, %eax
-; CHECK-NEXT:    orl %eax, %ebx
-; CHECK-NEXT:    orl %r11d, %ebx
-; CHECK-NEXT:    movl $134, %r15d
-; CHECK-NEXT:    subl %r10d, %r15d
-; CHECK-NEXT:    cmpl $31, %r15d
+; CHECK-NEXT:    movd %xmm0, (%rsp) # 4-byte Folded Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    movl $8, %edx
+; CHECK-NEXT:    subl %eax, %edx
+; CHECK-NEXT:    cmpl $31, %edx
 ; CHECK-NEXT:    movl $31, %ecx
-; CHECK-NEXT:    cmovbl %r15d, %ecx
-; CHECK-NEXT:    orl $8388608, %r9d # imm = 0x800000
+; CHECK-NEXT:    cmovbl %edx, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rdx), %edi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shrl %cl, %r9d
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpl $4, %r9d
-; CHECK-NEXT:    cmovgel %ebp, %r9d
-; CHECK-NEXT:    leal -112(%r10,%r14), %r10d
-; CHECK-NEXT:    setge %cl
-; CHECK-NEXT:    leal (%rax,%rcx,4), %ecx
-; CHECK-NEXT:    orl %r9d, %ecx
-; CHECK-NEXT:    testl %r10d, %r10d
-; CHECK-NEXT:    cmovgl %ebx, %ecx
-; CHECK-NEXT:    cmpl $4, %r11d
-; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    cmpl $30, %r10d
-; CHECK-NEXT:    sete %r11b
-; CHECK-NEXT:    andb %r9b, %r11b
-; CHECK-NEXT:    cmpl $31, %r10d
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    xorl %r8d, %r8d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $4, %edi
+; CHECK-NEXT:    cmovgel %r8d, %edi
 ; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    orb %r11b, %r9b
-; CHECK-NEXT:    leal 124(%rax), %r10d
-; CHECK-NEXT:    testb %r9b, %r9b
-; CHECK-NEXT:    cmovnel %r10d, %ecx
-; CHECK-NEXT:    testb %sil, %r8b
-; CHECK-NEXT:    cmovnel %eax, %ecx
-; CHECK-NEXT:    cmpl $255, %edi
-; CHECK-NEXT:    sete %al
-; CHECK-NEXT:    testb %sil, %al
-; CHECK-NEXT:    cmovnel %r10d, %ecx
-; CHECK-NEXT:    testb %dl, %al
+; CHECK-NEXT:    movd (%rsp), %xmm0 # 4-byte Folded Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movd %xmm0, %ecx
+; CHECK-NEXT:    movl %ecx, %esi
+; CHECK-NEXT:    shrl $24, %esi
+; CHECK-NEXT:    andl $-128, %esi
+; CHECK-NEXT:    leal (%rsi,%r9,4), %r9d
+; CHECK-NEXT:    orl %edi, %r9d
+; CHECK-NEXT:    shrl $21, %edx
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    cmovgel %r8d, %edx
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    leal (%rax,%r10), %edi
+; CHECK-NEXT:    leal 56(,%rdi,4), %edi
+; CHECK-NEXT:    orl %esi, %edi
+; CHECK-NEXT:    orl %edx, %edi
+; CHECK-NEXT:    leal 14(%rax,%r10), %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    cmovlel %r9d, %edi
+; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    cmpl $30, %eax
+; CHECK-NEXT:    sete %r8b
+; CHECK-NEXT:    andb %dl, %r8b
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %r8b, %al
+; CHECK-NEXT:    leal 124(%rsi), %edx
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    cmovnel %edx, %edi
+; CHECK-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
+; CHECK-NEXT:    cmovel %esi, %edi
+; CHECK-NEXT:    cmpl $2139095040, %ecx # imm = 0x7F800000
+; CHECK-NEXT:    cmovel %edx, %edi
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    cmovlel %edi, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    popq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    popq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    popq %rcx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
@@ -518,373 +206,308 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $152, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 208
 ; CHECK-NEXT:    .cfi_offset %rbx, -56
 ; CHECK-NEXT:    .cfi_offset %r12, -48
 ; CHECK-NEXT:    .cfi_offset %r13, -40
 ; CHECK-NEXT:    .cfi_offset %r14, -32
 ; CHECK-NEXT:    .cfi_offset %r15, -24
 ; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movaps %xmm0, %xmm1
-; CHECK-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; CHECK-NEXT:    movd %xmm1, %ecx
-; CHECK-NEXT:    movl %ecx, %eax
-; CHECK-NEXT:    movq %rcx, %rdx
-; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    andl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-NEXT:    bsrl %eax, %ecx
-; CHECK-NEXT:    xorl $31, %ecx
-; CHECK-NEXT:    movl $9, %esi
-; CHECK-NEXT:    subl %ecx, %esi
-; CHECK-NEXT:    addl $-8, %ecx
-; CHECK-NEXT:    movl %eax, %r10d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r10d
-; CHECK-NEXT:    andl $8388607, %r10d # imm = 0x7FFFFF
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
-; CHECK-NEXT:    setne %cl
-; CHECK-NEXT:    # kill: def $edx killed $edx killed $rdx
-; CHECK-NEXT:    shrl $23, %edx
-; CHECK-NEXT:    movzbl %dl, %edx
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    sete %dil
-; CHECK-NEXT:    movb %dil, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
-; CHECK-NEXT:    testb %cl, %dil
-; CHECK-NEXT:    cmovel %eax, %r10d
-; CHECK-NEXT:    cmovel %edx, %esi
-; CHECK-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    movl $149, %eax
-; CHECK-NEXT:    subl %esi, %eax
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $23, %eax
+; CHECK-NEXT:    subl %ecx, %eax
 ; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    movl $31, %r13d
-; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    movl $31, %ebp
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    leal 8388608(%r10), %ebp
-; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    movd %xmm0, %r13d
+; CHECK-NEXT:    movl %r13d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %ebx
+; CHECK-NEXT:    movl %ebx, %edx
 ; CHECK-NEXT:    shrl %cl, %edx
 ; CHECK-NEXT:    movl $1, %esi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    shll %cl, %esi
 ; CHECK-NEXT:    decl %esi
 ; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    testl %esi, %ebx
 ; CHECK-NEXT:    setne %dil
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %ebp
-; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    orl %edi, %ebp
-; CHECK-NEXT:    andl %edx, %ebp
-; CHECK-NEXT:    movaps %xmm0, %xmm1
-; CHECK-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
-; CHECK-NEXT:    movd %xmm1, %ecx
-; CHECK-NEXT:    movl %ecx, %esi
-; CHECK-NEXT:    movq %rcx, %rbx
-; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
-; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
-; CHECK-NEXT:    setne %r8b
-; CHECK-NEXT:    movd %xmm0, %ecx
-; CHECK-NEXT:    movl %ecx, %edx
-; CHECK-NEXT:    movq %rcx, %r14
-; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
-; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
-; CHECK-NEXT:    setne %dil
-; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    shrl %cl, %ebx
+; CHECK-NEXT:    movl %ebx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    orl %edi, %ebx
+; CHECK-NEXT:    andl %edx, %ebx
+; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %r9d, %ebp
-; CHECK-NEXT:    bsrl %esi, %ecx
-; CHECK-NEXT:    xorl $31, %ecx
-; CHECK-NEXT:    movl $9, %r11d
-; CHECK-NEXT:    subl %ecx, %r11d
-; CHECK-NEXT:    addl $-8, %ecx
-; CHECK-NEXT:    movl %esi, %r12d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r12d
-; CHECK-NEXT:    andl $8388607, %r12d # imm = 0x7FFFFF
-; CHECK-NEXT:    movl %ebx, %eax
-; CHECK-NEXT:    shrl $23, %eax
-; CHECK-NEXT:    movzbl %al, %eax
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    sete %cl
-; CHECK-NEXT:    movb %cl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
-; CHECK-NEXT:    testb %r8b, %cl
-; CHECK-NEXT:    cmovel %esi, %r12d
-; CHECK-NEXT:    cmovel %eax, %r11d
-; CHECK-NEXT:    movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    movl $149, %eax
-; CHECK-NEXT:    subl %r11d, %eax
+; CHECK-NEXT:    cmovbl %ecx, %ebx
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1,1]
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $23, %eax
+; CHECK-NEXT:    subl %ecx, %eax
 ; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmovael %ebp, %eax
+; CHECK-NEXT:    movl $31, %ebp
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    leal 8388608(%r12), %r11d
-; CHECK-NEXT:    movl %r11d, %esi
-; CHECK-NEXT:    shrl %cl, %esi
-; CHECK-NEXT:    movl $1, %r8d
+; CHECK-NEXT:    movd %xmm0, %r12d
+; CHECK-NEXT:    movl %r12d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %r15d
+; CHECK-NEXT:    movl %r15d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r8d
-; CHECK-NEXT:    decl %r8d
-; CHECK-NEXT:    xorl %ebx, %ebx
-; CHECK-NEXT:    testl %r8d, %r11d
-; CHECK-NEXT:    setne %bl
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %r15d
+; CHECK-NEXT:    setne %dil
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r11d
-; CHECK-NEXT:    movl %r11d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %r11d
-; CHECK-NEXT:    orl %ebx, %r11d
-; CHECK-NEXT:    andl %esi, %r11d
+; CHECK-NEXT:    shrl %cl, %r15d
+; CHECK-NEXT:    movl %r15d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r15d
+; CHECK-NEXT:    orl %edi, %r15d
+; CHECK-NEXT:    andl %edx, %r15d
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %r9d, %r11d
-; CHECK-NEXT:    bsrl %edx, %ecx
-; CHECK-NEXT:    xorl $31, %ecx
-; CHECK-NEXT:    movl $9, %esi
-; CHECK-NEXT:    subl %ecx, %esi
-; CHECK-NEXT:    addl $-8, %ecx
-; CHECK-NEXT:    movl %edx, %r8d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r8d
-; CHECK-NEXT:    andl $8388607, %r8d # imm = 0x7FFFFF
-; CHECK-NEXT:    movl %r14d, %eax
-; CHECK-NEXT:    shrl $23, %eax
-; CHECK-NEXT:    movzbl %al, %eax
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    sete %cl
-; CHECK-NEXT:    movb %cl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
-; CHECK-NEXT:    testb %dil, %cl
-; CHECK-NEXT:    cmovel %edx, %r8d
-; CHECK-NEXT:    cmovel %eax, %esi
-; CHECK-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    movl $149, %eax
-; CHECK-NEXT:    subl %esi, %eax
+; CHECK-NEXT:    cmovbl %r14d, %r15d
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $23, %eax
+; CHECK-NEXT:    subl %ecx, %eax
 ; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmovael %ebp, %eax
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    leal 8388608(%r8), %r14d
+; CHECK-NEXT:    movd %xmm0, %r14d
 ; CHECK-NEXT:    movl %r14d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
 ; CHECK-NEXT:    shrl %cl, %edx
-; CHECK-NEXT:    movl $1, %edi
+; CHECK-NEXT:    movl $1, %esi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %edi
-; CHECK-NEXT:    decl %edi
-; CHECK-NEXT:    xorl %ebx, %ebx
-; CHECK-NEXT:    testl %edi, %r14d
-; CHECK-NEXT:    setne %bl
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    setne %dil
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r14d
-; CHECK-NEXT:    movl %r14d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %r14d
-; CHECK-NEXT:    orl %ebx, %r14d
-; CHECK-NEXT:    andl %edx, %r14d
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %r9d, %r14d
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %ebp
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; CHECK-NEXT:    movd %xmm0, %ecx
-; CHECK-NEXT:    movl %ecx, %eax
-; CHECK-NEXT:    movq %rcx, %rdx
-; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    andl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-NEXT:    bsrl %eax, %ecx
-; CHECK-NEXT:    xorl $31, %ecx
-; CHECK-NEXT:    movl $9, %r15d
-; CHECK-NEXT:    subl %ecx, %r15d
-; CHECK-NEXT:    addl $-8, %ecx
-; CHECK-NEXT:    movl %eax, %edi
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %edi
-; CHECK-NEXT:    andl $8388607, %edi # imm = 0x7FFFFF
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    sete {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill
-; CHECK-NEXT:    setne %cl
-; CHECK-NEXT:    movl %edx, %ebx
-; CHECK-NEXT:    shrl $23, %ebx
-; CHECK-NEXT:    movzbl %bl, %ebx
-; CHECK-NEXT:    testl %ebx, %ebx
-; CHECK-NEXT:    sete %dl
-; CHECK-NEXT:    movb %dl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
-; CHECK-NEXT:    testb %cl, %dl
-; CHECK-NEXT:    cmovel %eax, %edi
-; CHECK-NEXT:    cmovel %ebx, %r15d
-; CHECK-NEXT:    movl $149, %edx
-; CHECK-NEXT:    subl %r15d, %edx
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    movl $23, %edx
+; CHECK-NEXT:    subl %eax, %edx
 ; CHECK-NEXT:    cmpl $31, %edx
-; CHECK-NEXT:    cmovael %r13d, %edx
+; CHECK-NEXT:    movl $31, %eax
+; CHECK-NEXT:    cmovael %eax, %edx
 ; CHECK-NEXT:    cmpl $1, %edx
 ; CHECK-NEXT:    movl %edx, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    leal 8388608(%rdi), %r13d
-; CHECK-NEXT:    movl %r13d, %ebx
-; CHECK-NEXT:    shrl %cl, %ebx
-; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    movl %eax, %esi
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rsi), %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    shrl %cl, %r8d
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %eax
-; CHECK-NEXT:    decl %eax
-; CHECK-NEXT:    xorl %esi, %esi
-; CHECK-NEXT:    testl %eax, %r13d
-; CHECK-NEXT:    setne %sil
+; CHECK-NEXT:    movl $1, %r9d
+; CHECK-NEXT:    shll %cl, %r9d
+; CHECK-NEXT:    decl %r9d
+; CHECK-NEXT:    movl %r9d, %ecx
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testl %ecx, %edi
+; CHECK-NEXT:    setne %r9b
 ; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    shrl %cl, %r13d
-; CHECK-NEXT:    movl %r13d, %ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    movl %edi, %ecx
 ; CHECK-NEXT:    andl $1, %ecx
-; CHECK-NEXT:    orl %esi, %ecx
-; CHECK-NEXT:    andl %ebx, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    andl %r8d, %ecx
 ; CHECK-NEXT:    cmpl $1, %edx
 ; CHECK-NEXT:    movl $0, %edx
 ; CHECK-NEXT:    cmovbl %edx, %ecx
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $2, %ebp
-; CHECK-NEXT:    cmovgel %edx, %ebp
-; CHECK-NEXT:    movl $0, %ebx
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    addl %eax, %eax
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
-; CHECK-NEXT:    shrl $31, %edx
-; CHECK-NEXT:    leal (%rax,%rdx,8), %r9d
-; CHECK-NEXT:    movq %rdx, %rax
-; CHECK-NEXT:    orl %ebp, %r9d
-; CHECK-NEXT:    movl %r10d, %edx
-; CHECK-NEXT:    shrl $22, %edx
-; CHECK-NEXT:    xorl %esi, %esi
-; CHECK-NEXT:    testl $2097151, %r10d # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %sil
-; CHECK-NEXT:    orl %edx, %esi
-; CHECK-NEXT:    shrl $21, %r10d
-; CHECK-NEXT:    andl %esi, %r10d
-; CHECK-NEXT:    addl %edx, %r10d
-; CHECK-NEXT:    xorl %edx, %edx
-; CHECK-NEXT:    cmpl $2, %r10d
-; CHECK-NEXT:    cmovgel %ebx, %r10d
-; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload
-; CHECK-NEXT:    leal (%rbp,%rdx), %esi
-; CHECK-NEXT:    leal -252(%rsi,%rsi), %esi
-; CHECK-NEXT:    shll $3, %eax
-; CHECK-NEXT:    orl %eax, %r10d
-; CHECK-NEXT:    orl %esi, %r10d
-; CHECK-NEXT:    leal -126(%rbp,%rdx), %edx
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    cmovlel %r9d, %r10d
-; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %edx # 1-byte Folded Reload
-; CHECK-NEXT:    testb %dl, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
-; CHECK-NEXT:    cmovnel %eax, %r10d
-; CHECK-NEXT:    movd %r10d, %xmm1
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebx # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $2, %ebx
+; CHECK-NEXT:    cmovgel %edx, %ebx
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    addl %r10d, %r10d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm0, %r9d
+; CHECK-NEXT:    movl %r9d, %r8d
+; CHECK-NEXT:    shrl $31, %r8d
+; CHECK-NEXT:    leal (%r10,%r8,8), %r10d
+; CHECK-NEXT:    orl %ebx, %r10d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
+; CHECK-NEXT:    shrl $22, %ebx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $2097151, %r13d # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ebx, %r11d
+; CHECK-NEXT:    shrl $21, %r13d
+; CHECK-NEXT:    andl %r11d, %r13d
+; CHECK-NEXT:    addl %ebx, %r13d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    cmpl $2, %r13d
+; CHECK-NEXT:    cmovgel %edx, %r13d
+; CHECK-NEXT:    setge %r11b
 ; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $2, %r11d
-; CHECK-NEXT:    cmovgel %ebx, %r11d
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    addl %eax, %eax
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload
-; CHECK-NEXT:    shrl $31, %r9d
-; CHECK-NEXT:    leal (%rax,%r9,8), %eax
-; CHECK-NEXT:    orl %r11d, %eax
-; CHECK-NEXT:    movl %r12d, %edx
-; CHECK-NEXT:    shrl $22, %edx
-; CHECK-NEXT:    xorl %esi, %esi
+; CHECK-NEXT:    shll $3, %r8d
+; CHECK-NEXT:    orl %r8d, %r13d
+; CHECK-NEXT:    leal (%r11,%r11), %ebx
+; CHECK-NEXT:    orl %ebx, %r13d
+; CHECK-NEXT:    testl %r11d, %r11d
+; CHECK-NEXT:    cmovlel %r10d, %r13d
+; CHECK-NEXT:    testl $2147483647, %r9d # imm = 0x7FFFFFFF
+; CHECK-NEXT:    cmovel %r8d, %r13d
+; CHECK-NEXT:    movd %r13d, %xmm1
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r15d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $2, %r15d
+; CHECK-NEXT:    cmovgel %edx, %r15d
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    addl %r10d, %r10d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm0, %r9d
+; CHECK-NEXT:    movl %r9d, %r8d
+; CHECK-NEXT:    shrl $31, %r8d
+; CHECK-NEXT:    leal (%r10,%r8,8), %r10d
+; CHECK-NEXT:    orl %r15d, %r10d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
+; CHECK-NEXT:    shrl $22, %ebx
+; CHECK-NEXT:    xorl %r11d, %r11d
 ; CHECK-NEXT:    testl $2097151, %r12d # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %sil
-; CHECK-NEXT:    orl %edx, %esi
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ebx, %r11d
 ; CHECK-NEXT:    shrl $21, %r12d
-; CHECK-NEXT:    andl %esi, %r12d
-; CHECK-NEXT:    addl %edx, %r12d
-; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    andl %r11d, %r12d
+; CHECK-NEXT:    addl %ebx, %r12d
+; CHECK-NEXT:    xorl %r11d, %r11d
 ; CHECK-NEXT:    cmpl $2, %r12d
-; CHECK-NEXT:    cmovgel %ebx, %r12d
-; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload
-; CHECK-NEXT:    leal (%r10,%rdx), %esi
-; CHECK-NEXT:    leal -252(%rsi,%rsi), %esi
-; CHECK-NEXT:    shll $3, %r9d
-; CHECK-NEXT:    orl %r9d, %r12d
-; CHECK-NEXT:    orl %esi, %r12d
-; CHECK-NEXT:    leal -126(%r10,%rdx), %edx
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    cmovlel %eax, %r12d
-; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
-; CHECK-NEXT:    testb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
-; CHECK-NEXT:    cmovnel %r9d, %r12d
+; CHECK-NEXT:    cmovgel %edx, %r12d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
+; CHECK-NEXT:    shll $3, %r8d
+; CHECK-NEXT:    orl %r8d, %r12d
+; CHECK-NEXT:    leal (%r11,%r11), %ebx
+; CHECK-NEXT:    orl %ebx, %r12d
+; CHECK-NEXT:    testl %r11d, %r11d
+; CHECK-NEXT:    cmovlel %r10d, %r12d
+; CHECK-NEXT:    testl $2147483647, %r9d # imm = 0x7FFFFFFF
+; CHECK-NEXT:    cmovel %r8d, %r12d
 ; CHECK-NEXT:    movd %r12d, %xmm2
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $2, %ebp
+; CHECK-NEXT:    cmovgel %edx, %ebp
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    addl %r10d, %r10d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm0, %r9d
+; CHECK-NEXT:    movl %r9d, %r8d
+; CHECK-NEXT:    shrl $31, %r8d
+; CHECK-NEXT:    leal (%r10,%r8,8), %r10d
+; CHECK-NEXT:    orl %ebp, %r10d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
+; CHECK-NEXT:    shrl $22, %ebx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $2097151, %r14d # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ebx, %r11d
+; CHECK-NEXT:    shrl $21, %r14d
+; CHECK-NEXT:    andl %r11d, %r14d
+; CHECK-NEXT:    addl %ebx, %r14d
+; CHECK-NEXT:    xorl %r11d, %r11d
 ; CHECK-NEXT:    cmpl $2, %r14d
-; CHECK-NEXT:    cmovgel %ebx, %r14d
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    addl %eax, %eax
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload
-; CHECK-NEXT:    shrl $31, %r9d
-; CHECK-NEXT:    leal (%rax,%r9,8), %eax
-; CHECK-NEXT:    orl %r14d, %eax
-; CHECK-NEXT:    movl %r8d, %edx
-; CHECK-NEXT:    shrl $22, %edx
-; CHECK-NEXT:    xorl %esi, %esi
-; CHECK-NEXT:    testl $2097151, %r8d # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %sil
-; CHECK-NEXT:    orl %edx, %esi
-; CHECK-NEXT:    shrl $21, %r8d
-; CHECK-NEXT:    andl %esi, %r8d
-; CHECK-NEXT:    addl %edx, %r8d
-; CHECK-NEXT:    xorl %edx, %edx
-; CHECK-NEXT:    cmpl $2, %r8d
-; CHECK-NEXT:    cmovgel %ebx, %r8d
-; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload
-; CHECK-NEXT:    leal (%r10,%rdx), %esi
-; CHECK-NEXT:    leal -252(%rsi,%rsi), %esi
-; CHECK-NEXT:    shll $3, %r9d
-; CHECK-NEXT:    orl %r9d, %r8d
-; CHECK-NEXT:    orl %esi, %r8d
-; CHECK-NEXT:    leal -126(%r10,%rdx), %edx
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    cmovlel %eax, %r8d
-; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
-; CHECK-NEXT:    testb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
-; CHECK-NEXT:    cmovnel %r9d, %r8d
-; CHECK-NEXT:    movd %r8d, %xmm0
-; CHECK-NEXT:    addl %r13d, %ecx
-; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmovgel %edx, %r14d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
+; CHECK-NEXT:    leal (%r11,%r11), %ebx
+; CHECK-NEXT:    shll $3, %r8d
+; CHECK-NEXT:    orl %r8d, %r14d
+; CHECK-NEXT:    orl %ebx, %r14d
+; CHECK-NEXT:    testl %r11d, %r11d
+; CHECK-NEXT:    cmovlel %r10d, %r14d
+; CHECK-NEXT:    testl $2147483647, %r9d # imm = 0x7FFFFFFF
+; CHECK-NEXT:    cmovel %r8d, %r14d
+; CHECK-NEXT:    movd %r14d, %xmm0
+; CHECK-NEXT:    addl %edi, %ecx
+; CHECK-NEXT:    xorl %r9d, %r9d
 ; CHECK-NEXT:    cmpl $2, %ecx
-; CHECK-NEXT:    cmovgel %ebx, %ecx
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    addl %eax, %eax
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload
-; CHECK-NEXT:    shrl $31, %esi
-; CHECK-NEXT:    leal (%rax,%rsi,8), %eax
-; CHECK-NEXT:    orl %ecx, %eax
-; CHECK-NEXT:    movl %edi, %ecx
-; CHECK-NEXT:    shrl $22, %ecx
-; CHECK-NEXT:    xorl %edx, %edx
-; CHECK-NEXT:    testl $2097151, %edi # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %dl
-; CHECK-NEXT:    orl %ecx, %edx
-; CHECK-NEXT:    shrl $21, %edi
-; CHECK-NEXT:    andl %edx, %edi
-; CHECK-NEXT:    addl %ecx, %edi
+; CHECK-NEXT:    cmovgel %edx, %ecx
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    addl %r9d, %r9d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm3, %r8d
+; CHECK-NEXT:    movl %r8d, %edi
+; CHECK-NEXT:    shrl $31, %edi
+; CHECK-NEXT:    leal (%r9,%rdi,8), %r9d
+; CHECK-NEXT:    orl %ecx, %r9d
+; CHECK-NEXT:    shrl $22, %esi
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpl $2, %edi
-; CHECK-NEXT:    cmovgel %ebx, %edi
+; CHECK-NEXT:    testl $2097151, %eax # imm = 0x1FFFFF
+; CHECK-NEXT:    setne %cl
+; CHECK-NEXT:    orl %esi, %ecx
+; CHECK-NEXT:    shrl $21, %eax
+; CHECK-NEXT:    andl %ecx, %eax
+; CHECK-NEXT:    addl %esi, %eax
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $2, %eax
+; CHECK-NEXT:    cmovgel %edx, %eax
 ; CHECK-NEXT:    setge %cl
-; CHECK-NEXT:    leal -126(%r15,%rcx), %edx
-; CHECK-NEXT:    addl %ecx, %r15d
-; CHECK-NEXT:    leal -252(%r15,%r15), %ecx
-; CHECK-NEXT:    shll $3, %esi
-; CHECK-NEXT:    orl %esi, %edi
-; CHECK-NEXT:    orl %ecx, %edi
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    cmovlel %eax, %edi
-; CHECK-NEXT:    movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
-; CHECK-NEXT:    testb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Reload
-; CHECK-NEXT:    cmovnel %esi, %edi
-; CHECK-NEXT:    movd %edi, %xmm3
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; CHECK-NEXT:    leal (%rcx,%rcx), %edx
+; CHECK-NEXT:    shll $3, %edi
+; CHECK-NEXT:    orl %edi, %eax
+; CHECK-NEXT:    orl %edx, %eax
+; CHECK-NEXT:    testl %ecx, %ecx
+; CHECK-NEXT:    cmovlel %r9d, %eax
+; CHECK-NEXT:    testl $2147483647, %r8d # imm = 0x7FFFFFFF
+; CHECK-NEXT:    cmovel %edi, %eax
+; CHECK-NEXT:    movd %eax, %xmm3
 ; CHECK-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
 ; CHECK-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
 ; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; CHECK-NEXT:    addq $152, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
 ; CHECK-NEXT:    popq %r12
@@ -910,131 +533,124 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    pushq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
 ; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    pushq %r13
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    subq $16, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
-; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 56
-; CHECK-NEXT:    .cfi_offset %rbx, -56
-; CHECK-NEXT:    .cfi_offset %r12, -48
-; CHECK-NEXT:    .cfi_offset %r13, -40
-; CHECK-NEXT:    .cfi_offset %r14, -32
-; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbx, -32
+; CHECK-NEXT:    .cfi_offset %r14, -24
 ; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    pextrw $0, %xmm0, %eax
-; CHECK-NEXT:    movl %eax, %r11d
-; CHECK-NEXT:    andl $1023, %r11d # imm = 0x3FF
-; CHECK-NEXT:    bsrw %r11w, %si
-; CHECK-NEXT:    xorl $15, %esi
-; CHECK-NEXT:    leal -5(%rsi), %ecx
-; CHECK-NEXT:    movl %r11d, %edx
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %edx
-; CHECK-NEXT:    andl $1023, %edx # imm = 0x3FF
-; CHECK-NEXT:    movl $6, %r10d
-; CHECK-NEXT:    subl %esi, %r10d
-; CHECK-NEXT:    testl %r11d, %r11d
-; CHECK-NEXT:    sete %dil
-; CHECK-NEXT:    setne %r13b
-; CHECK-NEXT:    movl %eax, %r8d
-; CHECK-NEXT:    shrl $10, %r8d
-; CHECK-NEXT:    andl $31, %r8d
-; CHECK-NEXT:    sete %r9b
-; CHECK-NEXT:    testb %r13b, %r9b
-; CHECK-NEXT:    cmovel %r11d, %edx
-; CHECK-NEXT:    cmovel %r8d, %r10d
-; CHECK-NEXT:    movl $9, %r11d
-; CHECK-NEXT:    subl %r10d, %r11d
-; CHECK-NEXT:    cmpw $15, %r11w
-; CHECK-NEXT:    movl $15, %ecx
-; CHECK-NEXT:    cmovbl %r11d, %ecx
-; CHECK-NEXT:    movl %ecx, %ebx
-; CHECK-NEXT:    leal 1024(%rdx), %r11d
-; CHECK-NEXT:    movl %r11d, %ebp
-; CHECK-NEXT:    shrl %cl, %ebp
-; CHECK-NEXT:    movl %ebp, %r14d
-; CHECK-NEXT:    andl $1, %r14d
-; CHECK-NEXT:    cmpw $1, %cx
+; CHECK-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    callq __truncsfhf2 at PLT
+; CHECK-NEXT:    pextrw $0, %xmm0, %edi
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    andl $31744, %eax # imm = 0x7C00
+; CHECK-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    pextrw $0, %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %esi
+; CHECK-NEXT:    andl $32767, %esi # imm = 0x7FFF
+; CHECK-NEXT:    cmpl $1024, %esi # imm = 0x400
+; CHECK-NEXT:    cmovael %edx, %edi
+; CHECK-NEXT:    cmovael %esi, %eax
+; CHECK-NEXT:    shrl $10, %eax
+; CHECK-NEXT:    leal -12(%rax), %r8d
+; CHECK-NEXT:    cmpl $1024, %esi # imm = 0x400
+; CHECK-NEXT:    cmovael %eax, %r8d
+; CHECK-NEXT:    addl $-14, %r8d
+; CHECK-NEXT:    andl $33791, %edi # imm = 0x83FF
+; CHECK-NEXT:    orl $14336, %edi # imm = 0x3800
+; CHECK-NEXT:    leal -31744(%rsi), %eax
+; CHECK-NEXT:    movzwl %ax, %eax
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $33792, %eax # imm = 0x8400
+; CHECK-NEXT:    cmovbel %r9d, %r8d
+; CHECK-NEXT:    cmovbel %edx, %edi
+; CHECK-NEXT:    movl $-5, %ecx
+; CHECK-NEXT:    subl %r8d, %ecx
+; CHECK-NEXT:    cmpw $15, %cx
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    cmovbl %ecx, %eax
+; CHECK-NEXT:    cmpw $1, %ax
+; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movl $1, %r15d
-; CHECK-NEXT:    shll %cl, %r15d
-; CHECK-NEXT:    decl %r15d
-; CHECK-NEXT:    xorl %r12d, %r12d
-; CHECK-NEXT:    testw %r15w, %r11w
-; CHECK-NEXT:    setne %r12b
-; CHECK-NEXT:    orl %r14d, %r12d
+; CHECK-NEXT:    movl %edi, %r10d
+; CHECK-NEXT:    andl $1023, %r10d # imm = 0x3FF
+; CHECK-NEXT:    leal 1024(%r10), %r11d
+; CHECK-NEXT:    movl %r11d, %ebx
+; CHECK-NEXT:    shrl %cl, %ebx
+; CHECK-NEXT:    movl $1, %ebp
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %ebp
+; CHECK-NEXT:    decl %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    testw %bp, %r11w
+; CHECK-NEXT:    setne %r14b
+; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    shrl %cl, %r11d
-; CHECK-NEXT:    andl %r12d, %r11d
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpw $1, %bx
-; CHECK-NEXT:    cmovbl %ecx, %r11d
-; CHECK-NEXT:    addl %ebp, %r11d
-; CHECK-NEXT:    xorl %ebx, %ebx
-; CHECK-NEXT:    cmpw $4, %r11w
-; CHECK-NEXT:    cmovgel %ecx, %r11d
-; CHECK-NEXT:    setge %bl
-; CHECK-NEXT:    shrl $8, %eax
-; CHECK-NEXT:    andl $128, %eax
-; CHECK-NEXT:    leal (%rax,%rbx,4), %ebx
-; CHECK-NEXT:    orl %r11d, %ebx
-; CHECK-NEXT:    movzbl %dh, %esi
-; CHECK-NEXT:    movl %esi, %ebp
-; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    movl %r11d, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    orl %r14d, %ecx
+; CHECK-NEXT:    andl %ebx, %ecx
+; CHECK-NEXT:    cmpw $1, %ax
+; CHECK-NEXT:    cmovbl %r9d, %ecx
+; CHECK-NEXT:    addl %r11d, %ecx
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpw $4, %cx
+; CHECK-NEXT:    cmovgel %r9d, %ecx
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    shrl $8, %edx
+; CHECK-NEXT:    andl $128, %edx
+; CHECK-NEXT:    leal (%rdx,%rax,4), %eax
+; CHECK-NEXT:    orl %ecx, %eax
+; CHECK-NEXT:    shrl $8, %r10d
+; CHECK-NEXT:    movl %r10d, %ecx
+; CHECK-NEXT:    andl $1, %ecx
 ; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    testb $127, %dl
+; CHECK-NEXT:    testb $127, %dil
 ; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %ebp, %r11d
-; CHECK-NEXT:    shrl $7, %edx
-; CHECK-NEXT:    andl %r11d, %edx
-; CHECK-NEXT:    addl %esi, %edx
-; CHECK-NEXT:    xorl %esi, %esi
-; CHECK-NEXT:    cmpw $4, %dx
-; CHECK-NEXT:    cmovgel %ecx, %edx
+; CHECK-NEXT:    orl %ecx, %r11d
+; CHECK-NEXT:    shrl $7, %edi
+; CHECK-NEXT:    andl %r11d, %edi
+; CHECK-NEXT:    addl %r10d, %edi
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpw $4, %di
+; CHECK-NEXT:    cmovgel %r9d, %edi
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    leal (%r8,%r10), %ecx
+; CHECK-NEXT:    leal 56(,%rcx,4), %r9d
 ; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    setge %sil
-; CHECK-NEXT:    addl %r10d, %esi
-; CHECK-NEXT:    movl %esi, %r10d
-; CHECK-NEXT:    shll $2, %r10d
-; CHECK-NEXT:    orl %eax, %edx
-; CHECK-NEXT:    orl %r10d, %edx
-; CHECK-NEXT:    testw %si, %si
-; CHECK-NEXT:    cmovlel %ebx, %edx
-; CHECK-NEXT:    cmpw $4, %cx
-; CHECK-NEXT:    setge %cl
-; CHECK-NEXT:    cmpw $30, %si
-; CHECK-NEXT:    sete %r10b
-; CHECK-NEXT:    andb %cl, %r10b
-; CHECK-NEXT:    cmpw $31, %si
-; CHECK-NEXT:    setge %cl
-; CHECK-NEXT:    orb %r10b, %cl
-; CHECK-NEXT:    leal 124(%rax), %esi
-; CHECK-NEXT:    testb %cl, %cl
-; CHECK-NEXT:    cmovnel %esi, %edx
-; CHECK-NEXT:    testb %dil, %r9b
-; CHECK-NEXT:    cmovnel %eax, %edx
+; CHECK-NEXT:    orl %edi, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    leal 14(%r8,%r10), %r8d
+; CHECK-NEXT:    testw %r8w, %r8w
+; CHECK-NEXT:    cmovlel %eax, %ecx
+; CHECK-NEXT:    cmpw $4, %di
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    cmpw $30, %r8w
+; CHECK-NEXT:    sete %dil
+; CHECK-NEXT:    andb %al, %dil
 ; CHECK-NEXT:    cmpw $31, %r8w
-; CHECK-NEXT:    sete %al
-; CHECK-NEXT:    testb %dil, %al
-; CHECK-NEXT:    cmovnel %esi, %edx
-; CHECK-NEXT:    testb %r13b, %al
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %dil, %al
+; CHECK-NEXT:    leal 124(%rdx), %edi
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    cmovnel %edi, %ecx
+; CHECK-NEXT:    testl %esi, %esi
+; CHECK-NEXT:    cmovel %edx, %ecx
+; CHECK-NEXT:    cmpl $31744, %esi # imm = 0x7C00
+; CHECK-NEXT:    cmovel %edi, %ecx
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovel %edx, %eax
+; CHECK-NEXT:    cmovlel %ecx, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    popq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 48
-; CHECK-NEXT:    popq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    addq $16, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    popq %r14
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    popq %rbp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
@@ -1049,130 +665,101 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    pushq %rax
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    pushq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 48
-; CHECK-NEXT:    .cfi_offset %rbx, -48
-; CHECK-NEXT:    .cfi_offset %r12, -40
-; CHECK-NEXT:    .cfi_offset %r14, -32
-; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbx, -24
 ; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    pextrw $0, %xmm0, %edx
-; CHECK-NEXT:    movl %edx, %eax
-; CHECK-NEXT:    andl $127, %eax
-; CHECK-NEXT:    shll $16, %eax
-; CHECK-NEXT:    bsrl %eax, %esi
-; CHECK-NEXT:    xorl $31, %esi
-; CHECK-NEXT:    leal -8(%rsi), %ecx
-; CHECK-NEXT:    movl %eax, %r9d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %r9d
-; CHECK-NEXT:    andl $8323072, %r9d # imm = 0x7F0000
-; CHECK-NEXT:    movl $9, %r11d
-; CHECK-NEXT:    subl %esi, %r11d
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    sete %dil
-; CHECK-NEXT:    setne %sil
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    shrl $7, %ecx
-; CHECK-NEXT:    movzbl %cl, %r8d
-; CHECK-NEXT:    testl %r8d, %r8d
-; CHECK-NEXT:    sete %r10b
-; CHECK-NEXT:    testb %sil, %r10b
-; CHECK-NEXT:    cmovel %eax, %r9d
-; CHECK-NEXT:    cmovel %r8d, %r11d
-; CHECK-NEXT:    leal 8388608(%r9), %ebx
-; CHECK-NEXT:    movl $134, %ecx
-; CHECK-NEXT:    subl %r11d, %ecx
+; CHECK-NEXT:    pextrw $0, %xmm0, %ebx
+; CHECK-NEXT:    movl %ebx, %ebp
+; CHECK-NEXT:    shll $16, %ebp
+; CHECK-NEXT:    movd %ebp, %xmm0
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx
+; CHECK-NEXT:    movl $8, %ecx
+; CHECK-NEXT:    subl %edx, %ecx
 ; CHECK-NEXT:    cmpl $31, %ecx
 ; CHECK-NEXT:    movl $31, %eax
 ; CHECK-NEXT:    cmovbl %ecx, %eax
-; CHECK-NEXT:    movl %ebx, %ebp
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %ebp
-; CHECK-NEXT:    movl %ebp, %r14d
-; CHECK-NEXT:    andl $1, %r14d
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movl $1, %r15d
-; CHECK-NEXT:    shll %cl, %r15d
-; CHECK-NEXT:    decl %r15d
-; CHECK-NEXT:    xorl %r12d, %r12d
-; CHECK-NEXT:    testl %r15d, %ebx
-; CHECK-NEXT:    setne %r12b
-; CHECK-NEXT:    orl %r14d, %r12d
+; CHECK-NEXT:    movd %xmm0, %esi
+; CHECK-NEXT:    movl %esi, %edi
+; CHECK-NEXT:    andl $8388607, %edi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rdi), %r8d
+; CHECK-NEXT:    movl %r8d, %r9d
+; CHECK-NEXT:    shrl %cl, %r9d
+; CHECK-NEXT:    movl $1, %r10d
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shrl %cl, %ebx
-; CHECK-NEXT:    andl %r12d, %ebx
+; CHECK-NEXT:    shll %cl, %r10d
+; CHECK-NEXT:    decl %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl %r10d, %r8d
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    movl %r8d, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    orl %r11d, %r10d
+; CHECK-NEXT:    andl %r9d, %r10d
 ; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %ecx, %ebx
-; CHECK-NEXT:    addl %ebp, %ebx
+; CHECK-NEXT:    cmovbl %ecx, %r10d
+; CHECK-NEXT:    addl %r8d, %r10d
 ; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl $4, %ebx
-; CHECK-NEXT:    cmovgel %ecx, %ebx
+; CHECK-NEXT:    cmpl $4, %r10d
+; CHECK-NEXT:    cmovgel %ecx, %r10d
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    shrl $8, %edx
-; CHECK-NEXT:    andl $128, %edx
-; CHECK-NEXT:    leal (%rdx,%rax,4), %eax
-; CHECK-NEXT:    orl %ebx, %eax
-; CHECK-NEXT:    movl %r9d, %ebx
-; CHECK-NEXT:    shrl $21, %ebx
-; CHECK-NEXT:    movl %ebx, %ebp
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    xorl %r14d, %r14d
-; CHECK-NEXT:    testl $983040, %r9d # imm = 0xF0000
-; CHECK-NEXT:    setne %r14b
-; CHECK-NEXT:    orl %ebp, %r14d
-; CHECK-NEXT:    shrl $20, %r9d
-; CHECK-NEXT:    andl %r14d, %r9d
-; CHECK-NEXT:    addl %ebx, %r9d
-; CHECK-NEXT:    xorl %ebx, %ebx
-; CHECK-NEXT:    cmpl $4, %r9d
-; CHECK-NEXT:    cmovgel %ecx, %r9d
-; CHECK-NEXT:    setge %bl
-; CHECK-NEXT:    leal -112(%r11,%rbx), %ebp
-; CHECK-NEXT:    addl %ebx, %r11d
-; CHECK-NEXT:    leal -448(,%r11,4), %r11d
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    orl %r9d, %ecx
-; CHECK-NEXT:    orl %r11d, %ecx
-; CHECK-NEXT:    testl %ebp, %ebp
+; CHECK-NEXT:    shrl $8, %ebx
+; CHECK-NEXT:    andl $128, %ebx
+; CHECK-NEXT:    leal (%rbx,%rax,4), %eax
+; CHECK-NEXT:    orl %r10d, %eax
+; CHECK-NEXT:    shrl $21, %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    andl $1, %r8d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testl $1048575, %esi # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    orl %r8d, %r9d
+; CHECK-NEXT:    shrl $20, %esi
+; CHECK-NEXT:    andl %r9d, %esi
+; CHECK-NEXT:    addl %edi, %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    cmpl $4, %esi
+; CHECK-NEXT:    cmovgel %ecx, %esi
+; CHECK-NEXT:    setge %dil
+; CHECK-NEXT:    leal (%rdx,%rdi), %ecx
+; CHECK-NEXT:    leal 56(,%rcx,4), %r8d
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    orl %esi, %ecx
+; CHECK-NEXT:    orl %r8d, %ecx
+; CHECK-NEXT:    leal 14(%rdx,%rdi), %edx
+; CHECK-NEXT:    testl %edx, %edx
 ; CHECK-NEXT:    cmovlel %eax, %ecx
-; CHECK-NEXT:    cmpl $4, %r9d
+; CHECK-NEXT:    cmpl $4, %esi
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    cmpl $30, %ebp
-; CHECK-NEXT:    sete %r9b
-; CHECK-NEXT:    andb %al, %r9b
-; CHECK-NEXT:    cmpl $31, %ebp
+; CHECK-NEXT:    cmpl $30, %edx
+; CHECK-NEXT:    sete %sil
+; CHECK-NEXT:    andb %al, %sil
+; CHECK-NEXT:    cmpl $31, %edx
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    orb %r9b, %al
-; CHECK-NEXT:    leal 124(%rdx), %r9d
+; CHECK-NEXT:    orb %sil, %al
+; CHECK-NEXT:    leal 124(%rbx), %edx
 ; CHECK-NEXT:    testb %al, %al
-; CHECK-NEXT:    cmovnel %r9d, %ecx
-; CHECK-NEXT:    testb %dil, %r10b
 ; CHECK-NEXT:    cmovnel %edx, %ecx
-; CHECK-NEXT:    cmpl $255, %r8d
-; CHECK-NEXT:    sete %al
-; CHECK-NEXT:    testb %dil, %al
-; CHECK-NEXT:    cmovnel %r9d, %ecx
-; CHECK-NEXT:    testb %sil, %al
+; CHECK-NEXT:    andl $2147418112, %ebp # imm = 0x7FFF0000
+; CHECK-NEXT:    cmovel %ebx, %ecx
+; CHECK-NEXT:    cmpl $2139095040, %ebp # imm = 0x7F800000
+; CHECK-NEXT:    cmovel %edx, %ecx
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovel %ecx, %eax
+; CHECK-NEXT:    cmovlel %ecx, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    popq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    popq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    addq $8, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    popq %rbp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
@@ -1185,46 +772,17 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f64:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    pushq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    subq $16, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    pushq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 48
-; CHECK-NEXT:    .cfi_offset %rbx, -48
-; CHECK-NEXT:    .cfi_offset %r12, -40
-; CHECK-NEXT:    .cfi_offset %r14, -32
-; CHECK-NEXT:    .cfi_offset %r15, -24
-; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movq %xmm0, %rsi
-; CHECK-NEXT:    movabsq $4503599627370495, %rax # imm = 0xFFFFFFFFFFFFF
-; CHECK-NEXT:    movq %rsi, %rdx
-; CHECK-NEXT:    andq %rax, %rdx
-; CHECK-NEXT:    bsrq %rdx, %rdi
-; CHECK-NEXT:    xorq $63, %rdi
-; CHECK-NEXT:    leaq -11(%rdi), %rcx
-; CHECK-NEXT:    movq %rdx, %r10
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
-; CHECK-NEXT:    shlq %cl, %r10
-; CHECK-NEXT:    andq %rax, %r10
-; CHECK-NEXT:    movl $12, %ebx
-; CHECK-NEXT:    subq %rdi, %rbx
-; CHECK-NEXT:    testq %rdx, %rdx
-; CHECK-NEXT:    sete %r8b
-; CHECK-NEXT:    setne %dil
-; CHECK-NEXT:    movq %rsi, %r9
-; CHECK-NEXT:    shrq $52, %r9
-; CHECK-NEXT:    andl $2047, %r9d # imm = 0x7FF
-; CHECK-NEXT:    sete %r11b
-; CHECK-NEXT:    testb %dil, %r11b
-; CHECK-NEXT:    cmoveq %rdx, %r10
-; CHECK-NEXT:    cmoveq %r9, %rbx
-; CHECK-NEXT:    movl $1059, %ecx # imm = 0x423
-; CHECK-NEXT:    subq %rbx, %rcx
+; CHECK-NEXT:    .cfi_offset %rbx, -16
+; CHECK-NEXT:    movq %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexp at PLT
+; CHECK-NEXT:    movslq {{[0-9]+}}(%rsp), %rsi
+; CHECK-NEXT:    movl $37, %ecx
+; CHECK-NEXT:    subq %rsi, %rcx
 ; CHECK-NEXT:    cmpq $63, %rcx
 ; CHECK-NEXT:    movl $63, %eax
 ; CHECK-NEXT:    cmovbq %rcx, %rax
@@ -1232,90 +790,89 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-NEXT:    movq %rax, %rdx
 ; CHECK-NEXT:    adcq $0, %rdx
 ; CHECK-NEXT:    decl %edx
-; CHECK-NEXT:    movl $1, %r15d
+; CHECK-NEXT:    movl $1, %r10d
 ; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    shlq %cl, %r15
-; CHECK-NEXT:    decq %r15
-; CHECK-NEXT:    movabsq $4503599627370496, %r14 # imm = 0x10000000000000
-; CHECK-NEXT:    orq %r10, %r14
-; CHECK-NEXT:    xorl %ebp, %ebp
-; CHECK-NEXT:    testq %r15, %r14
-; CHECK-NEXT:    setne %bpl
-; CHECK-NEXT:    movq %r14, %r15
+; CHECK-NEXT:    shlq %cl, %r10
+; CHECK-NEXT:    decq %r10
+; CHECK-NEXT:    movq %xmm0, %rdi
+; CHECK-NEXT:    movabsq $4503599627370495, %r8 # imm = 0xFFFFFFFFFFFFF
+; CHECK-NEXT:    andq %rdi, %r8
+; CHECK-NEXT:    movabsq $4503599627370496, %r9 # imm = 0x10000000000000
+; CHECK-NEXT:    orq %r8, %r9
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testq %r10, %r9
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    movq %r9, %r10
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrq %cl, %r15
-; CHECK-NEXT:    movl %r15d, %r12d
-; CHECK-NEXT:    andl $1, %r12d
-; CHECK-NEXT:    orl %ebp, %r12d
+; CHECK-NEXT:    shrq %cl, %r10
+; CHECK-NEXT:    movl %r10d, %ebx
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    orl %r11d, %ebx
 ; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    shrq %cl, %r14
-; CHECK-NEXT:    andl %r12d, %r14d
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpq $1, %rax
-; CHECK-NEXT:    cmovbq %rcx, %r14
-; CHECK-NEXT:    addq %r15, %r14
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpq $4, %r14
-; CHECK-NEXT:    cmovgeq %rcx, %r14
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    shrq $63, %rsi
-; CHECK-NEXT:    shll $7, %esi
-; CHECK-NEXT:    leal (%rsi,%rax,4), %eax
-; CHECK-NEXT:    orq %r14, %rax
-; CHECK-NEXT:    movq %r10, %rdx
-; CHECK-NEXT:    shrq $50, %rdx
-; CHECK-NEXT:    movl %edx, %ebp
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    xorl %r14d, %r14d
-; CHECK-NEXT:    movq %r10, %r15
-; CHECK-NEXT:    shlq $15, %r15
-; CHECK-NEXT:    setne %r14b
-; CHECK-NEXT:    orl %ebp, %r14d
-; CHECK-NEXT:    shrq $49, %r10
-; CHECK-NEXT:    andl %r14d, %r10d
-; CHECK-NEXT:    addq %rdx, %r10
+; CHECK-NEXT:    shrq %cl, %r9
+; CHECK-NEXT:    andl %ebx, %r9d
 ; CHECK-NEXT:    xorl %edx, %edx
-; CHECK-NEXT:    cmpq $4, %r10
-; CHECK-NEXT:    cmovgeq %rcx, %r10
-; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    leaq -1008(%rbx,%rdx), %r14
-; CHECK-NEXT:    addq %rdx, %rbx
-; CHECK-NEXT:    leaq -4032(,%rbx,4), %rdx
-; CHECK-NEXT:    movq %rsi, %rcx
-; CHECK-NEXT:    orq %r10, %rcx
-; CHECK-NEXT:    orq %rdx, %rcx
-; CHECK-NEXT:    testq %r14, %r14
-; CHECK-NEXT:    cmovleq %rax, %rcx
-; CHECK-NEXT:    cmpq $4, %r10
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    cmpq $30, %r14
-; CHECK-NEXT:    sete %dl
-; CHECK-NEXT:    andb %al, %dl
-; CHECK-NEXT:    cmpq $31, %r14
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    orb %dl, %al
-; CHECK-NEXT:    leaq 124(%rsi), %rdx
-; CHECK-NEXT:    testb %al, %al
-; CHECK-NEXT:    cmovneq %rdx, %rcx
-; CHECK-NEXT:    testb %r8b, %r11b
-; CHECK-NEXT:    cmovneq %rsi, %rcx
-; CHECK-NEXT:    cmpq $2047, %r9 # imm = 0x7FF
-; CHECK-NEXT:    sete %al
-; CHECK-NEXT:    testb %r8b, %al
-; CHECK-NEXT:    cmovneq %rdx, %rcx
-; CHECK-NEXT:    testb %dil, %al
+; CHECK-NEXT:    cmpq $1, %rax
+; CHECK-NEXT:    cmovbq %rdx, %r9
+; CHECK-NEXT:    addq %r10, %r9
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpq $4, %r9
+; CHECK-NEXT:    cmovgeq %rdx, %r9
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 8-byte Folded Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero
+; CHECK-NEXT:    movq %xmm0, %rcx
+; CHECK-NEXT:    movq %rcx, %rax
+; CHECK-NEXT:    shrq $63, %rax
+; CHECK-NEXT:    shll $7, %eax
+; CHECK-NEXT:    leal (%rax,%r10,4), %r10d
+; CHECK-NEXT:    orq %r9, %r10
+; CHECK-NEXT:    shrq $50, %r8
+; CHECK-NEXT:    movl %r8d, %r9d
+; CHECK-NEXT:    andl $1, %r9d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    shlq $15, %rbx
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %r9d, %r11d
+; CHECK-NEXT:    shrq $49, %rdi
+; CHECK-NEXT:    andl %r11d, %edi
+; CHECK-NEXT:    addq %r8, %rdi
+; CHECK-NEXT:    xorl %r8d, %r8d
+; CHECK-NEXT:    cmpq $4, %rdi
+; CHECK-NEXT:    cmovgeq %rdx, %rdi
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    leaq (%rsi,%r8), %rdx
+; CHECK-NEXT:    leaq 56(,%rdx,4), %r9
+; CHECK-NEXT:    movq %rax, %rdx
+; CHECK-NEXT:    orq %rdi, %rdx
+; CHECK-NEXT:    orq %r9, %rdx
+; CHECK-NEXT:    leaq 14(%rsi,%r8), %rsi
+; CHECK-NEXT:    testq %rsi, %rsi
+; CHECK-NEXT:    cmovleq %r10, %rdx
+; CHECK-NEXT:    cmpq $4, %rdi
+; CHECK-NEXT:    setge %dil
+; CHECK-NEXT:    cmpq $30, %rsi
+; CHECK-NEXT:    sete %r8b
+; CHECK-NEXT:    andb %dil, %r8b
+; CHECK-NEXT:    cmpq $31, %rsi
+; CHECK-NEXT:    setge %sil
+; CHECK-NEXT:    orb %r8b, %sil
+; CHECK-NEXT:    leaq 124(%rax), %rdi
+; CHECK-NEXT:    testb %sil, %sil
+; CHECK-NEXT:    cmovneq %rdi, %rdx
+; CHECK-NEXT:    movabsq $9223372036854775807, %rsi # imm = 0x7FFFFFFFFFFFFFFF
+; CHECK-NEXT:    andq %rcx, %rsi
+; CHECK-NEXT:    cmoveq %rax, %rdx
+; CHECK-NEXT:    movabsq $9218868437227405312, %rax # imm = 0x7FF0000000000000
+; CHECK-NEXT:    cmpq %rax, %rsi
+; CHECK-NEXT:    cmoveq %rdi, %rdx
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmoveq %rcx, %rax
+; CHECK-NEXT:    cmovleq %rdx, %rax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $rax
-; CHECK-NEXT:    popq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    popq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    popq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    addq $16, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)

>From 4c245d50f854514f8216da36c1fa5b7224733b28 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Wed, 6 May 2026 17:29:33 +0200
Subject: [PATCH 6/9] Re-write to allow vector support

---
 llvm/include/llvm/CodeGen/TargetLowering.h    |   5 +
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 423 +-------
 .../SelectionDAG/LegalizeVectorOps.cpp        |   6 +
 .../CodeGen/SelectionDAG/TargetLowering.cpp   | 422 ++++++++
 .../CodeGen/AMDGPU/float-to-arbitrary-fp.ll   | 384 ++++---
 .../CodeGen/NVPTX/float-to-arbitrary-fp.ll    | 104 +-
 .../test/CodeGen/X86/float-to-arbitrary-fp.ll | 998 ++++++++----------
 7 files changed, 1104 insertions(+), 1238 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 9b0bfa111f2d5..3962c49e525c1 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5648,6 +5648,11 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
   /// \returns The expansion result
   SDValue expandFCANONICALIZE(SDNode *Node, SelectionDAG &DAG) const;
 
+  /// Expand CONVERT_TO_ARBITRARY_FP using bit manipulation.
+  /// \param Node Node to expand.
+  /// \returns The expansion result, or SDValue() if fails.
+  SDValue expandCONVERT_TO_ARBITRARY_FP(SDNode *Node, SelectionDAG &DAG) const;
+
   /// Expand CTPOP nodes. Expands vector/scalar CTPOP nodes,
   /// vector nodes can only succeed if all operations are legal/custom.
   /// \param N Node to expand
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index d1242e73a0382..45a59c1799fe7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3793,427 +3793,10 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     // Float8E3M4, Float8E5M2FNUZ, Float8E4M3FNUZ, Float8E4M3B11FNUZ,
     // Float8E8M0FNU.
     EVT ResVT = Node->getValueType(0);
-    assert(!ResVT.isVector() &&
-           "Vector apfloat conversions are handled in LegalizeVectorOps");
-
-    SDValue FloatVal = Node->getOperand(0);
-    const uint64_t SemEnum = Node->getConstantOperandVal(1);
-    const auto Sem = static_cast<APFloatBase::Semantics>(SemEnum);
-    const auto RoundMode =
-        static_cast<RoundingMode>(Node->getConstantOperandVal(2));
-    const bool Saturate = Node->getConstantOperandVal(3) != 0;
-
-    // Supported destination formats.
-    switch (Sem) {
-    case APFloatBase::S_Float8E5M2:
-    case APFloatBase::S_Float8E4M3FN:
-    case APFloatBase::S_Float6E3M2FN:
-    case APFloatBase::S_Float6E2M3FN:
-    case APFloatBase::S_Float4E2M1FN:
-      break;
-    default:
-      DAG.getContext()->emitError("CONVERT_TO_ARBITRARY_FP: not implemented "
-                                  "destination format (semantics enum " +
-                                  Twine(SemEnum) + ")");
-      Results.push_back(DAG.getPOISON(ResVT));
-      break;
-    }
-    if (!Results.empty())
-      break;
-
-    // Supported rounding modes.
-    switch (RoundMode) {
-    case RoundingMode::NearestTiesToEven:
-    case RoundingMode::TowardZero:
-    case RoundingMode::TowardPositive:
-    case RoundingMode::TowardNegative:
-    case RoundingMode::NearestTiesToAway:
-      break;
-    default:
-      DAG.getContext()->emitError(
-          "CONVERT_TO_ARBITRARY_FP: unsupported rounding mode (enum " +
-          Twine(static_cast<int>(RoundMode)) + ")");
+    if (SDValue Expanded = TLI.expandCONVERT_TO_ARBITRARY_FP(Node, DAG))
+      Results.push_back(Expanded);
+    else
       Results.push_back(DAG.getPOISON(ResVT));
-      break;
-    }
-    if (!Results.empty())
-      break;
-
-    // Destination format parameters.
-    const fltSemantics &DstSem = APFloatBase::EnumToSemantics(Sem);
-    const unsigned DstBits = APFloat::getSizeInBits(DstSem);
-    const unsigned DstPrecision = APFloat::semanticsPrecision(DstSem);
-    const unsigned DstMant = DstPrecision - 1;
-    const unsigned DstExpBits = DstBits - DstMant - 1;
-    const int DstBias = 1 - APFloat::semanticsMinExponent(DstSem);
-    const unsigned DstExpMax = (1U << DstExpBits) - 1;
-    const uint64_t DstMantMask = (DstMant > 0) ? ((1ULL << DstMant) - 1) : 0;
-    const fltNonfiniteBehavior DstNFBehavior = DstSem.nonFiniteBehavior;
-    const fltNanEncoding DstNanEnc = DstSem.nanEncoding;
-
-    // Compute the maximum normal exponent for the destination format.
-    const unsigned DstExpMaxNormal =
-        DstNFBehavior == fltNonfiniteBehavior::IEEE754 ? DstExpMax - 1
-                                                       : DstExpMax;
-
-    // For NanOnly formats the max exponent field for finite values
-    // is DstExpMax, but the encoding with exp = DstExpMax and
-    // mant = all-ones is NaN. So DstExpMaxNormal = DstExpMax, but max
-    // mantissa at that exponent is DstMantMask - 1 (if NanEnc == AllOnes) to
-    // avoid the NaN encoding.
-    uint64_t DstMaxMantAtMaxExp = DstMantMask;
-    if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
-        DstNanEnc == fltNanEncoding::AllOnes)
-      DstMaxMantAtMaxExp = DstMantMask - 1;
-
-    // FIXME: ConstantFP inputs may not fully fold through this expansion.
-
-    // Source format parameters.
-    EVT SrcVT = FloatVal.getValueType();
-    const fltSemantics &SrcSem = SrcVT.getFltSemantics();
-    const unsigned SrcBits = APFloat::getSizeInBits(SrcSem);
-    const unsigned SrcPrecision = APFloat::semanticsPrecision(SrcSem);
-    const unsigned SrcMant = SrcPrecision - 1;
-    const uint64_t SrcMantMask = (1ULL << SrcMant) - 1;
-
-    // Work in the source integer type.
-    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), SrcBits);
-    EVT SetCCVT = getSetCCResultType(IntVT);
-
-    SDValue Zero = DAG.getConstant(0, dl, IntVT);
-    SDValue One = DAG.getConstant(1, dl, IntVT);
-
-    // Bitcast source float to integer to extract the sign bit.
-    SDValue Src = DAG.getNode(ISD::BITCAST, dl, IntVT, FloatVal);
-    SDValue SignBit =
-        DAG.getNode(ISD::SRL, dl, IntVT, Src,
-                    DAG.getShiftAmountConstant(SrcBits - 1, IntVT, dl));
-
-    // Classify the input.
-    SDValue IsNaN = DAG.getNode(ISD::IS_FPCLASS, dl, SetCCVT, FloatVal,
-                                DAG.getTargetConstant(fcNan, dl, MVT::i32));
-    SDValue IsInf = DAG.getNode(ISD::IS_FPCLASS, dl, SetCCVT, FloatVal,
-                                DAG.getTargetConstant(fcInf, dl, MVT::i32));
-    SDValue IsZero = DAG.getNode(ISD::IS_FPCLASS, dl, SetCCVT, FloatVal,
-                                 DAG.getTargetConstant(fcZero, dl, MVT::i32));
-
-    // Split into a normalized fraction and unbiased exponent. FFREXP normalizes
-    // source denormals automatically. The result is unspecified for Inf/NaN,
-    // but those inputs are detected above and override the final result.
-    EVT FrexpExpVT = MVT::i32;
-    SDValue Frexp = DAG.getNode(ISD::FFREXP, dl,
-                                DAG.getVTList(SrcVT, FrexpExpVT), FloatVal);
-    SDValue FrexpFrac = Frexp.getValue(0);
-    SDValue FrexpExp = Frexp.getValue(1);
-
-    SDValue FrexpFracInt = DAG.getNode(ISD::BITCAST, dl, IntVT, FrexpFrac);
-    SDValue EffSrcMant = DAG.getNode(ISD::AND, dl, IntVT, FrexpFracInt,
-                                     DAG.getConstant(SrcMantMask, dl, IntVT));
-
-    SDValue FrexpExpExt = DAG.getSExtOrTrunc(FrexpExp, dl, IntVT);
-    SDValue NewExp = DAG.getNode(
-        ISD::ADD, dl, IntVT, FrexpExpExt,
-        DAG.getConstant(APInt(SrcBits, DstBias - 1, true), dl, IntVT));
-
-    // Compute rounding increment given the round bit, sticky bits, and LSB
-    // of the truncated mantissa.
-    auto ComputeRoundUp = [&](SDValue RoundBit, SDValue StickyBits,
-                              SDValue LSB) -> SDValue {
-      if (RoundMode == RoundingMode::NearestTiesToEven) {
-        // Round up if round_bit && (sticky || lsb)
-        SDValue StickyOrLSB = DAG.getNode(ISD::OR, dl, IntVT, StickyBits, LSB);
-        return DAG.getNode(ISD::AND, dl, IntVT, RoundBit, StickyOrLSB);
-      }
-      if (RoundMode == RoundingMode::TowardZero)
-        return Zero;
-      if (RoundMode == RoundingMode::TowardPositive) {
-        // Round up if positive and any truncated bits are set.
-        SDValue AnyTruncBits =
-            DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
-        SDValue HasTruncBits =
-            DAG.getSetCC(dl, SetCCVT, AnyTruncBits, Zero, ISD::SETNE);
-        SDValue IsPositive =
-            DAG.getSetCC(dl, SetCCVT, SignBit, Zero, ISD::SETEQ);
-        SDValue DoRound =
-            DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsPositive);
-        return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
-      }
-      if (RoundMode == RoundingMode::TowardNegative) {
-        // Round up if negative and any truncated bits are set (to -Inf).
-        SDValue AnyTruncBits =
-            DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
-        SDValue HasTruncBits =
-            DAG.getSetCC(dl, SetCCVT, AnyTruncBits, Zero, ISD::SETNE);
-        SDValue IsNegative =
-            DAG.getSetCC(dl, SetCCVT, SignBit, Zero, ISD::SETNE);
-        SDValue DoRound =
-            DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsNegative);
-        return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
-      }
-      assert(RoundMode == RoundingMode::NearestTiesToAway &&
-             "Unsupported rounding mode; should have been rejected above");
-      return RoundBit;
-    };
-
-    // Round mantissa from SrcMant bits to DstMant bits.
-    SDValue TruncMant;
-    SDValue RoundUp;
-    if (SrcMant > DstMant) {
-      const unsigned Shift = SrcMant - DstMant;
-      SDValue ShiftConst = DAG.getShiftAmountConstant(Shift, IntVT, dl);
-      TruncMant = DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant, ShiftConst);
-
-      // Check bit at position Shift - 1 aka the round bit.
-      SDValue RoundBit;
-      if (Shift >= 1) {
-        RoundBit = DAG.getNode(
-            ISD::AND, dl, IntVT,
-            DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant,
-                        DAG.getShiftAmountConstant(Shift - 1, IntVT, dl)),
-            One);
-      } else {
-        RoundBit = Zero;
-      }
-
-      // OR of all bits below the round bit to get sticky bits.
-      SDValue StickyBits;
-      if (Shift >= 2) {
-        uint64_t StickyMask = (1ULL << (Shift - 1)) - 1;
-        StickyBits = DAG.getNode(ISD::AND, dl, IntVT, EffSrcMant,
-                                 DAG.getConstant(StickyMask, dl, IntVT));
-        StickyBits = DAG.getSetCC(dl, SetCCVT, StickyBits, Zero, ISD::SETNE);
-        StickyBits = DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, StickyBits);
-      } else {
-        StickyBits = Zero;
-      }
-
-      // LSB of truncated mantissa.
-      SDValue LSB = DAG.getNode(ISD::AND, dl, IntVT, TruncMant, One);
-
-      RoundUp = ComputeRoundUp(RoundBit, StickyBits, LSB);
-    } else {
-      // If DstMant >= SrcMant, then no rounding needed, just shift left.
-      SDValue MantShift =
-          DAG.getShiftAmountConstant(DstMant - SrcMant, IntVT, dl);
-      TruncMant = DAG.getNode(ISD::SHL, dl, IntVT, EffSrcMant, MantShift);
-      RoundUp = Zero;
-    }
-
-    // Apply rounding.
-    SDValue RoundedMant = DAG.getNode(ISD::ADD, dl, IntVT, TruncMant, RoundUp);
-
-    // Handle mantissa overflow from rounding.
-    // If rounded_mant > DstMantMask, carry into exponent.
-    SDValue MantOverflow =
-        DAG.getSetCC(dl, SetCCVT, RoundedMant,
-                     DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
-    // On overflow: mant = 0, exp += 1.
-    SDValue AdjMant = DAG.getSelect(dl, IntVT, MantOverflow, Zero, RoundedMant);
-    SDValue AdjExp =
-        DAG.getNode(ISD::ADD, dl, IntVT, NewExp,
-                    DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, MantOverflow));
-
-    // Precompute sign shifted to MSB of destination.
-    SDValue SignShifted =
-        DAG.getNode(ISD::SHL, dl, IntVT, SignBit,
-                    DAG.getShiftAmountConstant(DstBits - 1, IntVT, dl));
-
-    // Destination denormal conversion (when new_exp <= 0).
-    // Shift the mantissa right by 1 - new_exp additional bits and set the
-    // exponent field to 0.
-    SDValue ExpIsNeg = DAG.getSetCC(dl, SetCCVT, AdjExp,
-                                    DAG.getConstant(1, dl, IntVT), ISD::SETLT);
-
-    SDValue DenormResult;
-    {
-      // denorm_shift = 1 - NewExp.
-      SDValue DenormShift = DAG.getNode(ISD::SUB, dl, IntVT, One, NewExp);
-
-      // full_src_mant = (1 << SrcMant) | EffSrcMant.
-      SDValue ImplicitOne =
-          DAG.getNode(ISD::SHL, dl, IntVT, One,
-                      DAG.getShiftAmountConstant(SrcMant, IntVT, dl));
-      SDValue FullSrcMant =
-          DAG.getNode(ISD::OR, dl, IntVT, EffSrcMant, ImplicitOne);
-
-      // Total right shift = (SrcMant - DstMant) + DenormShift
-      SDValue TotalShift;
-      if (SrcMant >= DstMant) {
-        TotalShift = DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
-                                 DAG.getConstant(SrcMant - DstMant, dl, IntVT));
-      } else {
-        TotalShift = DAG.getNode(ISD::SUB, dl, IntVT, DenormShift,
-                                 DAG.getConstant(DstMant - SrcMant, dl, IntVT));
-      }
-
-      // Clamp total shift to avoid UB, then trancate denorm mantissa.
-      SDValue MaxShift = DAG.getConstant(SrcBits - 1, dl, IntVT);
-      SDValue ClampedShift =
-          DAG.getNode(ISD::UMIN, dl, IntVT, TotalShift, MaxShift);
-      SDValue DenormTruncMant =
-          DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, ClampedShift);
-
-      // Rounding for denorm path.
-      SDValue DenormRoundUp;
-      {
-        // Round bit is at position TotalShift - 1 of FullSrcMant.
-        // Clamp to at least 1 so the subtraction doesn't underflow and create
-        // shift nodes with invalid shift amounts.
-        SDValue SafeShift =
-            DAG.getNode(ISD::UMAX, dl, IntVT, ClampedShift, One);
-        SDValue RoundBitPos = DAG.getNode(ISD::SUB, dl, IntVT, SafeShift, One);
-        SDValue DenormRoundBit = DAG.getNode(
-            ISD::AND, dl, IntVT,
-            DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, RoundBitPos), One);
-
-        // Sticky: all bits below round bit.
-        // sticky_mask = (1 << RoundBitPos) - 1
-        SDValue StickyMask = DAG.getNode(
-            ISD::SUB, dl, IntVT,
-            DAG.getNode(ISD::SHL, dl, IntVT, One, RoundBitPos), One);
-        SDValue DenormStickyBits =
-            DAG.getNode(ISD::AND, dl, IntVT, FullSrcMant, StickyMask);
-        SDValue HasSticky = DAG.getNode(
-            ISD::ZERO_EXTEND, dl, IntVT,
-            DAG.getSetCC(dl, SetCCVT, DenormStickyBits, Zero, ISD::SETNE));
-
-        SDValue DenormLSB =
-            DAG.getNode(ISD::AND, dl, IntVT, DenormTruncMant, One);
-
-        DenormRoundUp = ComputeRoundUp(DenormRoundBit, HasSticky, DenormLSB);
-
-        // Only apply rounding if TotalShift >= 1 (i.e., there are bits to
-        // round).
-        SDValue ShiftGEOne =
-            DAG.getSetCC(dl, SetCCVT, ClampedShift, One, ISD::SETUGE);
-        DenormRoundUp =
-            DAG.getSelect(dl, IntVT, ShiftGEOne, DenormRoundUp, Zero);
-      }
-
-      SDValue DenormRoundedMant =
-          DAG.getNode(ISD::ADD, dl, IntVT, DenormTruncMant, DenormRoundUp);
-
-      // If rounding caused overflow into the normal range, then we get the
-      // smallest normal number.
-      SDValue DenormMantOF =
-          DAG.getSetCC(dl, SetCCVT, DenormRoundedMant,
-                       DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
-      SDValue DenormFinalMant =
-          DAG.getSelect(dl, IntVT, DenormMantOF, Zero, DenormRoundedMant);
-      SDValue DenormFinalExp =
-          DAG.getSelect(dl, IntVT, DenormMantOF, One, Zero);
-
-      // Assemble: sign | (exp << DstMant) | mant
-      SDValue DenormExpShifted =
-          DAG.getNode(ISD::SHL, dl, IntVT, DenormFinalExp,
-                      DAG.getShiftAmountConstant(DstMant, IntVT, dl));
-      DenormResult = DAG.getNode(
-          ISD::OR, dl, IntVT,
-          DAG.getNode(ISD::OR, dl, IntVT, SignShifted, DenormExpShifted),
-          DenormFinalMant);
-
-      // If the value is to small for even a denorm (all mantissa bits
-      // shifted away), handle based on rounding mode.
-      // This is covered by the DenormRoundedMant = 0 case naturally.
-    }
-
-    // Exponent overflow detection.
-    SDValue ExpOF =
-        DAG.getSetCC(dl, SetCCVT, AdjExp,
-                     DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETGT);
-
-    // Also check if AdjExp == DstExpMaxNormal and mantissa overflow into
-    // a value that exceeds the max allowed mantissa at that exponent.
-    SDValue ExpAtMax =
-        DAG.getSetCC(dl, SetCCVT, AdjExp,
-                     DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETEQ);
-    SDValue MantExceedsMax = DAG.getSetCC(
-        dl, SetCCVT, AdjMant, DAG.getConstant(DstMaxMantAtMaxExp, dl, IntVT),
-        ISD::SETGT);
-    SDValue ExpMantOF =
-        DAG.getNode(ISD::AND, dl, SetCCVT, ExpAtMax, MantExceedsMax);
-    SDValue IsOverflow = DAG.getNode(ISD::OR, dl, SetCCVT, ExpOF, ExpMantOF);
-
-    // Build overflow result.
-    SDValue OverflowResult;
-
-    if (Saturate) {
-      // Clamp to max finite value:
-      // sign | (DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp
-      uint64_t MaxFinite =
-          ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
-      OverflowResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
-                                   DAG.getConstant(MaxFinite, dl, IntVT));
-    } else if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
-      // Produce infinity.
-      uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
-      OverflowResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
-                                   DAG.getConstant(InfBits, dl, IntVT));
-    } else {
-      // Emit poison if no Inf in format and not saturating.
-      OverflowResult = DAG.getPOISON(IntVT);
-    }
-
-    // Assemble normal result: sign | (AdjExp << DstMant) | AdjMant
-    SDValue NormExpShifted =
-        DAG.getNode(ISD::SHL, dl, IntVT, AdjExp,
-                    DAG.getShiftAmountConstant(DstMant, IntVT, dl));
-    SDValue NormResult = DAG.getNode(
-        ISD::OR, dl, IntVT,
-        DAG.getNode(ISD::OR, dl, IntVT, SignShifted, NormExpShifted), AdjMant);
-
-    // Build special-value results.
-    SDValue NaNResult;
-    if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
-      // Produce canonical NaN.
-      const uint64_t QNaNBit = (DstMant > 0) ? (1ULL << (DstMant - 1)) : 0;
-      NaNResult = DAG.getConstant(((uint64_t)DstExpMax << DstMant) | QNaNBit,
-                                  dl, IntVT);
-    } else if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
-               DstNanEnc == fltNanEncoding::AllOnes) {
-      // E4M3FN-style: NaN is exp=all-ones, mant=all-ones.
-      NaNResult = DAG.getConstant(
-          ((uint64_t)DstExpMax << DstMant) | DstMantMask, dl, IntVT);
-    } else {
-      // NaN -> poison for finite only values.
-      NaNResult = DAG.getPOISON(IntVT);
-    }
-
-    // Inf handling.
-    SDValue InfResult;
-    if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
-      // Produce signed infinity.
-      uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
-      InfResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
-                              DAG.getConstant(InfBits, dl, IntVT));
-    } else if (Saturate) {
-      // Inf saturates to max finite.
-      uint64_t MaxFinite =
-          ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
-      InfResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
-                              DAG.getConstant(MaxFinite, dl, IntVT));
-    } else {
-      // No Inf and not saturating -> poison.
-      InfResult = DAG.getPOISON(IntVT);
-    }
-
-    SDValue ZeroResult = SignShifted;
-
-    // Final selection in an order: NaN takes priority, then Inf, then Zero.
-    SDValue FiniteResult =
-        DAG.getSelect(dl, IntVT, ExpIsNeg, DenormResult, NormResult);
-    FiniteResult =
-        DAG.getSelect(dl, IntVT, IsOverflow, OverflowResult, FiniteResult);
-
-    SDValue Result = FiniteResult;
-    Result = DAG.getSelect(dl, IntVT, IsZero, ZeroResult, Result);
-    Result = DAG.getSelect(dl, IntVT, IsInf, InfResult, Result);
-    Result = DAG.getSelect(dl, IntVT, IsNaN, NaNResult, Result);
-
-    // Truncate to destination integer type.
-    Result = DAG.getZExtOrTrunc(Result, dl, ResVT);
-
-    Results.push_back(Result);
     break;
   }
   case ISD::FCANONICALIZE: {
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 77b331df57f3d..97dc6f33b255b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -1412,6 +1412,12 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
       return;
     }
     break;
+  case ISD::CONVERT_TO_ARBITRARY_FP:
+    if (SDValue Expanded = TLI.expandCONVERT_TO_ARBITRARY_FP(Node, DAG))
+      Results.push_back(Expanded);
+    else
+      Results.push_back(DAG.getPOISON(Node->getValueType(0)));
+    return;
   case ISD::MASKED_UDIV:
   case ISD::MASKED_SDIV:
   case ISD::MASKED_UREM:
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 6aaf1bed7aae8..a61237019d985 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -9024,6 +9024,428 @@ SDValue TargetLowering::expandFCANONICALIZE(SDNode *Node,
   return Mul;
 }
 
+SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
+                                                      SelectionDAG &DAG) const {
+  // Expand conversion from a native IEEE float type to an arbitrary FP format
+  // returning the result as an integer using bit manipulation.
+  EVT ResVT = Node->getValueType(0);
+  SDLoc dl(Node);
+
+  SDValue FloatVal = Node->getOperand(0);
+  const uint64_t SemEnum = Node->getConstantOperandVal(1);
+  const auto Sem = static_cast<APFloatBase::Semantics>(SemEnum);
+  const auto RoundMode =
+      static_cast<RoundingMode>(Node->getConstantOperandVal(2));
+  const bool Saturate = Node->getConstantOperandVal(3) != 0;
+
+  // Supported destination formats.
+  switch (Sem) {
+  case APFloatBase::S_Float8E5M2:
+  case APFloatBase::S_Float8E4M3FN:
+  case APFloatBase::S_Float6E3M2FN:
+  case APFloatBase::S_Float6E2M3FN:
+  case APFloatBase::S_Float4E2M1FN:
+    break;
+  default:
+    DAG.getContext()->emitError("CONVERT_TO_ARBITRARY_FP: not implemented "
+                                "destination format (semantics enum " +
+                                Twine(SemEnum) + ")");
+    return SDValue();
+  }
+
+  // Supported rounding modes.
+  switch (RoundMode) {
+  case RoundingMode::NearestTiesToEven:
+  case RoundingMode::TowardZero:
+  case RoundingMode::TowardPositive:
+  case RoundingMode::TowardNegative:
+  case RoundingMode::NearestTiesToAway:
+    break;
+  default:
+    DAG.getContext()->emitError(
+        "CONVERT_TO_ARBITRARY_FP: unsupported rounding mode (enum " +
+        Twine(static_cast<int>(RoundMode)) + ")");
+    return SDValue();
+  }
+
+  // Destination format parameters.
+  const fltSemantics &DstSem = APFloatBase::EnumToSemantics(Sem);
+  const unsigned DstBits = APFloat::getSizeInBits(DstSem);
+  const unsigned DstPrecision = APFloat::semanticsPrecision(DstSem);
+  const unsigned DstMant = DstPrecision - 1;
+  const unsigned DstExpBits = DstBits - DstMant - 1;
+  const int DstBias = 1 - APFloat::semanticsMinExponent(DstSem);
+  const unsigned DstExpMax = (1U << DstExpBits) - 1;
+  const uint64_t DstMantMask = (DstMant > 0) ? ((1ULL << DstMant) - 1) : 0;
+  const fltNonfiniteBehavior DstNFBehavior = DstSem.nonFiniteBehavior;
+  const fltNanEncoding DstNanEnc = DstSem.nanEncoding;
+
+  // Compute the maximum normal exponent for the destination format.
+  const unsigned DstExpMaxNormal =
+      DstNFBehavior == fltNonfiniteBehavior::IEEE754 ? DstExpMax - 1
+                                                     : DstExpMax;
+
+  // For NanOnly formats the max exponent field for finite values
+  // is DstExpMax, but the encoding with exp = DstExpMax and
+  // mant = all-ones is NaN. So DstExpMaxNormal = DstExpMax, but max
+  // mantissa at that exponent is DstMantMask - 1 (if NanEnc == AllOnes) to
+  // avoid the NaN encoding.
+  uint64_t DstMaxMantAtMaxExp = DstMantMask;
+  if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
+      DstNanEnc == fltNanEncoding::AllOnes)
+    DstMaxMantAtMaxExp = DstMantMask - 1;
+
+  // FIXME: ConstantFP inputs may not fully fold through this expansion.
+
+  // Source format parameters.
+  EVT SrcVT = FloatVal.getValueType();
+  const fltSemantics &SrcSem = SrcVT.getScalarType().getFltSemantics();
+  const unsigned SrcBits = APFloat::getSizeInBits(SrcSem);
+  const unsigned SrcPrecision = APFloat::semanticsPrecision(SrcSem);
+  const unsigned SrcMant = SrcPrecision - 1;
+  const uint64_t SrcMantMask = (1ULL << SrcMant) - 1;
+
+  // Work in the source integer type. Match the destination shape so the
+  // expansion stays vector when ResVT is a vector.
+  EVT IntScalarVT = EVT::getIntegerVT(*DAG.getContext(), SrcBits);
+  EVT IntVT = ResVT.isVector()
+                  ? EVT::getVectorVT(*DAG.getContext(), IntScalarVT,
+                                     ResVT.getVectorElementCount())
+                  : IntScalarVT;
+  EVT SetCCVT =
+      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), IntVT);
+  EVT FPSetCCVT =
+      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+
+  SDValue Zero = DAG.getConstant(0, dl, IntVT);
+  SDValue One = DAG.getConstant(1, dl, IntVT);
+
+  // Bitcast source float to integer to extract the sign bit.
+  SDValue Src = DAG.getNode(ISD::BITCAST, dl, IntVT, FloatVal);
+  SDValue SignBit =
+      DAG.getNode(ISD::SRL, dl, IntVT, Src,
+                  DAG.getShiftAmountConstant(SrcBits - 1, IntVT, dl));
+
+  // Classify the input.
+  SDValue FPZero = DAG.getConstantFP(0.0, dl, SrcVT);
+  SDValue FPInf = DAG.getConstantFP(APFloat::getInf(SrcSem), dl, SrcVT);
+  SDValue AbsVal = DAG.getNode(ISD::FABS, dl, SrcVT, FloatVal);
+  SDValue IsNaN = DAG.getSetCC(dl, FPSetCCVT, FloatVal, FloatVal, ISD::SETUO);
+  SDValue IsInf = DAG.getSetCC(dl, FPSetCCVT, AbsVal, FPInf, ISD::SETOEQ);
+  SDValue IsZero = DAG.getSetCC(dl, FPSetCCVT, FloatVal, FPZero, ISD::SETOEQ);
+
+  // Split into a normalized fraction and unbiased exponent. FFREXP normalizes
+  // source denormals automatically. The result is unspecified for Inf/NaN, but
+  // those inputs are detected above and override the final result.
+  EVT FrexpExpScalarVT =
+      getValueType(DAG.getDataLayout(), Type::getInt32Ty(*DAG.getContext()));
+  EVT FrexpExpVT = SrcVT.isVector()
+                       ? EVT::getVectorVT(*DAG.getContext(), FrexpExpScalarVT,
+                                          SrcVT.getVectorElementCount())
+                       : FrexpExpScalarVT;
+  SDValue Frexp =
+      DAG.getNode(ISD::FFREXP, dl, DAG.getVTList(SrcVT, FrexpExpVT), FloatVal);
+  SDValue FrexpFrac = Frexp.getValue(0);
+  SDValue FrexpExp = Frexp.getValue(1);
+
+  SDValue FrexpFracInt = DAG.getNode(ISD::BITCAST, dl, IntVT, FrexpFrac);
+  SDValue EffSrcMant = DAG.getNode(ISD::AND, dl, IntVT, FrexpFracInt,
+                                   DAG.getConstant(SrcMantMask, dl, IntVT));
+
+  SDValue FrexpExpExt = DAG.getSExtOrTrunc(FrexpExp, dl, IntVT);
+  SDValue NewExp = DAG.getNode(
+      ISD::ADD, dl, IntVT, FrexpExpExt,
+      DAG.getConstant(APInt(SrcBits, DstBias - 1, true), dl, IntVT));
+
+  // Compute rounding increment given the round bit, sticky bits, and LSB
+  // of the truncated mantissa.
+  auto ComputeRoundUp = [&](SDValue RoundBit, SDValue StickyBits,
+                            SDValue LSB) -> SDValue {
+    if (RoundMode == RoundingMode::NearestTiesToEven) {
+      // Round up if round_bit && (sticky || lsb)
+      SDValue StickyOrLSB = DAG.getNode(ISD::OR, dl, IntVT, StickyBits, LSB);
+      return DAG.getNode(ISD::AND, dl, IntVT, RoundBit, StickyOrLSB);
+    }
+    if (RoundMode == RoundingMode::TowardZero)
+      return Zero;
+    if (RoundMode == RoundingMode::TowardPositive) {
+      // Round up if positive and any truncated bits are set.
+      SDValue AnyTruncBits =
+          DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
+      SDValue HasTruncBits =
+          DAG.getSetCC(dl, SetCCVT, AnyTruncBits, Zero, ISD::SETNE);
+      SDValue IsPositive = DAG.getSetCC(dl, SetCCVT, SignBit, Zero, ISD::SETEQ);
+      SDValue DoRound =
+          DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsPositive);
+      return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
+    }
+    if (RoundMode == RoundingMode::TowardNegative) {
+      // Round up if negative and any truncated bits are set (to -Inf).
+      SDValue AnyTruncBits =
+          DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
+      SDValue HasTruncBits =
+          DAG.getSetCC(dl, SetCCVT, AnyTruncBits, Zero, ISD::SETNE);
+      SDValue IsNegative = DAG.getSetCC(dl, SetCCVT, SignBit, Zero, ISD::SETNE);
+      SDValue DoRound =
+          DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsNegative);
+      return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
+    }
+    assert(RoundMode == RoundingMode::NearestTiesToAway &&
+           "Unsupported rounding mode; should have been rejected above");
+    return RoundBit;
+  };
+
+  // Round mantissa from SrcMant bits to DstMant bits.
+  SDValue TruncMant;
+  SDValue RoundUp;
+  if (SrcMant > DstMant) {
+    const unsigned Shift = SrcMant - DstMant;
+    SDValue ShiftConst = DAG.getShiftAmountConstant(Shift, IntVT, dl);
+    TruncMant = DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant, ShiftConst);
+
+    // Check bit at position Shift - 1 aka the round bit.
+    SDValue RoundBit;
+    if (Shift >= 1) {
+      RoundBit = DAG.getNode(
+          ISD::AND, dl, IntVT,
+          DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant,
+                      DAG.getShiftAmountConstant(Shift - 1, IntVT, dl)),
+          One);
+    } else {
+      RoundBit = Zero;
+    }
+
+    // OR of all bits below the round bit to get sticky bits.
+    SDValue StickyBits;
+    if (Shift >= 2) {
+      uint64_t StickyMask = (1ULL << (Shift - 1)) - 1;
+      StickyBits = DAG.getNode(ISD::AND, dl, IntVT, EffSrcMant,
+                               DAG.getConstant(StickyMask, dl, IntVT));
+      StickyBits = DAG.getSetCC(dl, SetCCVT, StickyBits, Zero, ISD::SETNE);
+      StickyBits = DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, StickyBits);
+    } else {
+      StickyBits = Zero;
+    }
+
+    // LSB of truncated mantissa.
+    SDValue LSB = DAG.getNode(ISD::AND, dl, IntVT, TruncMant, One);
+
+    RoundUp = ComputeRoundUp(RoundBit, StickyBits, LSB);
+  } else {
+    // If DstMant >= SrcMant, then no rounding needed, just shift left.
+    SDValue MantShift =
+        DAG.getShiftAmountConstant(DstMant - SrcMant, IntVT, dl);
+    TruncMant = DAG.getNode(ISD::SHL, dl, IntVT, EffSrcMant, MantShift);
+    RoundUp = Zero;
+  }
+
+  // Apply rounding.
+  SDValue RoundedMant = DAG.getNode(ISD::ADD, dl, IntVT, TruncMant, RoundUp);
+
+  // Handle mantissa overflow from rounding.
+  // If rounded_mant > DstMantMask, carry into exponent.
+  SDValue MantOverflow =
+      DAG.getSetCC(dl, SetCCVT, RoundedMant,
+                   DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
+  // On overflow: mant = 0, exp += 1.
+  SDValue AdjMant = DAG.getSelect(dl, IntVT, MantOverflow, Zero, RoundedMant);
+  SDValue AdjExp =
+      DAG.getNode(ISD::ADD, dl, IntVT, NewExp,
+                  DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, MantOverflow));
+
+  // Precompute sign shifted to MSB of destination.
+  SDValue SignShifted =
+      DAG.getNode(ISD::SHL, dl, IntVT, SignBit,
+                  DAG.getShiftAmountConstant(DstBits - 1, IntVT, dl));
+
+  // Destination denormal conversion (when new_exp <= 0).
+  // Shift the mantissa right by 1 - new_exp additional bits and set the
+  // exponent field to 0.
+  SDValue ExpIsNeg = DAG.getSetCC(dl, SetCCVT, AdjExp,
+                                  DAG.getConstant(1, dl, IntVT), ISD::SETLT);
+
+  SDValue DenormResult;
+  {
+    // denorm_shift = 1 - NewExp.
+    SDValue DenormShift = DAG.getNode(ISD::SUB, dl, IntVT, One, NewExp);
+
+    // full_src_mant = (1 << SrcMant) | EffSrcMant.
+    SDValue ImplicitOne =
+        DAG.getNode(ISD::SHL, dl, IntVT, One,
+                    DAG.getShiftAmountConstant(SrcMant, IntVT, dl));
+    SDValue FullSrcMant =
+        DAG.getNode(ISD::OR, dl, IntVT, EffSrcMant, ImplicitOne);
+
+    // Total right shift = (SrcMant - DstMant) + DenormShift
+    SDValue TotalShift;
+    if (SrcMant >= DstMant) {
+      TotalShift = DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
+                               DAG.getConstant(SrcMant - DstMant, dl, IntVT));
+    } else {
+      TotalShift = DAG.getNode(ISD::SUB, dl, IntVT, DenormShift,
+                               DAG.getConstant(DstMant - SrcMant, dl, IntVT));
+    }
+
+    // Clamp total shift to avoid UB, then trancate denorm mantissa.
+    SDValue MaxShift = DAG.getConstant(SrcBits - 1, dl, IntVT);
+    SDValue ClampedShift =
+        DAG.getNode(ISD::UMIN, dl, IntVT, TotalShift, MaxShift);
+    SDValue DenormTruncMant =
+        DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, ClampedShift);
+
+    // Rounding for denorm path.
+    SDValue DenormRoundUp;
+    {
+      // Round bit is at position TotalShift - 1 of FullSrcMant.
+      // Clamp to at least 1 so the subtraction doesn't underflow and create
+      // shift nodes with invalid shift amounts.
+      SDValue SafeShift = DAG.getNode(ISD::UMAX, dl, IntVT, ClampedShift, One);
+      SDValue RoundBitPos = DAG.getNode(ISD::SUB, dl, IntVT, SafeShift, One);
+      SDValue DenormRoundBit = DAG.getNode(
+          ISD::AND, dl, IntVT,
+          DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, RoundBitPos), One);
+
+      // Sticky: all bits below round bit.
+      // sticky_mask = (1 << RoundBitPos) - 1
+      SDValue StickyMask =
+          DAG.getNode(ISD::SUB, dl, IntVT,
+                      DAG.getNode(ISD::SHL, dl, IntVT, One, RoundBitPos), One);
+      SDValue DenormStickyBits =
+          DAG.getNode(ISD::AND, dl, IntVT, FullSrcMant, StickyMask);
+      SDValue HasSticky = DAG.getNode(
+          ISD::ZERO_EXTEND, dl, IntVT,
+          DAG.getSetCC(dl, SetCCVT, DenormStickyBits, Zero, ISD::SETNE));
+
+      SDValue DenormLSB =
+          DAG.getNode(ISD::AND, dl, IntVT, DenormTruncMant, One);
+
+      DenormRoundUp = ComputeRoundUp(DenormRoundBit, HasSticky, DenormLSB);
+
+      // Only apply rounding if TotalShift >= 1 (i.e., there are bits to round).
+      SDValue ShiftGEOne =
+          DAG.getSetCC(dl, SetCCVT, ClampedShift, One, ISD::SETUGE);
+      DenormRoundUp = DAG.getSelect(dl, IntVT, ShiftGEOne, DenormRoundUp, Zero);
+    }
+
+    SDValue DenormRoundedMant =
+        DAG.getNode(ISD::ADD, dl, IntVT, DenormTruncMant, DenormRoundUp);
+
+    // If rounding caused overflow into the normal range, then we get the
+    // smallest normal number.
+    SDValue DenormMantOF =
+        DAG.getSetCC(dl, SetCCVT, DenormRoundedMant,
+                     DAG.getConstant(DstMantMask, dl, IntVT), ISD::SETGT);
+    SDValue DenormFinalMant =
+        DAG.getSelect(dl, IntVT, DenormMantOF, Zero, DenormRoundedMant);
+    SDValue DenormFinalExp = DAG.getSelect(dl, IntVT, DenormMantOF, One, Zero);
+
+    // Assemble: sign | (exp << DstMant) | mant
+    SDValue DenormExpShifted =
+        DAG.getNode(ISD::SHL, dl, IntVT, DenormFinalExp,
+                    DAG.getShiftAmountConstant(DstMant, IntVT, dl));
+    DenormResult = DAG.getNode(
+        ISD::OR, dl, IntVT,
+        DAG.getNode(ISD::OR, dl, IntVT, SignShifted, DenormExpShifted),
+        DenormFinalMant);
+  }
+
+  // Exponent overflow detection.
+  SDValue ExpOF =
+      DAG.getSetCC(dl, SetCCVT, AdjExp,
+                   DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETGT);
+
+  // Also check if AdjExp == DstExpMaxNormal and mantissa overflow into
+  // a value that exceeds the max allowed mantissa at that exponent.
+  SDValue ExpAtMax =
+      DAG.getSetCC(dl, SetCCVT, AdjExp,
+                   DAG.getConstant(DstExpMaxNormal, dl, IntVT), ISD::SETEQ);
+  SDValue MantExceedsMax =
+      DAG.getSetCC(dl, SetCCVT, AdjMant,
+                   DAG.getConstant(DstMaxMantAtMaxExp, dl, IntVT), ISD::SETGT);
+  SDValue ExpMantOF =
+      DAG.getNode(ISD::AND, dl, SetCCVT, ExpAtMax, MantExceedsMax);
+  SDValue IsOverflow = DAG.getNode(ISD::OR, dl, SetCCVT, ExpOF, ExpMantOF);
+
+  // Build overflow result.
+  SDValue OverflowResult;
+
+  if (Saturate) {
+    // Clamp to max finite value:
+    // sign | (DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp
+    uint64_t MaxFinite =
+        ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
+    OverflowResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                                 DAG.getConstant(MaxFinite, dl, IntVT));
+  } else if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
+    // Produce infinity.
+    uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
+    OverflowResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                                 DAG.getConstant(InfBits, dl, IntVT));
+  } else {
+    // Emit poison if no Inf in format and not saturating.
+    OverflowResult = DAG.getPOISON(IntVT);
+  }
+
+  // Assemble normal result: sign | (AdjExp << DstMant) | AdjMant
+  SDValue NormExpShifted =
+      DAG.getNode(ISD::SHL, dl, IntVT, AdjExp,
+                  DAG.getShiftAmountConstant(DstMant, IntVT, dl));
+  SDValue NormResult = DAG.getNode(
+      ISD::OR, dl, IntVT,
+      DAG.getNode(ISD::OR, dl, IntVT, SignShifted, NormExpShifted), AdjMant);
+
+  // Build special-value results.
+  SDValue NaNResult;
+  if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
+    // Produce canonical NaN.
+    const uint64_t QNaNBit = (DstMant > 0) ? (1ULL << (DstMant - 1)) : 0;
+    NaNResult =
+        DAG.getConstant(((uint64_t)DstExpMax << DstMant) | QNaNBit, dl, IntVT);
+  } else if (DstNFBehavior == fltNonfiniteBehavior::NanOnly &&
+             DstNanEnc == fltNanEncoding::AllOnes) {
+    // E4M3FN-style: NaN is exp=all-ones, mant=all-ones.
+    NaNResult = DAG.getConstant(((uint64_t)DstExpMax << DstMant) | DstMantMask,
+                                dl, IntVT);
+  } else {
+    // NaN -> poison for finite only values.
+    NaNResult = DAG.getPOISON(IntVT);
+  }
+
+  // Inf handling.
+  SDValue InfResult;
+  if (DstNFBehavior == fltNonfiniteBehavior::IEEE754) {
+    // Produce signed infinity.
+    uint64_t InfBits = (uint64_t)DstExpMax << DstMant;
+    InfResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                            DAG.getConstant(InfBits, dl, IntVT));
+  } else if (Saturate) {
+    // Inf saturates to max finite.
+    uint64_t MaxFinite =
+        ((uint64_t)DstExpMaxNormal << DstMant) | DstMaxMantAtMaxExp;
+    InfResult = DAG.getNode(ISD::OR, dl, IntVT, SignShifted,
+                            DAG.getConstant(MaxFinite, dl, IntVT));
+  } else {
+    // No Inf and not saturating -> poison.
+    InfResult = DAG.getPOISON(IntVT);
+  }
+
+  SDValue ZeroResult = SignShifted;
+
+  // Final selection in an order: NaN takes priority, then Inf, then Zero.
+  SDValue FiniteResult =
+      DAG.getSelect(dl, IntVT, ExpIsNeg, DenormResult, NormResult);
+  FiniteResult =
+      DAG.getSelect(dl, IntVT, IsOverflow, OverflowResult, FiniteResult);
+
+  SDValue Result = FiniteResult;
+  Result = DAG.getSelect(dl, IntVT, IsZero, ZeroResult, Result);
+  Result = DAG.getSelect(dl, IntVT, IsInf, InfResult, Result);
+  Result = DAG.getSelect(dl, IntVT, IsNaN, NaNResult, Result);
+
+  // Truncate to destination integer type.
+  return DAG.getZExtOrTrunc(Result, dl, ResVT);
+}
+
 bool TargetLowering::expandFP_TO_SINT(SDNode *Node, SDValue &Result,
                                       SelectionDAG &DAG) const {
   unsigned OpNo = Node->isStrictFPOpcode() ? 1 : 0;
diff --git a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
index 630365dfcab62..94618ef705f19 100644
--- a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
@@ -65,16 +65,15 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v3
 ; CHECK-NEXT:    v_or_b32_e32 v1, 0x7c, v5
 ; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v3, 0x60
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v1, vcc
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v3
-; CHECK-NEXT:    v_mov_b32_e32 v3, 0x204
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    s_movk_i32 s4, 0x204
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v5, vcc
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v3
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, s4
 ; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
 ; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
-; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, 3
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -114,16 +113,15 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v5
 ; CHECK-NEXT:    v_or_b32_e32 v2, 0x7c, v3
 ; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v4, 0x60
 ; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v4
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    s_movk_i32 s4, 0x204
 ; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v3, vcc
-; CHECK-NEXT:    v_mov_b32_e32 v3, 0x204
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v3
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, s4
 ; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v2, vcc
 ; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
-; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, 3
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
   ret i8 %r
@@ -140,17 +138,17 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
 ; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
 ; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
-; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
-; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
-; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
-; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_sub_u32_e64 v8, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v9, v5, 0, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_lshrrev_b32_e32 v10, v7, v5
+; CHECK-NEXT:    v_and_or_b32 v9, v10, 1, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v9
 ; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
 ; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
-; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v5
 ; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 28, v0
 ; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v4
@@ -166,135 +164,138 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    v_and_b32_e32 v7, v7, v9
 ; CHECK-NEXT:    v_add_u32_e32 v4, v4, v7
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v6, v7
 ; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
-; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 0, v6, vcc
 ; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 1, v6
 ; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
 ; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
 ; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
-; CHECK-NEXT:    v_mov_b32_e32 v5, 0x60
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v0, v5
-; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v1
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v1
 ; CHECK-NEXT:    v_cndmask_b32_e32 v0, v4, v8, vcc
 ; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v1
-; CHECK-NEXT:    v_sub_u32_e32 v8, 23, v7
-; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
-; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
-; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
-; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
-; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
-; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
-; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
-; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
-; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 28, v1
-; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
-; CHECK-NEXT:    v_and_b32_e32 v9, 8, v9
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
-; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 21, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_sub_u32_e32 v7, 23, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v8, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v9, v5, 0, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_lshrrev_b32_e32 v10, v7, v5
+; CHECK-NEXT:    v_and_or_b32 v9, v10, 1, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 28, v1
+; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 2, vcc
+; CHECK-NEXT:    v_and_b32_e32 v8, 8, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
 ; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
-; CHECK-NEXT:    v_or_b32_e32 v10, v10, v4
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v10
-; CHECK-NEXT:    v_add_u32_e32 v4, v4, v8
+; CHECK-NEXT:    v_or_b32_e32 v9, v9, v4
+; CHECK-NEXT:    v_and_b32_e32 v7, v7, v9
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v7
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v6, v7
 ; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
-; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 0, v7, vcc
-; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 1, v7
-; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v1, v5
-; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v2
-; CHECK-NEXT:    v_cndmask_b32_e32 v1, v4, v9, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v4, v8, vcc
 ; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v2
-; CHECK-NEXT:    v_sub_u32_e32 v8, 23, v7
-; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
-; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
-; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
-; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
-; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
-; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
-; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
-; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
-; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 28, v2
-; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
-; CHECK-NEXT:    v_and_b32_e32 v9, 8, v9
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
-; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 21, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_sub_u32_e32 v7, 23, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v8, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v9, v5, 0, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_lshrrev_b32_e32 v10, v7, v5
+; CHECK-NEXT:    v_and_or_b32 v9, v10, 1, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 28, v2
+; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 2, vcc
+; CHECK-NEXT:    v_and_b32_e32 v8, 8, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
 ; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
-; CHECK-NEXT:    v_or_b32_e32 v10, v10, v4
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v10
-; CHECK-NEXT:    v_add_u32_e32 v4, v4, v8
+; CHECK-NEXT:    v_or_b32_e32 v9, v9, v4
+; CHECK-NEXT:    v_and_b32_e32 v7, v7, v9
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v7
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v6, v7
 ; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
-; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 0, v7, vcc
-; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 1, v7
-; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v2, v5
-; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v3
-; CHECK-NEXT:    v_cndmask_b32_e32 v2, v4, v9, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v2
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v4, v8, vcc
 ; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v3
-; CHECK-NEXT:    v_sub_u32_e32 v8, 23, v7
-; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
-; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
-; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
-; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
-; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
-; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
-; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
-; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
-; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
-; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
-; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v9, 28, v3
-; CHECK-NEXT:    v_and_b32_e32 v10, 0x1fffff, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
-; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 2, vcc
-; CHECK-NEXT:    v_and_b32_e32 v9, 8, v9
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
-; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
-; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 21, v4
-; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_sub_u32_e32 v7, 23, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v8, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v9, v5, 0, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_lshrrev_b32_e32 v10, v7, v5
+; CHECK-NEXT:    v_and_or_b32 v9, v10, 1, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v8, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 28, v3
+; CHECK-NEXT:    v_and_b32_e32 v9, 0x1fffff, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 2, vcc
+; CHECK-NEXT:    v_and_b32_e32 v8, 8, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, 21, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
 ; CHECK-NEXT:    v_bfe_u32 v4, v4, 22, 1
-; CHECK-NEXT:    v_or_b32_e32 v10, v10, v4
-; CHECK-NEXT:    v_and_b32_e32 v8, v8, v10
-; CHECK-NEXT:    v_add_u32_e32 v4, v4, v8
+; CHECK-NEXT:    v_or_b32_e32 v9, v9, v4
+; CHECK-NEXT:    v_and_b32_e32 v7, v7, v9
+; CHECK-NEXT:    v_add_u32_e32 v4, v4, v7
 ; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v6, v7
 ; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
-; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 0, v7, vcc
-; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 1, v7
-; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
-; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
-; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
-; CHECK-NEXT:    v_cmp_class_f32_e32 vcc, v3, v5
-; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v9, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v8, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
   ret <4 x i4> %r
@@ -358,15 +359,14 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-NEXT:    v_or_b32_e32 v1, 0x7c, v6
 ; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v1, vcc
-; CHECK-NEXT:    v_mov_b32_e32 v3, 0x60
-; CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v3
-; CHECK-NEXT:    v_mov_b32_e32 v3, 0x204
+; CHECK-NEXT:    v_cmp_eq_f16_e32 vcc, 0, v0
+; CHECK-NEXT:    s_movk_i32 s4, 0x204
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
-; CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v3
+; CHECK-NEXT:    v_cmp_class_f16_e64 vcc, v0, s4
 ; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
 ; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
-; CHECK-NEXT:    v_cmp_class_f16_e64 vcc, v0, 3
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; CHECK-NEXT:    v_cmp_o_f16_e32 vcc, v0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -379,76 +379,75 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    v_lshlrev_b32_e32 v1, 16, v0
 ; CHECK-NEXT:    v_frexp_mant_f32_e32 v2, v1
-; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v1, v1
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v5, v1
 ; CHECK-NEXT:    v_bfe_u32 v3, v2, 16, 1
-; CHECK-NEXT:    s_movk_i32 s4, 0x7fff
-; CHECK-NEXT:    v_sub_u16_e32 v5, -8, v1
-; CHECK-NEXT:    v_add3_u32 v3, v3, v2, s4
+; CHECK-NEXT:    s_movk_i32 s6, 0x7fff
+; CHECK-NEXT:    v_sub_u16_e32 v6, -8, v5
+; CHECK-NEXT:    v_add3_u32 v3, v3, v2, s6
 ; CHECK-NEXT:    v_or_b32_e32 v4, 0x400000, v2
 ; CHECK-NEXT:    v_cmp_u_f32_e32 vcc, v2, v2
-; CHECK-NEXT:    v_min_u16_e32 v5, 15, v5
+; CHECK-NEXT:    v_min_u16_e32 v6, 15, v6
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v4, vcc
 ; CHECK-NEXT:    s_movk_i32 s4, 0x7f
-; CHECK-NEXT:    v_sub_u16_e64 v8, v5, 1 clamp
+; CHECK-NEXT:    v_sub_u16_e64 v9, v6, 1 clamp
 ; CHECK-NEXT:    v_and_b32_sdwa v3, v2, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
-; CHECK-NEXT:    v_lshlrev_b16_e64 v9, v8, 1
+; CHECK-NEXT:    v_lshlrev_b16_e64 v10, v9, 1
 ; CHECK-NEXT:    v_or_b32_e32 v4, 0x80, v3
-; CHECK-NEXT:    v_add_u16_e32 v9, -1, v9
-; CHECK-NEXT:    v_and_b32_e32 v9, v4, v9
-; CHECK-NEXT:    v_lshrrev_b16_e32 v6, v5, v4
-; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v9
-; CHECK-NEXT:    v_and_b32_e32 v7, 1, v6
-; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
-; CHECK-NEXT:    v_or_b32_e32 v7, v9, v7
-; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v8, v4
-; CHECK-NEXT:    v_and_b32_e32 v4, v4, v7
-; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v5
+; CHECK-NEXT:    v_add_u16_e32 v10, -1, v10
+; CHECK-NEXT:    v_and_b32_e32 v10, v4, v10
+; CHECK-NEXT:    v_lshrrev_b16_e32 v7, v6, v4
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v10
+; CHECK-NEXT:    v_and_b32_e32 v8, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v8, v10, v8
+; CHECK-NEXT:    v_lshrrev_b16_e32 v4, v9, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v8
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v6
 ; CHECK-NEXT:    v_cndmask_b32_e32 v4, 0, v4, vcc
-; CHECK-NEXT:    v_add_u16_e32 v4, v6, v4
+; CHECK-NEXT:    v_add_u16_e32 v4, v7, v4
 ; CHECK-NEXT:    s_movk_i32 s4, 0x80
 ; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v4
-; CHECK-NEXT:    v_mov_b32_e32 v7, 15
-; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 4, vcc
-; CHECK-NEXT:    v_and_b32_sdwa v6, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
-; CHECK-NEXT:    v_and_b32_sdwa v7, v2, v7 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
+; CHECK-NEXT:    v_mov_b32_e32 v8, 15
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v7, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_and_b32_sdwa v8, v2, v8 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
 ; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
-; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_or_b32_e32 v6, v7, v6
 ; CHECK-NEXT:    v_lshrrev_b16_e32 v3, 5, v3
-; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v7
-; CHECK-NEXT:    v_or_b32_e32 v4, v5, v4
-; CHECK-NEXT:    v_and_b32_e32 v5, 1, v3
-; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
-; CHECK-NEXT:    v_or_b32_e32 v5, v7, v5
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v8
+; CHECK-NEXT:    v_or_b32_e32 v4, v6, v4
+; CHECK-NEXT:    v_and_b32_e32 v6, 1, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v6, v8, v6
 ; CHECK-NEXT:    v_lshrrev_b32_e32 v2, 20, v2
-; CHECK-NEXT:    v_and_b32_e32 v2, v2, v5
+; CHECK-NEXT:    v_and_b32_e32 v2, v2, v6
 ; CHECK-NEXT:    v_add_u16_e32 v2, v3, v2
 ; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v2
 ; CHECK-NEXT:    v_cndmask_b32_e64 v3, 0, 1, vcc
-; CHECK-NEXT:    v_add_u16_e32 v1, v1, v3
-; CHECK-NEXT:    v_add_u16_e32 v1, 14, v1
-; CHECK-NEXT:    v_lshlrev_b16_e32 v3, 2, v1
+; CHECK-NEXT:    v_add_u16_e32 v3, v5, v3
+; CHECK-NEXT:    v_add_u16_e32 v3, 14, v3
+; CHECK-NEXT:    v_lshlrev_b16_e32 v5, 2, v3
 ; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
-; CHECK-NEXT:    v_or_b32_e32 v3, v6, v3
-; CHECK-NEXT:    v_or_b32_e32 v3, v3, v2
-; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, 1, v1
-; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v4, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v7, v5
+; CHECK-NEXT:    v_or_b32_e32 v5, v5, v2
+; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, 1, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v5, v4, vcc
 ; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 3, v2
-; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 30, v1
+; CHECK-NEXT:    v_cmp_eq_u16_e64 s[4:5], 30, v3
 ; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
-; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 30, v1
-; CHECK-NEXT:    v_or_b32_e32 v1, 0x7c, v6
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 30, v3
+; CHECK-NEXT:    v_or_b32_e32 v2, 0x7c, v7
 ; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
-; CHECK-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
-; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v1, vcc
-; CHECK-NEXT:    v_cmp_eq_u16_e32 vcc, 0, v0
-; CHECK-NEXT:    s_movk_i32 s4, 0x7f80
-; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
-; CHECK-NEXT:    v_cmp_eq_u16_e32 vcc, s4, v0
-; CHECK-NEXT:    s_movk_i32 s4, 0x7f81
-; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v2, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_and_b32_sdwa v0, s6, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; CHECK-NEXT:    s_mov_b32 s4, 0x7f800000
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v7, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, s4, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v3, v2, vcc
 ; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7e
-; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, s4, v0
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v1, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -525,16 +524,15 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-NEXT:    v_cndmask_b32_e64 v2, v6, v9, s[6:7]
 ; CHECK-NEXT:    v_or_b32_e32 v3, 0x7c, v8
 ; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
-; CHECK-NEXT:    v_mov_b32_e32 v4, 0x60
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
-; CHECK-NEXT:    v_cmp_class_f64_e32 vcc, v[0:1], v4
-; CHECK-NEXT:    v_mov_b32_e32 v4, 0x204
+; CHECK-NEXT:    v_cmp_eq_f64_e32 vcc, 0, v[0:1]
+; CHECK-NEXT:    s_movk_i32 s4, 0x204
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v8, vcc
-; CHECK-NEXT:    v_cmp_class_f64_e32 vcc, v[0:1], v4
+; CHECK-NEXT:    v_cmp_class_f64_e64 vcc, v[0:1], s4
 ; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
-; CHECK-NEXT:    v_cmp_class_f64_e64 vcc, v[0:1], 3
+; CHECK-NEXT:    v_cmp_o_f64_e32 vcc, v[0:1], v[0:1]
 ; CHECK-NEXT:    v_mov_b32_e32 v3, 0x7e
-; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v3, vcc
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v3, v2, vcc
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
diff --git a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
index 0c53acb05b3a3..d4c80c2d1a2b4 100644
--- a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
@@ -21,7 +21,7 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-LABEL: to_f8e5m2_dynamic(
 ; CHECK:       {
 ; CHECK-NEXT:    .reg .pred %p<15>;
-; CHECK-NEXT:    .reg .b32 %r<63>;
+; CHECK-NEXT:    .reg .b32 %r<64>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e5m2_dynamic_param_0];
@@ -94,13 +94,14 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-NEXT:    selp.b32 %r58, %r57, %r55, %p10;
 ; CHECK-NEXT:    setp.gt.s32 %p11, %r51, 30;
 ; CHECK-NEXT:    selp.b32 %r59, %r56, %r58, %p11;
-; CHECK-NEXT:    setp.eq.b32 %p12, %r3, 0;
+; CHECK-NEXT:    setp.eq.f32 %p12, %r1, 0f00000000;
 ; CHECK-NEXT:    selp.b32 %r60, %r37, %r59, %p12;
-; CHECK-NEXT:    setp.eq.b32 %p13, %r3, 2139095040;
-; CHECK-NEXT:    selp.b32 %r61, %r56, %r60, %p13;
-; CHECK-NEXT:    setp.gt.s32 %p14, %r3, 2139095040;
-; CHECK-NEXT:    selp.b32 %r62, 126, %r61, %p14;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r62;
+; CHECK-NEXT:    abs.f32 %r61, %r1;
+; CHECK-NEXT:    setp.eq.f32 %p13, %r61, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r62, %r56, %r60, %p13;
+; CHECK-NEXT:    setp.nan.f32 %p14, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r63, 126, %r62, %p14;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r63;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -113,7 +114,7 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-LABEL: to_f8e5m2_round_towardzero(
 ; CHECK:       {
 ; CHECK-NEXT:    .reg .pred %p<12>;
-; CHECK-NEXT:    .reg .b32 %r<41>;
+; CHECK-NEXT:    .reg .b32 %r<42>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e5m2_round_towardzero_param_0];
@@ -161,13 +162,14 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-NEXT:    selp.b32 %r36, %r35, %r33, %p7;
 ; CHECK-NEXT:    setp.gt.s32 %p8, %r18, 30;
 ; CHECK-NEXT:    selp.b32 %r37, %r34, %r36, %p8;
-; CHECK-NEXT:    setp.eq.b32 %p9, %r3, 0;
+; CHECK-NEXT:    setp.eq.f32 %p9, %r1, 0f00000000;
 ; CHECK-NEXT:    selp.b32 %r38, %r21, %r37, %p9;
-; CHECK-NEXT:    setp.eq.b32 %p10, %r3, 2139095040;
-; CHECK-NEXT:    selp.b32 %r39, %r34, %r38, %p10;
-; CHECK-NEXT:    setp.gt.s32 %p11, %r3, 2139095040;
-; CHECK-NEXT:    selp.b32 %r40, 126, %r39, %p11;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r40;
+; CHECK-NEXT:    abs.f32 %r39, %r1;
+; CHECK-NEXT:    setp.eq.f32 %p10, %r39, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r40, %r34, %r38, %p10;
+; CHECK-NEXT:    setp.nan.f32 %p11, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r41, 126, %r40, %p11;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r41;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
   ret i8 %r
@@ -242,7 +244,7 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    or.b32 %r55, %r54, %r50;
 ; CHECK-NEXT:    setp.lt.s32 %p8, %r52, 1;
 ; CHECK-NEXT:    selp.b32 %r56, %r42, %r55, %p8;
-; CHECK-NEXT:    setp.eq.b32 %p9, %r6, 0;
+; CHECK-NEXT:    setp.eq.f32 %p9, %r4, 0f00000000;
 ; CHECK-NEXT:    selp.b32 %r57, %r40, %r56, %p9;
 ; CHECK-NEXT:    mul.rn.f32 %r58, %r3, 0f4C000000;
 ; CHECK-NEXT:    and.b32 %r59, %r3, 2147483647;
@@ -303,7 +305,7 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    or.b32 %r107, %r106, %r102;
 ; CHECK-NEXT:    setp.lt.s32 %p17, %r104, 1;
 ; CHECK-NEXT:    selp.b32 %r108, %r94, %r107, %p17;
-; CHECK-NEXT:    setp.eq.b32 %p18, %r59, 0;
+; CHECK-NEXT:    setp.eq.f32 %p18, %r3, 0f00000000;
 ; CHECK-NEXT:    selp.b32 %r109, %r92, %r108, %p18;
 ; CHECK-NEXT:    prmt.b32 %r110, %r109, %r57, 0x3340U;
 ; CHECK-NEXT:    mul.rn.f32 %r111, %r2, 0f4C000000;
@@ -365,7 +367,7 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    or.b32 %r160, %r159, %r155;
 ; CHECK-NEXT:    setp.lt.s32 %p26, %r157, 1;
 ; CHECK-NEXT:    selp.b32 %r161, %r147, %r160, %p26;
-; CHECK-NEXT:    setp.eq.b32 %p27, %r112, 0;
+; CHECK-NEXT:    setp.eq.f32 %p27, %r2, 0f00000000;
 ; CHECK-NEXT:    selp.b32 %r162, %r145, %r161, %p27;
 ; CHECK-NEXT:    mul.rn.f32 %r163, %r1, 0f4C000000;
 ; CHECK-NEXT:    and.b32 %r164, %r1, 2147483647;
@@ -426,7 +428,7 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    or.b32 %r212, %r211, %r207;
 ; CHECK-NEXT:    setp.lt.s32 %p35, %r209, 1;
 ; CHECK-NEXT:    selp.b32 %r213, %r199, %r212, %p35;
-; CHECK-NEXT:    setp.eq.b32 %p36, %r164, 0;
+; CHECK-NEXT:    setp.eq.f32 %p36, %r1, 0f00000000;
 ; CHECK-NEXT:    selp.b32 %r214, %r197, %r213, %p36;
 ; CHECK-NEXT:    prmt.b32 %r215, %r214, %r162, 0x3340U;
 ; CHECK-NEXT:    prmt.b32 %r216, %r215, %r110, 0x5410U;
@@ -443,8 +445,8 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f16(
 ; CHECK:       {
 ; CHECK-NEXT:    .reg .pred %p<15>;
-; CHECK-NEXT:    .reg .b16 %rs<61>;
-; CHECK-NEXT:    .reg .b32 %r<9>;
+; CHECK-NEXT:    .reg .b16 %rs<64>;
+; CHECK-NEXT:    .reg .b32 %r<11>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b16 %rs1, [to_f8e5m2_from_f16_param_0];
@@ -522,14 +524,19 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-NEXT:    selp.b16 %rs56, %rs55, %rs53, %p10;
 ; CHECK-NEXT:    setp.gt.s16 %p11, %rs49, 30;
 ; CHECK-NEXT:    selp.b16 %rs57, %rs54, %rs56, %p11;
-; CHECK-NEXT:    setp.eq.b16 %p12, %rs4, 0;
-; CHECK-NEXT:    selp.b16 %rs58, %rs35, %rs57, %p12;
-; CHECK-NEXT:    setp.eq.b16 %p13, %rs4, 31744;
-; CHECK-NEXT:    selp.b16 %rs59, %rs54, %rs58, %p13;
-; CHECK-NEXT:    setp.gt.s16 %p14, %rs4, 31744;
-; CHECK-NEXT:    selp.b16 %rs60, 126, %rs59, %p14;
-; CHECK-NEXT:    cvt.u32.u16 %r8, %rs60;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r8;
+; CHECK-NEXT:    mov.b16 %rs58, 0x0000;
+; CHECK-NEXT:    setp.eq.f16 %p12, %rs1, %rs58;
+; CHECK-NEXT:    selp.b16 %rs59, %rs35, %rs57, %p12;
+; CHECK-NEXT:    cvt.f32.f16 %r8, %rs1;
+; CHECK-NEXT:    abs.f32 %r9, %r8;
+; CHECK-NEXT:    cvt.rn.f16.f32 %rs60, %r9;
+; CHECK-NEXT:    mov.b16 %rs61, 0x7C00;
+; CHECK-NEXT:    setp.eq.f16 %p13, %rs60, %rs61;
+; CHECK-NEXT:    selp.b16 %rs62, %rs54, %rs59, %p13;
+; CHECK-NEXT:    setp.nan.f16 %p14, %rs1, %rs1;
+; CHECK-NEXT:    selp.b16 %rs63, 126, %rs62, %p14;
+; CHECK-NEXT:    cvt.u32.u16 %r10, %rs63;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r10;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f16(half %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -539,9 +546,9 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-LABEL: to_f8e5m2_from_bf16(
 ; CHECK:       {
-; CHECK-NEXT:    .reg .pred %p<16>;
+; CHECK-NEXT:    .reg .pred %p<17>;
 ; CHECK-NEXT:    .reg .b16 %rs<60>;
-; CHECK-NEXT:    .reg .b32 %r<17>;
+; CHECK-NEXT:    .reg .b32 %r<24>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b16 %rs1, [to_f8e5m2_from_bf16_param_0];
@@ -627,14 +634,22 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-NEXT:    selp.b16 %rs55, %rs54, %rs52, %p11;
 ; CHECK-NEXT:    setp.gt.s16 %p12, %rs48, 30;
 ; CHECK-NEXT:    selp.b16 %rs56, %rs53, %rs55, %p12;
-; CHECK-NEXT:    setp.eq.b16 %p13, %rs3, 0;
+; CHECK-NEXT:    setp.eq.f32 %p13, %r2, 0f00000000;
 ; CHECK-NEXT:    selp.b16 %rs57, %rs34, %rs56, %p13;
-; CHECK-NEXT:    setp.eq.b16 %p14, %rs3, 32640;
-; CHECK-NEXT:    selp.b16 %rs58, %rs53, %rs57, %p14;
-; CHECK-NEXT:    setp.gt.s16 %p15, %rs3, 32640;
-; CHECK-NEXT:    selp.b16 %rs59, 126, %rs58, %p15;
-; CHECK-NEXT:    cvt.u32.u16 %r16, %rs59;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %r16;
+; CHECK-NEXT:    abs.f32 %r16, %r2;
+; CHECK-NEXT:    bfe.u32 %r17, %r16, 16, 1;
+; CHECK-NEXT:    or.b32 %r18, %r17, %r16;
+; CHECK-NEXT:    add.s32 %r19, %r18, 32767;
+; CHECK-NEXT:    setp.nan.f32 %p14, %r16, %r16;
+; CHECK-NEXT:    or.b32 %r20, %r16, 4194304;
+; CHECK-NEXT:    selp.b32 %r21, %r20, %r19, %p14;
+; CHECK-NEXT:    and.b32 %r22, %r21, 2147418112;
+; CHECK-NEXT:    setp.eq.f32 %p15, %r22, 0f7F800000;
+; CHECK-NEXT:    selp.b16 %rs58, %rs53, %rs57, %p15;
+; CHECK-NEXT:    setp.nan.f32 %p16, %r2, %r2;
+; CHECK-NEXT:    selp.b16 %rs59, 126, %rs58, %p16;
+; CHECK-NEXT:    cvt.u32.u16 %r23, %rs59;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r23;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
@@ -646,7 +661,7 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK:       {
 ; CHECK-NEXT:    .reg .pred %p<15>;
 ; CHECK-NEXT:    .reg .b32 %r<8>;
-; CHECK-NEXT:    .reg .b64 %rd<60>;
+; CHECK-NEXT:    .reg .b64 %rd<61>;
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ld.param.b64 %rd1, [to_f8e5m2_from_f64_param_0];
@@ -723,13 +738,14 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-NEXT:    selp.b64 %rd55, %rd54, %rd52, %p10;
 ; CHECK-NEXT:    setp.gt.s64 %p11, %rd48, 30;
 ; CHECK-NEXT:    selp.b64 %rd56, %rd53, %rd55, %p11;
-; CHECK-NEXT:    setp.eq.b64 %p12, %rd3, 0;
+; CHECK-NEXT:    setp.eq.f64 %p12, %rd1, 0d0000000000000000;
 ; CHECK-NEXT:    selp.b64 %rd57, %rd34, %rd56, %p12;
-; CHECK-NEXT:    setp.eq.b64 %p13, %rd3, 9218868437227405312;
-; CHECK-NEXT:    selp.b64 %rd58, %rd53, %rd57, %p13;
-; CHECK-NEXT:    setp.gt.s64 %p14, %rd3, 9218868437227405312;
-; CHECK-NEXT:    selp.b64 %rd59, 126, %rd58, %p14;
-; CHECK-NEXT:    st.param.b32 [func_retval0], %rd59;
+; CHECK-NEXT:    abs.f64 %rd58, %rd1;
+; CHECK-NEXT:    setp.eq.f64 %p13, %rd58, 0d7FF0000000000000;
+; CHECK-NEXT:    selp.b64 %rd59, %rd53, %rd57, %p13;
+; CHECK-NEXT:    setp.nan.f64 %p14, %rd1, %rd1;
+; CHECK-NEXT:    selp.b64 %rd60, 126, %rd59, %p14;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %rd60;
 ; CHECK-NEXT:    ret;
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f64(double %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
   ret i8 %r
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
index c835fbba2838a..e823b0a1ed47c 100644
--- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
@@ -20,9 +20,9 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f64(double, metadata, metadata, i1)
 define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-LABEL: to_f8e5m2_dynamic:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rax
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    movd %xmm0, (%rsp) # 4-byte Folded Spill
+; CHECK-NEXT:    subq $40, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
 ; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx
@@ -37,79 +37,83 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-NEXT:    movd %xmm0, %esi
 ; CHECK-NEXT:    movl %esi, %edi
 ; CHECK-NEXT:    andl $8388607, %edi # imm = 0x7FFFFF
-; CHECK-NEXT:    leal 8388608(%rdi), %r9d
-; CHECK-NEXT:    movl %r9d, %r8d
-; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    leal 8388608(%rdi), %r8d
+; CHECK-NEXT:    movl %r8d, %r9d
+; CHECK-NEXT:    shrl %cl, %r9d
 ; CHECK-NEXT:    movl $1, %r10d
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    shll %cl, %r10d
 ; CHECK-NEXT:    decl %r10d
 ; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    testl %r10d, %r9d
+; CHECK-NEXT:    testl %r10d, %r8d
 ; CHECK-NEXT:    setne %r11b
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r9d
-; CHECK-NEXT:    movl %r9d, %r10d
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    movl %r8d, %r10d
 ; CHECK-NEXT:    andl $1, %r10d
 ; CHECK-NEXT:    orl %r11d, %r10d
-; CHECK-NEXT:    andl %r8d, %r10d
-; CHECK-NEXT:    xorl %r8d, %r8d
+; CHECK-NEXT:    andl %r9d, %r10d
+; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %r8d, %r10d
-; CHECK-NEXT:    addl %r9d, %r10d
-; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmovbl %ecx, %r10d
+; CHECK-NEXT:    addl %r8d, %r10d
+; CHECK-NEXT:    xorl %r8d, %r8d
 ; CHECK-NEXT:    cmpl $4, %r10d
-; CHECK-NEXT:    cmovgel %r8d, %r10d
-; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    movd (%rsp), %xmm0 # 4-byte Folded Reload
-; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl $24, %ecx
-; CHECK-NEXT:    andl $-128, %ecx
-; CHECK-NEXT:    leal (%rcx,%r9,4), %r9d
-; CHECK-NEXT:    orl %r10d, %r9d
+; CHECK-NEXT:    cmovgel %ecx, %r10d
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    shrl $24, %eax
+; CHECK-NEXT:    andl $-128, %eax
+; CHECK-NEXT:    leal (%rax,%r8,4), %r8d
+; CHECK-NEXT:    orl %r10d, %r8d
 ; CHECK-NEXT:    shrl $21, %edi
-; CHECK-NEXT:    movl %edi, %r10d
-; CHECK-NEXT:    andl $1, %r10d
-; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    movl %edi, %r9d
+; CHECK-NEXT:    andl $1, %r9d
+; CHECK-NEXT:    xorl %r10d, %r10d
 ; CHECK-NEXT:    testl $1048575, %esi # imm = 0xFFFFF
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %r10d, %r11d
+; CHECK-NEXT:    setne %r10b
+; CHECK-NEXT:    orl %r9d, %r10d
 ; CHECK-NEXT:    shrl $20, %esi
-; CHECK-NEXT:    andl %r11d, %esi
+; CHECK-NEXT:    andl %r10d, %esi
 ; CHECK-NEXT:    addl %edi, %esi
-; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    xorl %edi, %edi
 ; CHECK-NEXT:    cmpl $4, %esi
-; CHECK-NEXT:    cmovgel %r8d, %esi
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    leal (%rdx,%r10), %edi
-; CHECK-NEXT:    leal 56(,%rdi,4), %r8d
-; CHECK-NEXT:    movl %ecx, %edi
-; CHECK-NEXT:    orl %esi, %edi
-; CHECK-NEXT:    orl %r8d, %edi
-; CHECK-NEXT:    leal 14(%rdx,%r10), %edx
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    cmovlel %r9d, %edi
+; CHECK-NEXT:    cmovgel %ecx, %esi
+; CHECK-NEXT:    setge %dil
+; CHECK-NEXT:    leal (%rdx,%rdi), %ecx
+; CHECK-NEXT:    leal 56(,%rcx,4), %ecx
+; CHECK-NEXT:    movl %eax, %r9d
+; CHECK-NEXT:    orl %esi, %r9d
+; CHECK-NEXT:    orl %ecx, %r9d
+; CHECK-NEXT:    leal 14(%rdx,%rdi), %ecx
+; CHECK-NEXT:    testl %ecx, %ecx
+; CHECK-NEXT:    cmovlel %r8d, %r9d
 ; CHECK-NEXT:    cmpl $4, %esi
-; CHECK-NEXT:    setge %sil
-; CHECK-NEXT:    cmpl $30, %edx
-; CHECK-NEXT:    sete %r8b
-; CHECK-NEXT:    andb %sil, %r8b
-; CHECK-NEXT:    cmpl $31, %edx
 ; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    orb %r8b, %dl
-; CHECK-NEXT:    leal 124(%rcx), %esi
-; CHECK-NEXT:    testb %dl, %dl
-; CHECK-NEXT:    cmovnel %esi, %edi
-; CHECK-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmovel %ecx, %edi
-; CHECK-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
-; CHECK-NEXT:    cmovel %esi, %edi
+; CHECK-NEXT:    cmpl $30, %ecx
+; CHECK-NEXT:    sete %sil
+; CHECK-NEXT:    andb %dl, %sil
+; CHECK-NEXT:    cmpl $31, %ecx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    orb %sil, %cl
+; CHECK-NEXT:    leal 124(%rax), %edx
+; CHECK-NEXT:    testb %cl, %cl
+; CHECK-NEXT:    cmovnel %edx, %r9d
+; CHECK-NEXT:    pxor %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r9d, %eax
+; CHECK-NEXT:    cmovpl %r9d, %eax
+; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    andps %xmm1, %xmm0
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    cmovnel %eax, %edx
+; CHECK-NEXT:    cmovpl %eax, %edx
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovlel %edi, %eax
+; CHECK-NEXT:    cmovnpl %edx, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    addq $40, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
@@ -122,66 +126,70 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-LABEL: to_f8e5m2_round_towardzero:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rax
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    movd %xmm0, (%rsp) # 4-byte Folded Spill
+; CHECK-NEXT:    subq $40, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
-; CHECK-NEXT:    movl $8, %edx
-; CHECK-NEXT:    subl %eax, %edx
-; CHECK-NEXT:    cmpl $31, %edx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx
+; CHECK-NEXT:    movl $8, %eax
+; CHECK-NEXT:    subl %edx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
 ; CHECK-NEXT:    movl $31, %ecx
-; CHECK-NEXT:    cmovbl %edx, %ecx
-; CHECK-NEXT:    movd %xmm0, %edx
-; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
-; CHECK-NEXT:    leal 8388608(%rdx), %edi
+; CHECK-NEXT:    cmovbl %eax, %ecx
+; CHECK-NEXT:    movd %xmm0, %esi
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rsi), %edi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    xorl %r8d, %r8d
-; CHECK-NEXT:    xorl %r9d, %r9d
 ; CHECK-NEXT:    cmpl $4, %edi
-; CHECK-NEXT:    cmovgel %r8d, %edi
-; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    movd (%rsp), %xmm0 # 4-byte Folded Reload
-; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
-; CHECK-NEXT:    movd %xmm0, %ecx
-; CHECK-NEXT:    movl %ecx, %esi
-; CHECK-NEXT:    shrl $24, %esi
-; CHECK-NEXT:    andl $-128, %esi
-; CHECK-NEXT:    leal (%rsi,%r9,4), %r9d
-; CHECK-NEXT:    orl %edi, %r9d
-; CHECK-NEXT:    shrl $21, %edx
-; CHECK-NEXT:    xorl %r10d, %r10d
-; CHECK-NEXT:    cmpl $4, %edx
-; CHECK-NEXT:    cmovgel %r8d, %edx
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    leal (%rax,%r10), %edi
-; CHECK-NEXT:    leal 56(,%rdi,4), %edi
-; CHECK-NEXT:    orl %esi, %edi
-; CHECK-NEXT:    orl %edx, %edi
-; CHECK-NEXT:    leal 14(%rax,%r10), %eax
-; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    cmovlel %r9d, %edi
-; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    cmovgel %ecx, %edi
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    shrl $24, %eax
+; CHECK-NEXT:    andl $-128, %eax
+; CHECK-NEXT:    leal (%rax,%r8,4), %r8d
+; CHECK-NEXT:    orl %edi, %r8d
+; CHECK-NEXT:    shrl $21, %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    cmpl $4, %esi
+; CHECK-NEXT:    cmovgel %ecx, %esi
+; CHECK-NEXT:    setge %dil
+; CHECK-NEXT:    leal (%rdx,%rdi), %ecx
+; CHECK-NEXT:    leal 56(,%rcx,4), %ecx
+; CHECK-NEXT:    orl %eax, %ecx
+; CHECK-NEXT:    orl %esi, %ecx
+; CHECK-NEXT:    leal 14(%rdx,%rdi), %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %r8d, %ecx
+; CHECK-NEXT:    cmpl $4, %esi
+; CHECK-NEXT:    setge %sil
+; CHECK-NEXT:    cmpl $30, %edx
+; CHECK-NEXT:    sete %dil
+; CHECK-NEXT:    andb %sil, %dil
+; CHECK-NEXT:    cmpl $31, %edx
 ; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    cmpl $30, %eax
-; CHECK-NEXT:    sete %r8b
-; CHECK-NEXT:    andb %dl, %r8b
-; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    orb %r8b, %al
-; CHECK-NEXT:    leal 124(%rsi), %edx
-; CHECK-NEXT:    testb %al, %al
-; CHECK-NEXT:    cmovnel %edx, %edi
-; CHECK-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmovel %esi, %edi
-; CHECK-NEXT:    cmpl $2139095040, %ecx # imm = 0x7F800000
-; CHECK-NEXT:    cmovel %edx, %edi
+; CHECK-NEXT:    orb %dil, %dl
+; CHECK-NEXT:    leal 124(%rax), %esi
+; CHECK-NEXT:    testb %dl, %dl
+; CHECK-NEXT:    cmovnel %esi, %ecx
+; CHECK-NEXT:    pxor %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %ecx, %eax
+; CHECK-NEXT:    cmovpl %ecx, %eax
+; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    andps %xmm1, %xmm0
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    cmovnel %eax, %esi
+; CHECK-NEXT:    cmovpl %eax, %esi
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovlel %edi, %eax
+; CHECK-NEXT:    cmovnpl %esi, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    addq $40, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.towardzero", i1 false)
@@ -194,331 +202,143 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-LABEL: to_f4e2m1fn_v4f32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rbp
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    pushq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    pushq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    pushq %r13
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    pushq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 48
-; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 56
-; CHECK-NEXT:    subq $152, %rsp
-; CHECK-NEXT:    .cfi_def_cfa_offset 208
-; CHECK-NEXT:    .cfi_offset %rbx, -56
-; CHECK-NEXT:    .cfi_offset %r12, -48
-; CHECK-NEXT:    .cfi_offset %r13, -40
-; CHECK-NEXT:    .cfi_offset %r14, -32
-; CHECK-NEXT:    .cfi_offset %r15, -24
-; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
+; CHECK-NEXT:    subq $88, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 96
 ; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
-; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    movl $23, %eax
-; CHECK-NEXT:    subl %ecx, %eax
-; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    movl $31, %ecx
-; CHECK-NEXT:    cmovael %ecx, %eax
-; CHECK-NEXT:    movl $31, %ebp
-; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movd %xmm0, %r13d
-; CHECK-NEXT:    movl %r13d, %edx
-; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
-; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    leal 8388608(%rdx), %ebx
-; CHECK-NEXT:    movl %ebx, %edx
-; CHECK-NEXT:    shrl %cl, %edx
-; CHECK-NEXT:    movl $1, %esi
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %esi
-; CHECK-NEXT:    decl %esi
-; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %ebx
-; CHECK-NEXT:    setne %dil
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %ebx
-; CHECK-NEXT:    movl %ebx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %ebx
-; CHECK-NEXT:    orl %edi, %ebx
-; CHECK-NEXT:    andl %edx, %ebx
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %ecx, %ebx
-; CHECK-NEXT:    xorl %r14d, %r14d
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1,1]
-; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
-; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    movl $23, %eax
-; CHECK-NEXT:    subl %ecx, %eax
-; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    cmovael %ebp, %eax
-; CHECK-NEXT:    movl $31, %ebp
-; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movd %xmm0, %r12d
-; CHECK-NEXT:    movl %r12d, %edx
-; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
-; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    leal 8388608(%rdx), %r15d
-; CHECK-NEXT:    movl %r15d, %edx
-; CHECK-NEXT:    shrl %cl, %edx
-; CHECK-NEXT:    movl $1, %esi
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %esi
-; CHECK-NEXT:    decl %esi
-; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %r15d
-; CHECK-NEXT:    setne %dil
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r15d
-; CHECK-NEXT:    movl %r15d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %r15d
-; CHECK-NEXT:    orl %edi, %r15d
-; CHECK-NEXT:    andl %edx, %r15d
-; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %r14d, %r15d
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
-; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    movl $23, %eax
-; CHECK-NEXT:    subl %ecx, %eax
-; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    cmovael %ebp, %eax
-; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movd %xmm0, %r14d
-; CHECK-NEXT:    movl %r14d, %edx
-; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
-; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    leal 8388608(%rdx), %ebp
-; CHECK-NEXT:    movl %ebp, %edx
-; CHECK-NEXT:    shrl %cl, %edx
-; CHECK-NEXT:    movl $1, %esi
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %esi
-; CHECK-NEXT:    decl %esi
-; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %ebp
-; CHECK-NEXT:    setne %dil
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %ebp
-; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    orl %edi, %ebp
-; CHECK-NEXT:    andl %edx, %ebp
-; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    movl $0, %eax
-; CHECK-NEXT:    cmovbl %eax, %ebp
-; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
 ; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
+; CHECK-NEXT:    movq %rsp, %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
-; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    movl $23, %edx
-; CHECK-NEXT:    subl %eax, %edx
-; CHECK-NEXT:    cmpl $31, %edx
-; CHECK-NEXT:    movl $31, %eax
-; CHECK-NEXT:    cmovael %eax, %edx
-; CHECK-NEXT:    cmpl $1, %edx
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    movl %eax, %esi
-; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
-; CHECK-NEXT:    leal 8388608(%rsi), %edi
-; CHECK-NEXT:    movl %edi, %r8d
-; CHECK-NEXT:    shrl %cl, %r8d
-; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    movl $1, %r9d
-; CHECK-NEXT:    shll %cl, %r9d
-; CHECK-NEXT:    decl %r9d
-; CHECK-NEXT:    movl %r9d, %ecx
-; CHECK-NEXT:    xorl %r9d, %r9d
-; CHECK-NEXT:    testl %ecx, %edi
-; CHECK-NEXT:    setne %r9b
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    shrl %cl, %edi
-; CHECK-NEXT:    movl %edi, %ecx
-; CHECK-NEXT:    andl $1, %ecx
-; CHECK-NEXT:    orl %r9d, %ecx
-; CHECK-NEXT:    andl %r8d, %ecx
-; CHECK-NEXT:    cmpl $1, %edx
-; CHECK-NEXT:    movl $0, %edx
-; CHECK-NEXT:    cmovbl %edx, %ecx
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebx # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %r10d, %r10d
-; CHECK-NEXT:    cmpl $2, %ebx
-; CHECK-NEXT:    cmovgel %edx, %ebx
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    addl %r10d, %r10d
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm0, %r9d
-; CHECK-NEXT:    movl %r9d, %r8d
-; CHECK-NEXT:    shrl $31, %r8d
-; CHECK-NEXT:    leal (%r10,%r8,8), %r10d
-; CHECK-NEXT:    orl %ebx, %r10d
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
-; CHECK-NEXT:    shrl $22, %ebx
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    testl $2097151, %r13d # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %ebx, %r11d
-; CHECK-NEXT:    shrl $21, %r13d
-; CHECK-NEXT:    andl %r11d, %r13d
-; CHECK-NEXT:    addl %ebx, %r13d
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    cmpl $2, %r13d
-; CHECK-NEXT:    cmovgel %edx, %r13d
-; CHECK-NEXT:    setge %r11b
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
-; CHECK-NEXT:    shll $3, %r8d
-; CHECK-NEXT:    orl %r8d, %r13d
-; CHECK-NEXT:    leal (%r11,%r11), %ebx
-; CHECK-NEXT:    orl %ebx, %r13d
-; CHECK-NEXT:    testl %r11d, %r11d
-; CHECK-NEXT:    cmovlel %r10d, %r13d
-; CHECK-NEXT:    testl $2147483647, %r9d # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmovel %r8d, %r13d
-; CHECK-NEXT:    movd %r13d, %xmm1
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r15d # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %r10d, %r10d
-; CHECK-NEXT:    cmpl $2, %r15d
-; CHECK-NEXT:    cmovgel %edx, %r15d
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    addl %r10d, %r10d
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm0, %r9d
-; CHECK-NEXT:    movl %r9d, %r8d
-; CHECK-NEXT:    shrl $31, %r8d
-; CHECK-NEXT:    leal (%r10,%r8,8), %r10d
-; CHECK-NEXT:    orl %r15d, %r10d
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
-; CHECK-NEXT:    shrl $22, %ebx
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    testl $2097151, %r12d # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %ebx, %r11d
-; CHECK-NEXT:    shrl $21, %r12d
-; CHECK-NEXT:    andl %r11d, %r12d
-; CHECK-NEXT:    addl %ebx, %r12d
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    cmpl $2, %r12d
-; CHECK-NEXT:    cmovgel %edx, %r12d
-; CHECK-NEXT:    setge %r11b
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
-; CHECK-NEXT:    shll $3, %r8d
-; CHECK-NEXT:    orl %r8d, %r12d
-; CHECK-NEXT:    leal (%r11,%r11), %ebx
-; CHECK-NEXT:    orl %ebx, %r12d
-; CHECK-NEXT:    testl %r11d, %r11d
-; CHECK-NEXT:    cmovlel %r10d, %r12d
-; CHECK-NEXT:    testl $2147483647, %r9d # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmovel %r8d, %r12d
-; CHECK-NEXT:    movd %r12d, %xmm2
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %r10d, %r10d
-; CHECK-NEXT:    cmpl $2, %ebp
-; CHECK-NEXT:    cmovgel %edx, %ebp
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    addl %r10d, %r10d
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm0, %r9d
-; CHECK-NEXT:    movl %r9d, %r8d
-; CHECK-NEXT:    shrl $31, %r8d
-; CHECK-NEXT:    leal (%r10,%r8,8), %r10d
-; CHECK-NEXT:    orl %ebp, %r10d
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
-; CHECK-NEXT:    shrl $22, %ebx
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    testl $2097151, %r14d # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %ebx, %r11d
-; CHECK-NEXT:    shrl $21, %r14d
-; CHECK-NEXT:    andl %r11d, %r14d
-; CHECK-NEXT:    addl %ebx, %r14d
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    cmpl $2, %r14d
-; CHECK-NEXT:    cmovgel %edx, %r14d
-; CHECK-NEXT:    setge %r11b
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r11d # 4-byte Folded Reload
-; CHECK-NEXT:    leal (%r11,%r11), %ebx
-; CHECK-NEXT:    shll $3, %r8d
-; CHECK-NEXT:    orl %r8d, %r14d
-; CHECK-NEXT:    orl %ebx, %r14d
-; CHECK-NEXT:    testl %r11d, %r11d
-; CHECK-NEXT:    cmovlel %r10d, %r14d
-; CHECK-NEXT:    testl $2147483647, %r9d # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmovel %r8d, %r14d
-; CHECK-NEXT:    movd %r14d, %xmm0
-; CHECK-NEXT:    addl %edi, %ecx
-; CHECK-NEXT:    xorl %r9d, %r9d
-; CHECK-NEXT:    cmpl $2, %ecx
-; CHECK-NEXT:    cmovgel %edx, %ecx
-; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    addl %r9d, %r9d
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm3, %r8d
-; CHECK-NEXT:    movl %r8d, %edi
-; CHECK-NEXT:    shrl $31, %edi
-; CHECK-NEXT:    leal (%r9,%rdi,8), %r9d
-; CHECK-NEXT:    orl %ecx, %r9d
-; CHECK-NEXT:    shrl $22, %esi
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testl $2097151, %eax # imm = 0x1FFFFF
-; CHECK-NEXT:    setne %cl
-; CHECK-NEXT:    orl %esi, %ecx
-; CHECK-NEXT:    shrl $21, %eax
-; CHECK-NEXT:    andl %ecx, %eax
-; CHECK-NEXT:    addl %esi, %eax
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpl $2, %eax
-; CHECK-NEXT:    cmovgel %edx, %eax
-; CHECK-NEXT:    setge %cl
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
-; CHECK-NEXT:    leal (%rcx,%rcx), %edx
-; CHECK-NEXT:    shll $3, %edi
-; CHECK-NEXT:    orl %edi, %eax
-; CHECK-NEXT:    orl %edx, %eax
-; CHECK-NEXT:    testl %ecx, %ecx
-; CHECK-NEXT:    cmovlel %r9d, %eax
-; CHECK-NEXT:    testl $2147483647, %r8d # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmovel %edi, %eax
-; CHECK-NEXT:    movd %eax, %xmm3
+; CHECK-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
 ; CHECK-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
-; CHECK-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
-; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
-; CHECK-NEXT:    addq $152, %rsp
-; CHECK-NEXT:    .cfi_def_cfa_offset 56
-; CHECK-NEXT:    popq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 48
-; CHECK-NEXT:    popq %r12
-; CHECK-NEXT:    .cfi_def_cfa_offset 40
-; CHECK-NEXT:    popq %r13
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    popq %r14
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %r15
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; CHECK-NEXT:    movdqa {{.*#+}} xmm2 = [23,23,23,23]
+; CHECK-NEXT:    psubd %xmm1, %xmm2
+; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648]
+; CHECK-NEXT:    movdqa %xmm2, %xmm3
+; CHECK-NEXT:    pxor %xmm4, %xmm3
+; CHECK-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
+; CHECK-NEXT:    movdqa %xmm3, %xmm5
+; CHECK-NEXT:    pandn %xmm2, %xmm5
+; CHECK-NEXT:    psrld $27, %xmm3
+; CHECK-NEXT:    por %xmm5, %xmm3
+; CHECK-NEXT:    pxor %xmm2, %xmm2
+; CHECK-NEXT:    movdqa %xmm3, %xmm7
+; CHECK-NEXT:    pcmpeqd %xmm2, %xmm7
+; CHECK-NEXT:    pcmpeqd %xmm6, %xmm6
+; CHECK-NEXT:    pxor %xmm6, %xmm7
+; CHECK-NEXT:    paddd %xmm3, %xmm7
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm9 = xmm7[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm5 # 16-byte Reload
+; CHECK-NEXT:    unpcklps {{.*#+}} xmm5 = xmm5[0],xmm0[0],xmm5[1],xmm0[1]
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Reload
+; CHECK-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm14 # 16-byte Folded Reload
+; CHECK-NEXT:    # xmm14 = xmm14[0],mem[0],xmm14[1],mem[1]
+; CHECK-NEXT:    movlhps {{.*#+}} xmm14 = xmm14[0],xmm5[0]
+; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [8388607,8388607,8388607,8388607]
+; CHECK-NEXT:    andps %xmm14, %xmm0
+; CHECK-NEXT:    movaps {{.*#+}} xmm8 = [8388608,8388608,8388608,8388608]
+; CHECK-NEXT:    orps %xmm0, %xmm8
+; CHECK-NEXT:    movaps %xmm8, %xmm5
+; CHECK-NEXT:    movaps %xmm8, %xmm10
+; CHECK-NEXT:    movaps %xmm8, %xmm11
+; CHECK-NEXT:    movaps %xmm8, %xmm12
+; CHECK-NEXT:    movaps %xmm8, %xmm13
+; CHECK-NEXT:    psrld %xmm9, %xmm13
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm9 = xmm7[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm9, %xmm5
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm13[0]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm13 = xmm7[2,3,2,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm9 = xmm13[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm9, %xmm10
+; CHECK-NEXT:    movaps %xmm8, %xmm9
+; CHECK-NEXT:    pslld $23, %xmm7
+; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm7 # [1065353216,1065353216,1065353216,1065353216]
+; CHECK-NEXT:    cvttps2dq %xmm7, %xmm7
+; CHECK-NEXT:    paddd %xmm6, %xmm7
+; CHECK-NEXT:    movaps %xmm8, %xmm6
+; CHECK-NEXT:    pand %xmm8, %xmm7
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm13 = xmm13[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm13, %xmm11
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm11 = xmm11[1],xmm10[1]
+; CHECK-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,3],xmm11[0,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm10 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm10, %xmm12
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm10 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm10, %xmm9
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm9 = xmm9[0],xmm12[0]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm10 = xmm3[2,3,2,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm11 = xmm10[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm11, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm10 = xmm10[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm10, %xmm8
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm8 = xmm8[1],xmm6[1]
+; CHECK-NEXT:    shufps {{.*#+}} xmm9 = xmm9[0,3],xmm8[0,3]
+; CHECK-NEXT:    pcmpgtd %xmm2, %xmm7
+; CHECK-NEXT:    por %xmm9, %xmm7
+; CHECK-NEXT:    pxor %xmm4, %xmm3
+; CHECK-NEXT:    pcmpgtd %xmm4, %xmm3
+; CHECK-NEXT:    pand %xmm5, %xmm3
+; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [1,1,1,1]
+; CHECK-NEXT:    pand %xmm4, %xmm3
+; CHECK-NEXT:    pand %xmm7, %xmm3
+; CHECK-NEXT:    paddd %xmm9, %xmm3
+; CHECK-NEXT:    movdqa %xmm3, %xmm6
+; CHECK-NEXT:    pcmpgtd %xmm4, %xmm6
+; CHECK-NEXT:    movdqa %xmm6, %xmm5
+; CHECK-NEXT:    pandn %xmm3, %xmm5
+; CHECK-NEXT:    psrld $31, %xmm6
+; CHECK-NEXT:    paddd %xmm6, %xmm6
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; CHECK-NEXT:    movdqa %xmm7, %xmm3
+; CHECK-NEXT:    psrld $31, %xmm3
+; CHECK-NEXT:    pslld $3, %xmm3
+; CHECK-NEXT:    por %xmm3, %xmm5
+; CHECK-NEXT:    por %xmm6, %xmm5
+; CHECK-NEXT:    movaps {{.*#+}} xmm6 = [2097151,2097151,2097151,2097151]
+; CHECK-NEXT:    movaps %xmm14, %xmm8
+; CHECK-NEXT:    andps %xmm14, %xmm6
+; CHECK-NEXT:    pcmpgtd %xmm2, %xmm6
+; CHECK-NEXT:    psrld $22, %xmm0
+; CHECK-NEXT:    por %xmm0, %xmm6
+; CHECK-NEXT:    psrld $21, %xmm8
+; CHECK-NEXT:    pand %xmm4, %xmm8
+; CHECK-NEXT:    pand %xmm6, %xmm8
+; CHECK-NEXT:    paddd %xmm0, %xmm8
+; CHECK-NEXT:    movdqa %xmm8, %xmm0
+; CHECK-NEXT:    pcmpgtd %xmm4, %xmm0
+; CHECK-NEXT:    paddd %xmm0, %xmm1
+; CHECK-NEXT:    pcmpgtd %xmm1, %xmm4
+; CHECK-NEXT:    pand %xmm4, %xmm5
+; CHECK-NEXT:    pandn %xmm8, %xmm0
+; CHECK-NEXT:    paddd %xmm1, %xmm1
+; CHECK-NEXT:    por %xmm3, %xmm0
+; CHECK-NEXT:    por %xmm1, %xmm0
+; CHECK-NEXT:    pandn %xmm0, %xmm4
+; CHECK-NEXT:    por %xmm5, %xmm4
+; CHECK-NEXT:    movdqa %xmm7, %xmm0
+; CHECK-NEXT:    cmpeqps %xmm2, %xmm0
+; CHECK-NEXT:    pand %xmm0, %xmm3
+; CHECK-NEXT:    pandn %xmm4, %xmm0
+; CHECK-NEXT:    por %xmm3, %xmm0
+; CHECK-NEXT:    addq $88, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float> %x, metadata !"Float4E2M1FN", metadata !"round.tonearest", i1 false)
@@ -537,116 +357,127 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    subq $16, %rsp
-; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    subq $32, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
 ; CHECK-NEXT:    .cfi_offset %rbx, -32
 ; CHECK-NEXT:    .cfi_offset %r14, -24
 ; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    callq __extendhfsf2 at PLT
 ; CHECK-NEXT:    mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    callq __truncsfhf2 at PLT
-; CHECK-NEXT:    pextrw $0, %xmm0, %edi
-; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    andl $31744, %eax # imm = 0x7C00
-; CHECK-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    pextrw $0, %xmm0, %edx
-; CHECK-NEXT:    movl %edx, %esi
-; CHECK-NEXT:    andl $32767, %esi # imm = 0x7FFF
-; CHECK-NEXT:    cmpl $1024, %esi # imm = 0x400
-; CHECK-NEXT:    cmovael %edx, %edi
-; CHECK-NEXT:    cmovael %esi, %eax
+; CHECK-NEXT:    movl %edx, %eax
+; CHECK-NEXT:    andl $31744, %eax # imm = 0x7C00
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    pextrw $0, %xmm0, %ebx
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    andl $32767, %ecx # imm = 0x7FFF
+; CHECK-NEXT:    cmpl $1024, %ecx # imm = 0x400
+; CHECK-NEXT:    cmovael %ebx, %edx
+; CHECK-NEXT:    cmovael %ecx, %eax
 ; CHECK-NEXT:    shrl $10, %eax
-; CHECK-NEXT:    leal -12(%rax), %r8d
-; CHECK-NEXT:    cmpl $1024, %esi # imm = 0x400
-; CHECK-NEXT:    cmovael %eax, %r8d
-; CHECK-NEXT:    addl $-14, %r8d
-; CHECK-NEXT:    andl $33791, %edi # imm = 0x83FF
-; CHECK-NEXT:    orl $14336, %edi # imm = 0x3800
-; CHECK-NEXT:    leal -31744(%rsi), %eax
-; CHECK-NEXT:    movzwl %ax, %eax
-; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    leal -12(%rax), %esi
+; CHECK-NEXT:    cmpl $1024, %ecx # imm = 0x400
+; CHECK-NEXT:    cmovael %eax, %esi
+; CHECK-NEXT:    addl $-14, %esi
+; CHECK-NEXT:    andl $33791, %edx # imm = 0x83FF
+; CHECK-NEXT:    orl $14336, %edx # imm = 0x3800
+; CHECK-NEXT:    addl $-31744, %ecx # imm = 0x8400
+; CHECK-NEXT:    movzwl %cx, %eax
+; CHECK-NEXT:    xorl %edi, %edi
 ; CHECK-NEXT:    cmpl $33792, %eax # imm = 0x8400
-; CHECK-NEXT:    cmovbel %r9d, %r8d
-; CHECK-NEXT:    cmovbel %edx, %edi
+; CHECK-NEXT:    cmovbel %edi, %esi
+; CHECK-NEXT:    cmovbel %ebx, %edx
 ; CHECK-NEXT:    movl $-5, %ecx
-; CHECK-NEXT:    subl %r8d, %ecx
+; CHECK-NEXT:    subl %esi, %ecx
 ; CHECK-NEXT:    cmpw $15, %cx
 ; CHECK-NEXT:    movl $15, %eax
 ; CHECK-NEXT:    cmovbl %ecx, %eax
 ; CHECK-NEXT:    cmpw $1, %ax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
-; CHECK-NEXT:    movl %edi, %r10d
-; CHECK-NEXT:    andl $1023, %r10d # imm = 0x3FF
-; CHECK-NEXT:    leal 1024(%r10), %r11d
-; CHECK-NEXT:    movl %r11d, %ebx
-; CHECK-NEXT:    shrl %cl, %ebx
-; CHECK-NEXT:    movl $1, %ebp
+; CHECK-NEXT:    movl %edx, %r8d
+; CHECK-NEXT:    andl $1023, %r8d # imm = 0x3FF
+; CHECK-NEXT:    leal 1024(%r8), %r9d
+; CHECK-NEXT:    movl %r9d, %r10d
+; CHECK-NEXT:    shrl %cl, %r10d
+; CHECK-NEXT:    movl $1, %r11d
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT:    shll %cl, %ebp
-; CHECK-NEXT:    decl %ebp
-; CHECK-NEXT:    xorl %r14d, %r14d
-; CHECK-NEXT:    testw %bp, %r11w
-; CHECK-NEXT:    setne %r14b
+; CHECK-NEXT:    shll %cl, %r11d
+; CHECK-NEXT:    decl %r11d
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    testw %r11w, %r9w
+; CHECK-NEXT:    setne %bpl
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r11d
-; CHECK-NEXT:    movl %r11d, %ecx
+; CHECK-NEXT:    shrl %cl, %r9d
+; CHECK-NEXT:    movl %r9d, %ecx
 ; CHECK-NEXT:    andl $1, %ecx
-; CHECK-NEXT:    orl %r14d, %ecx
-; CHECK-NEXT:    andl %ebx, %ecx
+; CHECK-NEXT:    orl %ebp, %ecx
+; CHECK-NEXT:    andl %r10d, %ecx
 ; CHECK-NEXT:    cmpw $1, %ax
-; CHECK-NEXT:    cmovbl %r9d, %ecx
-; CHECK-NEXT:    addl %r11d, %ecx
+; CHECK-NEXT:    cmovbl %edi, %ecx
+; CHECK-NEXT:    addl %r9d, %ecx
 ; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    cmpw $4, %cx
-; CHECK-NEXT:    cmovgel %r9d, %ecx
+; CHECK-NEXT:    cmovgel %edi, %ecx
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    shrl $8, %edx
-; CHECK-NEXT:    andl $128, %edx
-; CHECK-NEXT:    leal (%rdx,%rax,4), %eax
+; CHECK-NEXT:    shrl $8, %ebx
+; CHECK-NEXT:    andl $128, %ebx
+; CHECK-NEXT:    leal (%rbx,%rax,4), %eax
 ; CHECK-NEXT:    orl %ecx, %eax
-; CHECK-NEXT:    shrl $8, %r10d
-; CHECK-NEXT:    movl %r10d, %ecx
+; CHECK-NEXT:    shrl $8, %r8d
+; CHECK-NEXT:    movl %r8d, %ecx
 ; CHECK-NEXT:    andl $1, %ecx
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    testb $127, %dil
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %ecx, %r11d
-; CHECK-NEXT:    shrl $7, %edi
-; CHECK-NEXT:    andl %r11d, %edi
-; CHECK-NEXT:    addl %r10d, %edi
-; CHECK-NEXT:    xorl %r10d, %r10d
-; CHECK-NEXT:    cmpw $4, %di
-; CHECK-NEXT:    cmovgel %r9d, %edi
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    leal (%r8,%r10), %ecx
-; CHECK-NEXT:    leal 56(,%rcx,4), %r9d
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    orl %edi, %ecx
-; CHECK-NEXT:    orl %r9d, %ecx
-; CHECK-NEXT:    leal 14(%r8,%r10), %r8d
-; CHECK-NEXT:    testw %r8w, %r8w
-; CHECK-NEXT:    cmovlel %eax, %ecx
-; CHECK-NEXT:    cmpw $4, %di
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testb $127, %dl
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    orl %ecx, %r9d
+; CHECK-NEXT:    shrl $7, %edx
+; CHECK-NEXT:    andl %r9d, %edx
+; CHECK-NEXT:    addl %r8d, %edx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpw $4, %dx
+; CHECK-NEXT:    cmovgel %edi, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    leal (%rsi,%rcx), %edi
+; CHECK-NEXT:    leal 56(,%rdi,4), %edi
+; CHECK-NEXT:    movl %ebx, %ebp
+; CHECK-NEXT:    orl %edx, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    leal 14(%rsi,%rcx), %ecx
+; CHECK-NEXT:    testw %cx, %cx
+; CHECK-NEXT:    cmovlel %eax, %ebp
+; CHECK-NEXT:    cmpw $4, %dx
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    cmpw $30, %r8w
-; CHECK-NEXT:    sete %dil
-; CHECK-NEXT:    andb %al, %dil
-; CHECK-NEXT:    cmpw $31, %r8w
+; CHECK-NEXT:    cmpw $30, %cx
+; CHECK-NEXT:    sete %dl
+; CHECK-NEXT:    andb %al, %dl
+; CHECK-NEXT:    cmpw $31, %cx
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    orb %dil, %al
-; CHECK-NEXT:    leal 124(%rdx), %edi
+; CHECK-NEXT:    orb %dl, %al
+; CHECK-NEXT:    leal 124(%rbx), %r14d
 ; CHECK-NEXT:    testb %al, %al
-; CHECK-NEXT:    cmovnel %edi, %ecx
-; CHECK-NEXT:    testl %esi, %esi
-; CHECK-NEXT:    cmovel %edx, %ecx
-; CHECK-NEXT:    cmpl $31744, %esi # imm = 0x7C00
-; CHECK-NEXT:    cmovel %edi, %ecx
+; CHECK-NEXT:    cmovnel %r14d, %ebp
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm1, %xmm0
+; CHECK-NEXT:    cmovnel %ebp, %ebx
+; CHECK-NEXT:    cmovpl %ebp, %ebx
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    cmovnel %ebx, %r14d
+; CHECK-NEXT:    cmovpl %ebx, %r14d
+; CHECK-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    ucomiss %xmm0, %xmm0
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovlel %ecx, %eax
+; CHECK-NEXT:    cmovnpl %r14d, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    addq $16, %rsp
+; CHECK-NEXT:    addq $32, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
@@ -663,18 +494,16 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-LABEL: to_f8e5m2_from_bf16:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pushq %rbp
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    pushq %rax
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
-; CHECK-NEXT:    .cfi_offset %rbx, -24
-; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    subq $32, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    .cfi_offset %rbx, -16
 ; CHECK-NEXT:    pextrw $0, %xmm0, %ebx
-; CHECK-NEXT:    movl %ebx, %ebp
-; CHECK-NEXT:    shll $16, %ebp
-; CHECK-NEXT:    movd %ebp, %xmm0
+; CHECK-NEXT:    movl %ebx, %eax
+; CHECK-NEXT:    shll $16, %eax
+; CHECK-NEXT:    movd %eax, %xmm0
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
 ; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx
@@ -732,36 +561,41 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-NEXT:    cmovgel %ecx, %esi
 ; CHECK-NEXT:    setge %dil
 ; CHECK-NEXT:    leal (%rdx,%rdi), %ecx
-; CHECK-NEXT:    leal 56(,%rcx,4), %r8d
-; CHECK-NEXT:    movl %ebx, %ecx
-; CHECK-NEXT:    orl %esi, %ecx
-; CHECK-NEXT:    orl %r8d, %ecx
-; CHECK-NEXT:    leal 14(%rdx,%rdi), %edx
-; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    cmovlel %eax, %ecx
+; CHECK-NEXT:    leal 56(,%rcx,4), %ecx
+; CHECK-NEXT:    movl %ebx, %r8d
+; CHECK-NEXT:    orl %esi, %r8d
+; CHECK-NEXT:    orl %ecx, %r8d
+; CHECK-NEXT:    leal 14(%rdx,%rdi), %ecx
+; CHECK-NEXT:    testl %ecx, %ecx
+; CHECK-NEXT:    cmovlel %eax, %r8d
 ; CHECK-NEXT:    cmpl $4, %esi
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    cmpl $30, %edx
-; CHECK-NEXT:    sete %sil
-; CHECK-NEXT:    andb %al, %sil
-; CHECK-NEXT:    cmpl $31, %edx
+; CHECK-NEXT:    cmpl $30, %ecx
+; CHECK-NEXT:    sete %dl
+; CHECK-NEXT:    andb %al, %dl
+; CHECK-NEXT:    cmpl $31, %ecx
 ; CHECK-NEXT:    setge %al
-; CHECK-NEXT:    orb %sil, %al
-; CHECK-NEXT:    leal 124(%rbx), %edx
+; CHECK-NEXT:    orb %dl, %al
+; CHECK-NEXT:    leal 124(%rbx), %ecx
 ; CHECK-NEXT:    testb %al, %al
-; CHECK-NEXT:    cmovnel %edx, %ecx
-; CHECK-NEXT:    andl $2147418112, %ebp # imm = 0x7FFF0000
-; CHECK-NEXT:    cmovel %ebx, %ecx
-; CHECK-NEXT:    cmpl $2139095040, %ebp # imm = 0x7F800000
-; CHECK-NEXT:    cmovel %edx, %ecx
+; CHECK-NEXT:    cmovnel %ecx, %r8d
+; CHECK-NEXT:    pxor %xmm0, %xmm0
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r8d, %ebx
+; CHECK-NEXT:    cmovpl %r8d, %ebx
+; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    andps %xmm1, %xmm0
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    cmovnel %ebx, %ecx
+; CHECK-NEXT:    cmovpl %ebx, %ecx
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovlel %ecx, %eax
+; CHECK-NEXT:    cmovnpl %ecx, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    addq $8, %rsp
-; CHECK-NEXT:    .cfi_def_cfa_offset 24
-; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    addq $32, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK-NEXT:    retq
   %r = call i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
@@ -774,10 +608,10 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    subq $16, %rsp
-; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    subq $32, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
 ; CHECK-NEXT:    .cfi_offset %rbx, -16
-; CHECK-NEXT:    movq %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexp at PLT
 ; CHECK-NEXT:    movslq {{[0-9]+}}(%rsp), %rsi
@@ -811,66 +645,68 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-NEXT:    movl %edx, %ecx
 ; CHECK-NEXT:    shrq %cl, %r9
 ; CHECK-NEXT:    andl %ebx, %r9d
-; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpq $1, %rax
-; CHECK-NEXT:    cmovbq %rdx, %r9
+; CHECK-NEXT:    cmovbq %rcx, %r9
 ; CHECK-NEXT:    addq %r10, %r9
-; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    xorl %edx, %edx
 ; CHECK-NEXT:    cmpq $4, %r9
-; CHECK-NEXT:    cmovgeq %rdx, %r9
-; CHECK-NEXT:    setge %r10b
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 8-byte Folded Reload
-; CHECK-NEXT:    # xmm0 = mem[0],zero
-; CHECK-NEXT:    movq %xmm0, %rcx
-; CHECK-NEXT:    movq %rcx, %rax
+; CHECK-NEXT:    cmovgeq %rcx, %r9
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movq %xmm1, %rax
 ; CHECK-NEXT:    shrq $63, %rax
 ; CHECK-NEXT:    shll $7, %eax
-; CHECK-NEXT:    leal (%rax,%r10,4), %r10d
-; CHECK-NEXT:    orq %r9, %r10
+; CHECK-NEXT:    leal (%rax,%rdx,4), %edx
+; CHECK-NEXT:    orq %r9, %rdx
 ; CHECK-NEXT:    shrq $50, %r8
 ; CHECK-NEXT:    movl %r8d, %r9d
 ; CHECK-NEXT:    andl $1, %r9d
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    movq %rdi, %rbx
-; CHECK-NEXT:    shlq $15, %rbx
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %r9d, %r11d
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    movq %rdi, %r11
+; CHECK-NEXT:    shlq $15, %r11
+; CHECK-NEXT:    setne %r10b
+; CHECK-NEXT:    orl %r9d, %r10d
 ; CHECK-NEXT:    shrq $49, %rdi
-; CHECK-NEXT:    andl %r11d, %edi
+; CHECK-NEXT:    andl %r10d, %edi
 ; CHECK-NEXT:    addq %r8, %rdi
 ; CHECK-NEXT:    xorl %r8d, %r8d
 ; CHECK-NEXT:    cmpq $4, %rdi
-; CHECK-NEXT:    cmovgeq %rdx, %rdi
+; CHECK-NEXT:    cmovgeq %rcx, %rdi
 ; CHECK-NEXT:    setge %r8b
-; CHECK-NEXT:    leaq (%rsi,%r8), %rdx
-; CHECK-NEXT:    leaq 56(,%rdx,4), %r9
-; CHECK-NEXT:    movq %rax, %rdx
-; CHECK-NEXT:    orq %rdi, %rdx
-; CHECK-NEXT:    orq %r9, %rdx
-; CHECK-NEXT:    leaq 14(%rsi,%r8), %rsi
-; CHECK-NEXT:    testq %rsi, %rsi
-; CHECK-NEXT:    cmovleq %r10, %rdx
+; CHECK-NEXT:    leaq (%rsi,%r8), %rcx
+; CHECK-NEXT:    leaq 56(,%rcx,4), %rcx
+; CHECK-NEXT:    movq %rax, %r9
+; CHECK-NEXT:    orq %rdi, %r9
+; CHECK-NEXT:    orq %rcx, %r9
+; CHECK-NEXT:    leaq 14(%rsi,%r8), %rcx
+; CHECK-NEXT:    testq %rcx, %rcx
+; CHECK-NEXT:    cmovleq %rdx, %r9
 ; CHECK-NEXT:    cmpq $4, %rdi
-; CHECK-NEXT:    setge %dil
-; CHECK-NEXT:    cmpq $30, %rsi
-; CHECK-NEXT:    sete %r8b
-; CHECK-NEXT:    andb %dil, %r8b
-; CHECK-NEXT:    cmpq $31, %rsi
-; CHECK-NEXT:    setge %sil
-; CHECK-NEXT:    orb %r8b, %sil
-; CHECK-NEXT:    leaq 124(%rax), %rdi
-; CHECK-NEXT:    testb %sil, %sil
-; CHECK-NEXT:    cmovneq %rdi, %rdx
-; CHECK-NEXT:    movabsq $9223372036854775807, %rsi # imm = 0x7FFFFFFFFFFFFFFF
-; CHECK-NEXT:    andq %rcx, %rsi
-; CHECK-NEXT:    cmoveq %rax, %rdx
-; CHECK-NEXT:    movabsq $9218868437227405312, %rax # imm = 0x7FF0000000000000
-; CHECK-NEXT:    cmpq %rax, %rsi
-; CHECK-NEXT:    cmoveq %rdi, %rdx
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    cmpq $30, %rcx
+; CHECK-NEXT:    sete %sil
+; CHECK-NEXT:    andb %dl, %sil
+; CHECK-NEXT:    cmpq $31, %rcx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    orb %sil, %cl
+; CHECK-NEXT:    leaq 124(%rax), %rdx
+; CHECK-NEXT:    testb %cl, %cl
+; CHECK-NEXT:    cmovneq %rdx, %r9
+; CHECK-NEXT:    pxor %xmm0, %xmm0
+; CHECK-NEXT:    ucomisd %xmm0, %xmm1
+; CHECK-NEXT:    cmovneq %r9, %rax
+; CHECK-NEXT:    cmovpq %r9, %rax
+; CHECK-NEXT:    movapd {{.*#+}} xmm0 = [NaN,NaN]
+; CHECK-NEXT:    andpd %xmm1, %xmm0
+; CHECK-NEXT:    ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    cmovneq %rax, %rdx
+; CHECK-NEXT:    cmovpq %rax, %rdx
+; CHECK-NEXT:    ucomisd %xmm1, %xmm1
 ; CHECK-NEXT:    movl $126, %eax
-; CHECK-NEXT:    cmovleq %rdx, %rax
+; CHECK-NEXT:    cmovnpq %rdx, %rax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $rax
-; CHECK-NEXT:    addq $16, %rsp
+; CHECK-NEXT:    addq $32, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    .cfi_def_cfa_offset 8

>From bb88c57a206c7eea88f28d6f51d804f0cc53a8e6 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Wed, 6 May 2026 20:31:44 +0200
Subject: [PATCH 7/9] add more vector cases

---
 .../CodeGen/AMDGPU/float-to-arbitrary-fp.ll   |  874 +++++++-
 .../CodeGen/NVPTX/float-to-arbitrary-fp.ll    | 1302 +++++++++++-
 .../test/CodeGen/X86/float-to-arbitrary-fp.ll | 1753 ++++++++++++++++-
 3 files changed, 3925 insertions(+), 4 deletions(-)

diff --git a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
index 94618ef705f19..767849bed5bac 100644
--- a/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/AMDGPU/float-to-arbitrary-fp.ll
@@ -7,6 +7,10 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
 declare i6 @llvm.convert.to.arbitrary.fp.i6.f32(float, metadata, metadata, i1)
 declare i4 @llvm.convert.to.arbitrary.fp.i4.f32(float, metadata, metadata, i1)
 declare <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float>, metadata, metadata, i1)
+declare <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float>, metadata, metadata, i1)
+declare <3 x i8> @llvm.convert.to.arbitrary.fp.v3i8.v3f32(<3 x float>, metadata, metadata, i1)
+declare <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float>, metadata, metadata, i1)
+declare <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f16(<2 x half>, metadata, metadata, i1)
 
 declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1)
 declare i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat, metadata, metadata, i1)
@@ -127,7 +131,7 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
   ret i8 %r
 }
 
-; Vector test: f32 <4 x float> -> <4 x i4> Float4E2M1FN
+; <4 x float> -> <4 x i4> Float4E2M1FN
 define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-LABEL: to_f4e2m1fn_v4f32:
 ; CHECK:       ; %bb.0:
@@ -301,6 +305,874 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
   ret <4 x i4> %r
 }
 
+; <2 x float> -> <2 x i8> Float8E5M2
+define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
+; CHECK-LABEL: to_f8e5m2_v2f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v4, v1
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v2, v1
+; CHECK-NEXT:    v_sub_u32_e32 v5, 8, v4
+; CHECK-NEXT:    v_and_b32_e32 v3, 0x7fffff, v2
+; CHECK-NEXT:    v_min_u32_e32 v5, 31, v5
+; CHECK-NEXT:    v_or_b32_e32 v3, 0x800000, v3
+; CHECK-NEXT:    v_sub_u32_e64 v7, v5, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v8, v3, 0, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v5, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v8, v6, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, v7, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; CHECK-NEXT:    v_add_u32_e32 v3, v6, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v3
+; CHECK-NEXT:    s_movk_i32 s6, 0x80
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v6, v1, s6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v3, v6, v5, v3
+; CHECK-NEXT:    v_and_b32_e32 v5, 0xfffff, v2
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v7, v2, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v5, v7, 1, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v2, 20, v2
+; CHECK-NEXT:    v_and_b32_e32 v2, v2, v5
+; CHECK-NEXT:    v_add_u32_e32 v2, v7, v2
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v4, vcc, 14, v4, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v5, 2, v4
+; CHECK-NEXT:    v_or3_b32 v5, v6, v5, v2
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v5, v3, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v2
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v4
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v4
+; CHECK-NEXT:    v_or_b32_e32 v2, 0x7c, v6
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v2, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v6, vcc
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v0
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v0
+; CHECK-NEXT:    v_sub_u32_e32 v7, 8, v6
+; CHECK-NEXT:    s_movk_i32 s7, 0x204
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v1, s7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v3, v2, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x7e
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v1, v1
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v3, v2, vcc
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v8, v0, s6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0xfffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v9, v4, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v7, v9, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 20, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v7
+; CHECK-NEXT:    v_add_u32_e32 v4, v9, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 14, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 2, v6
+; CHECK-NEXT:    v_or3_b32 v7, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v7, v5, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v4
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v6
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v6
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v8
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v5, v4, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v5, v8, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, s7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v5, v4, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_lshlrev_b16_e32 v2, 8, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v3, v4, vcc
+; CHECK-NEXT:    v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_and_b32_e32 v1, 0xff, v1
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float> %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
+; <2 x float> -> <2 x i8> Float8E4M3FN
+define <2 x i8> @to_f8e4m3fn_v2f32(<2 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v2f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v4, v1
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v2, v1
+; CHECK-NEXT:    v_sub_u32_e32 v5, 15, v4
+; CHECK-NEXT:    v_and_b32_e32 v3, 0x7fffff, v2
+; CHECK-NEXT:    v_min_u32_e32 v5, 31, v5
+; CHECK-NEXT:    v_or_b32_e32 v3, 0x800000, v3
+; CHECK-NEXT:    v_sub_u32_e64 v7, v5, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v8, v3, 0, v7
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v5, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v8, v6, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, v7, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; CHECK-NEXT:    v_add_u32_e32 v3, v6, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v3
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v6, v1, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v3, v6, v5, v3
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7ffff, v2
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v7, v2, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v5, v7, 1, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v2, 19, v2
+; CHECK-NEXT:    v_and_b32_e32 v2, v2, v5
+; CHECK-NEXT:    v_add_u32_e32 v2, v7, v2
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, v2, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v4, vcc, 6, v4, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v5, 3, v4
+; CHECK-NEXT:    v_or3_b32 v2, v6, v5, v2
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v6, vcc
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v0
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v0
+; CHECK-NEXT:    v_sub_u32_e32 v7, 15, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_mov_b32_e32 v3, 0x7f
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v1, v1
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v3, v2, vcc
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v8, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0x7ffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v9, v4, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v7, v9, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 19, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v7
+; CHECK-NEXT:    v_add_u32_e32 v4, v9, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 6, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 3, v6
+; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v8, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_lshlrev_b16_e32 v2, 8, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v3, v4, vcc
+; CHECK-NEXT:    v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_and_b32_e32 v1, 0xff, v1
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
+; <3 x float> -> <3 x i8> Float8E4M3FN
+define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v3f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v5, v0
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v3, v0
+; CHECK-NEXT:    v_sub_u32_e32 v6, 15, v5
+; CHECK-NEXT:    v_and_b32_e32 v4, 0x7fffff, v3
+; CHECK-NEXT:    v_min_u32_e32 v6, 31, v6
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x800000, v4
+; CHECK-NEXT:    v_sub_u32_e64 v8, v6, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v9, v4, 0, v8
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v7, v6, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v9, v7, 1, v9
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, v8, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, 0, v4, vcc
+; CHECK-NEXT:    v_add_u32_e32 v4, v7, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v4
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v7, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v4, v7, v6, v4
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7ffff, v3
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v8, v3, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v6, v8, 1, v6
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 19, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v6
+; CHECK-NEXT:    v_add_u32_e32 v3, v8, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v5, vcc, 6, v5, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v6, 3, v5
+; CHECK-NEXT:    v_or3_b32 v3, v7, v6, v3
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v4, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v7, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0x7f
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v4, v3, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v3, v1
+; CHECK-NEXT:    v_sub_u32_e32 v7, 15, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v3
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v8, v1, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0x7ffff, v3
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v9, v3, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v7, v9, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 19, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v7
+; CHECK-NEXT:    v_add_u32_e32 v3, v9, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 6, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 3, v6
+; CHECK-NEXT:    v_or3_b32 v3, v8, v7, v3
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v8, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v1, v1
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v4, v3, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v3, v2
+; CHECK-NEXT:    v_sub_u32_e32 v7, 15, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v3
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v8, v2, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0x7ffff, v3
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v9, v3, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v7, v9, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 19, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v7
+; CHECK-NEXT:    v_add_u32_e32 v3, v9, v3
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 6, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 3, v6
+; CHECK-NEXT:    v_or3_b32 v3, v8, v7, v3
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v8, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v2, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v4, v3, vcc
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <3 x i8> @llvm.convert.to.arbitrary.fp.v3i8.v3f32(<3 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <3 x i8> %r
+}
+
+; <4 x float> -> <4 x i8> Float8E4M3FN
+define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v4f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v1
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v1
+; CHECK-NEXT:    v_sub_u32_e32 v7, 15, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v5
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v8, v1, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0x7ffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v9, v4, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v7, v9, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 19, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v7
+; CHECK-NEXT:    v_add_u32_e32 v4, v9, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 6, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 3, v6
+; CHECK-NEXT:    v_or3_b32 v4, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v8, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v5, 0x7f
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v1, v1
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v5, v4, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v0
+; CHECK-NEXT:    v_sub_u32_e32 v8, 15, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v9, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x7ffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v10, v4, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v8, v10, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 19, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v8
+; CHECK-NEXT:    v_add_u32_e32 v4, v10, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 6, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 3, v7
+; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v9, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v5, v4, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v3
+; CHECK-NEXT:    v_sub_u32_e32 v8, 15, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v9, v3, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x7ffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v10, v4, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v8, v10, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 19, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v8
+; CHECK-NEXT:    v_add_u32_e32 v4, v10, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 6, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 3, v7
+; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v9, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v3, v3
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v5, v4, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v2
+; CHECK-NEXT:    v_sub_u32_e32 v8, 15, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v9, v2, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_and_b32_e32 v8, 0x7ffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v10, v4, 20, 3
+; CHECK-NEXT:    v_and_or_b32 v8, v10, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 19, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v8
+; CHECK-NEXT:    v_add_u32_e32 v4, v10, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 7, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 6, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 3, v7
+; CHECK-NEXT:    v_or3_b32 v4, v9, v8, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v6, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v4, v4, v9, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v2, v2
+; CHECK-NEXT:    v_lshlrev_b16_e32 v3, 8, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v5, v4, vcc
+; CHECK-NEXT:    v_or_b32_sdwa v2, v2, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_lshlrev_b16_e32 v1, 8, v1
+; CHECK-NEXT:    v_lshlrev_b32_e32 v3, 16, v2
+; CHECK-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_or_b32_e32 v1, v1, v3
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 24, v3
+; CHECK-NEXT:    v_lshrrev_b32_e32 v1, 8, v1
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <4 x i8> %r
+}
+
+; <4 x float> -> <4 x i8> Float8E5M2
+define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f8e5m2_v4f32:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v6, v1
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v4, v1
+; CHECK-NEXT:    v_sub_u32_e32 v7, 8, v6
+; CHECK-NEXT:    v_and_b32_e32 v5, 0x7fffff, v4
+; CHECK-NEXT:    v_min_u32_e32 v7, 31, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x800000, v5
+; CHECK-NEXT:    v_sub_u32_e64 v9, v7, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 0, v9
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, v7, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v10, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v10, v8, 1, v10
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, v9, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u32_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    s_movk_i32 s6, 0x80
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v8, v1, s6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v5, v8, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 0xfffff, v4
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v9, v4, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v7, v9, 1, v7
+; CHECK-NEXT:    v_lshrrev_b32_e32 v4, 20, v4
+; CHECK-NEXT:    v_and_b32_e32 v4, v4, v7
+; CHECK-NEXT:    v_add_u32_e32 v4, v9, v4
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, v4, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v6, vcc, 14, v6, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v7, 2, v6
+; CHECK-NEXT:    v_or3_b32 v7, v8, v7, v4
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v7, v5, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v4
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v6
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v6
+; CHECK-NEXT:    v_or_b32_e32 v4, 0x7c, v8
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v5, v4, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v1
+; CHECK-NEXT:    s_movk_i32 s7, 0x204
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v5, v8, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v1, s7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v5, v4, vcc
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0x7e
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v1, v1
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v4, v5, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v5, v0
+; CHECK-NEXT:    v_sub_u32_e32 v8, 8, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v5
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v9, v0, s6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_and_b32_e32 v8, 0xfffff, v5
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v8, v10, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, 20, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v8
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 14, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 2, v7
+; CHECK-NEXT:    v_or3_b32 v8, v9, v8, v5
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v8, v6, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v7
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x7c, v9
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v6, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v6, v9, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v0, s7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v6, v5, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v0, v4, v5, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v5, v3
+; CHECK-NEXT:    v_sub_u32_e32 v8, 8, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v5
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v9, v3, s6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_and_b32_e32 v8, 0xfffff, v5
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v8, v10, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, 20, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v8
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 14, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 2, v7
+; CHECK-NEXT:    v_or3_b32 v8, v9, v8, v5
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v8, v6, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v7
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x7c, v9
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v6, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v6, v9, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v3, s7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v6, v5, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v3, v3
+; CHECK-NEXT:    v_frexp_exp_i32_f32_e32 v7, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v4, v5, vcc
+; CHECK-NEXT:    v_frexp_mant_f32_e32 v5, v2
+; CHECK-NEXT:    v_sub_u32_e32 v8, 8, v7
+; CHECK-NEXT:    v_and_b32_e32 v6, 0x7fffff, v5
+; CHECK-NEXT:    v_min_u32_e32 v8, 31, v8
+; CHECK-NEXT:    v_or_b32_e32 v6, 0x800000, v6
+; CHECK-NEXT:    v_sub_u32_e64 v10, v8, 1 clamp
+; CHECK-NEXT:    v_bfe_u32 v11, v6, 0, v10
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v9, v8, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_and_or_b32 v11, v9, 1, v11
+; CHECK-NEXT:    v_lshrrev_b32_e32 v6, v10, v6
+; CHECK-NEXT:    v_and_b32_e32 v6, v6, v11
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
+; CHECK-NEXT:    v_add_u32_e32 v6, v9, v6
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v6, v6, 0, vcc
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 4, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v9, v2, s6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
+; CHECK-NEXT:    v_or3_b32 v6, v9, v8, v6
+; CHECK-NEXT:    v_and_b32_e32 v8, 0xfffff, v5
+; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, 0, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v8, 0, 1, vcc
+; CHECK-NEXT:    v_bfe_u32 v10, v5, 21, 2
+; CHECK-NEXT:    v_and_or_b32 v8, v10, 1, v8
+; CHECK-NEXT:    v_lshrrev_b32_e32 v5, 20, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v8
+; CHECK-NEXT:    v_add_u32_e32 v5, v10, v5
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_addc_co_u32_e32 v7, vcc, 14, v7, vcc
+; CHECK-NEXT:    v_lshlrev_b32_e32 v8, 2, v7
+; CHECK-NEXT:    v_or3_b32 v8, v9, v8, v5
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v8, v6, vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 3, v5
+; CHECK-NEXT:    v_cmp_eq_u32_e64 s[4:5], 30, v7
+; CHECK-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc, 30, v7
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x7c, v9
+; CHECK-NEXT:    s_or_b64 vcc, vcc, s[4:5]
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v6, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f32_e32 vcc, 0, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v6, v6, v9, vcc
+; CHECK-NEXT:    v_cmp_class_f32_e64 vcc, v2, s7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, v6, v5, vcc
+; CHECK-NEXT:    v_cmp_o_f32_e32 vcc, v2, v2
+; CHECK-NEXT:    v_lshlrev_b16_e32 v3, 8, v3
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v4, v5, vcc
+; CHECK-NEXT:    v_or_b32_sdwa v2, v2, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_lshlrev_b16_e32 v1, 8, v1
+; CHECK-NEXT:    v_lshlrev_b32_e32 v3, 16, v2
+; CHECK-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_or_b32_e32 v1, v1, v3
+; CHECK-NEXT:    v_lshrrev_b32_e32 v3, 24, v3
+; CHECK-NEXT:    v_lshrrev_b32_e32 v1, 8, v1
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float> %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret <4 x i8> %r
+}
+
+; <2 x half> -> <2 x i8> Float8E4M3FN
+define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v2f16:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_frexp_exp_i16_f16_e32 v4, v0
+; CHECK-NEXT:    v_sub_u16_e32 v5, 2, v4
+; CHECK-NEXT:    v_min_u16_e32 v5, 15, v5
+; CHECK-NEXT:    v_frexp_mant_f16_e32 v1, v0
+; CHECK-NEXT:    v_sub_u16_e64 v8, v5, 1 clamp
+; CHECK-NEXT:    v_and_b32_e32 v2, 0x3ff, v1
+; CHECK-NEXT:    v_lshlrev_b16_e64 v9, v8, 1
+; CHECK-NEXT:    v_or_b32_e32 v3, 0x400, v2
+; CHECK-NEXT:    v_add_u16_e32 v9, -1, v9
+; CHECK-NEXT:    v_and_b32_e32 v9, v3, v9
+; CHECK-NEXT:    v_lshrrev_b16_e32 v6, v5, v3
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v9
+; CHECK-NEXT:    v_and_b32_e32 v7, 1, v6
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v7, v9, v7
+; CHECK-NEXT:    v_lshrrev_b16_e32 v3, v8, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v7
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v5
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
+; CHECK-NEXT:    v_add_u16_e32 v3, v6, v3
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 7, v3
+; CHECK-NEXT:    s_movk_i32 s4, 0x80
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, 0, 8, vcc
+; CHECK-NEXT:    v_and_b32_sdwa v6, v0, s4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD
+; CHECK-NEXT:    v_and_b32_e32 v7, 63, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v6, v5
+; CHECK-NEXT:    v_lshrrev_b16_e32 v2, 7, v2
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v7
+; CHECK-NEXT:    v_or_b32_e32 v3, v5, v3
+; CHECK-NEXT:    v_and_b32_e32 v5, 1, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v5, v7, v5
+; CHECK-NEXT:    v_lshrrev_b16_e32 v1, 6, v1
+; CHECK-NEXT:    v_and_b32_e32 v1, v1, v5
+; CHECK-NEXT:    v_add_u16_e32 v1, v2, v1
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 7, v1
+; CHECK-NEXT:    v_cndmask_b32_e64 v2, 0, 1, vcc
+; CHECK-NEXT:    v_add_u16_e32 v2, v4, v2
+; CHECK-NEXT:    v_add_u16_e32 v2, 6, v2
+; CHECK-NEXT:    v_lshlrev_b16_e32 v4, 3, v2
+; CHECK-NEXT:    v_cndmask_b32_e64 v1, v1, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v4, v6, v4
+; CHECK-NEXT:    v_or_b32_e32 v1, v4, v1
+; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, 1, v2
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v3, vcc
+; CHECK-NEXT:    v_cmp_eq_f16_e32 vcc, 0, v0
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v1, v6, vcc
+; CHECK-NEXT:    v_frexp_exp_i16_f16_sdwa v6, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; CHECK-NEXT:    v_sub_u16_e32 v7, 2, v6
+; CHECK-NEXT:    v_min_u16_e32 v7, 15, v7
+; CHECK-NEXT:    v_frexp_mant_f16_sdwa v3, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; CHECK-NEXT:    v_sub_u16_e64 v10, v7, 1 clamp
+; CHECK-NEXT:    v_and_b32_e32 v4, 0x3ff, v3
+; CHECK-NEXT:    v_lshlrev_b16_e64 v11, v10, 1
+; CHECK-NEXT:    v_or_b32_e32 v5, 0x400, v4
+; CHECK-NEXT:    v_add_u16_e32 v11, -1, v11
+; CHECK-NEXT:    v_mov_b32_e32 v2, 0x7f
+; CHECK-NEXT:    v_cmp_o_f16_e32 vcc, v0, v0
+; CHECK-NEXT:    v_and_b32_e32 v11, v5, v11
+; CHECK-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
+; CHECK-NEXT:    v_lshrrev_b16_e32 v8, v7, v5
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v11
+; CHECK-NEXT:    v_and_b32_e32 v9, 1, v8
+; CHECK-NEXT:    v_cndmask_b32_e64 v11, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v9, v11, v9
+; CHECK-NEXT:    v_lshrrev_b16_e32 v5, v10, v5
+; CHECK-NEXT:    v_and_b32_e32 v5, v5, v9
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v7
+; CHECK-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
+; CHECK-NEXT:    v_add_u16_e32 v5, v8, v5
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 7, v5
+; CHECK-NEXT:    v_lshrrev_b32_e32 v8, 31, v0
+; CHECK-NEXT:    v_cndmask_b32_e64 v7, 0, 8, vcc
+; CHECK-NEXT:    v_lshlrev_b16_e32 v8, 7, v8
+; CHECK-NEXT:    v_and_b32_e32 v9, 63, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v5, v5, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v7, v8, v7
+; CHECK-NEXT:    v_lshrrev_b16_e32 v4, 7, v4
+; CHECK-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v9
+; CHECK-NEXT:    v_or_b32_e32 v5, v7, v5
+; CHECK-NEXT:    v_and_b32_e32 v7, 1, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v9, 0, 1, vcc
+; CHECK-NEXT:    v_or_b32_e32 v7, v9, v7
+; CHECK-NEXT:    v_lshrrev_b16_e32 v3, 6, v3
+; CHECK-NEXT:    v_and_b32_e32 v3, v3, v7
+; CHECK-NEXT:    v_add_u16_e32 v3, v4, v3
+; CHECK-NEXT:    v_cmp_lt_i16_e32 vcc, 7, v3
+; CHECK-NEXT:    v_cndmask_b32_e64 v4, 0, 1, vcc
+; CHECK-NEXT:    v_add_u16_e32 v4, v6, v4
+; CHECK-NEXT:    v_add_u16_e32 v4, 6, v4
+; CHECK-NEXT:    v_lshlrev_b16_e32 v6, 3, v4
+; CHECK-NEXT:    v_cndmask_b32_e64 v3, v3, 0, vcc
+; CHECK-NEXT:    v_or_b32_e32 v6, v8, v6
+; CHECK-NEXT:    v_or_b32_e32 v3, v6, v3
+; CHECK-NEXT:    v_cmp_gt_i16_e32 vcc, 1, v4
+; CHECK-NEXT:    v_mov_b32_e32 v4, 0
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v5, vcc
+; CHECK-NEXT:    v_cmp_eq_f16_sdwa vcc, v0, v4 src0_sel:WORD_1 src1_sel:DWORD
+; CHECK-NEXT:    v_cndmask_b32_e32 v3, v3, v8, vcc
+; CHECK-NEXT:    v_cmp_o_f16_sdwa vcc, v0, v0 src0_sel:WORD_1 src1_sel:WORD_1
+; CHECK-NEXT:    v_cndmask_b32_e32 v2, v2, v3, vcc
+; CHECK-NEXT:    v_lshlrev_b16_e32 v0, 8, v2
+; CHECK-NEXT:    v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
+; CHECK-NEXT:    v_and_b32_e32 v1, 0xff, v2
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f16(<2 x half> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
 ; Float8E5M2 from f16: half -> i8
 define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f16:
diff --git a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
index d4c80c2d1a2b4..16ac8c8634db5 100644
--- a/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/NVPTX/float-to-arbitrary-fp.ll
@@ -7,6 +7,10 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
 declare i6 @llvm.convert.to.arbitrary.fp.i6.f32(float, metadata, metadata, i1)
 declare i4 @llvm.convert.to.arbitrary.fp.i4.f32(float, metadata, metadata, i1)
 declare <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float>, metadata, metadata, i1)
+declare <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float>, metadata, metadata, i1)
+declare <3 x i8> @llvm.convert.to.arbitrary.fp.v3i8.v3f32(<3 x float>, metadata, metadata, i1)
+declare <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float>, metadata, metadata, i1)
+declare <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f16(<2 x half>, metadata, metadata, i1)
 
 declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1)
 declare i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat, metadata, metadata, i1)
@@ -175,7 +179,7 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
   ret i8 %r
 }
 
-; Vector test: f32 <4 x float> -> <4 x i4> Float4E2M1FN
+; <4 x float> -> <4 x i4> Float4E2M1FN
 define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-LABEL: to_f4e2m1fn_v4f32(
 ; CHECK:       {
@@ -440,6 +444,1302 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
   ret <4 x i4> %r
 }
 
+; <2 x float> -> <2 x i8> Float8E5M2
+define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
+; CHECK-LABEL: to_f8e5m2_v2f32(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<29>;
+; CHECK-NEXT:    .reg .b16 %rs<3>;
+; CHECK-NEXT:    .reg .b32 %r<126>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.v2.b32 {%r1, %r2}, [to_f8e5m2_v2f32_param_0];
+; CHECK-NEXT:    mul.rn.f32 %r3, %r2, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r4, %r2, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r4, 8388608;
+; CHECK-NEXT:    selp.b32 %r5, %r3, %r2, %p1;
+; CHECK-NEXT:    and.b32 %r6, %r5, -2139095041;
+; CHECK-NEXT:    or.b32 %r7, %r6, 1056964608;
+; CHECK-NEXT:    add.s32 %r8, %r4, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r8, -2139095039;
+; CHECK-NEXT:    selp.f32 %r9, %r2, %r7, %p2;
+; CHECK-NEXT:    and.b32 %r10, %r9, 8388607;
+; CHECK-NEXT:    or.b32 %r11, %r10, 8388608;
+; CHECK-NEXT:    and.b32 %r12, %r3, 2139095040;
+; CHECK-NEXT:    selp.b32 %r13, %r12, %r4, %p1;
+; CHECK-NEXT:    shr.u32 %r14, %r13, 23;
+; CHECK-NEXT:    selp.b32 %r15, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r16, %r14, %r15;
+; CHECK-NEXT:    add.s32 %r17, %r16, -126;
+; CHECK-NEXT:    selp.b32 %r18, 0, %r17, %p2;
+; CHECK-NEXT:    sub.s32 %r19, 8, %r18;
+; CHECK-NEXT:    min.u32 %r20, %r19, 31;
+; CHECK-NEXT:    shr.u32 %r21, %r11, %r20;
+; CHECK-NEXT:    and.b32 %r22, %r21, 1;
+; CHECK-NEXT:    max.u32 %r23, %r20, 1;
+; CHECK-NEXT:    add.s32 %r24, %r23, -1;
+; CHECK-NEXT:    mov.b32 %r25, 1;
+; CHECK-NEXT:    shl.b32 %r26, %r25, %r24;
+; CHECK-NEXT:    add.s32 %r27, %r26, -1;
+; CHECK-NEXT:    and.b32 %r28, %r11, %r27;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r28, 0;
+; CHECK-NEXT:    selp.b32 %r29, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r30, %r29, %r22;
+; CHECK-NEXT:    shr.u32 %r31, %r11, %r24;
+; CHECK-NEXT:    and.b32 %r32, %r31, %r30;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r20, 0;
+; CHECK-NEXT:    selp.b32 %r33, %r32, 0, %p4;
+; CHECK-NEXT:    add.s32 %r34, %r21, %r33;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r34, 3;
+; CHECK-NEXT:    selp.b32 %r35, 0, %r34, %p5;
+; CHECK-NEXT:    selp.b32 %r36, 4, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r37, %r2, 24;
+; CHECK-NEXT:    and.b32 %r38, %r37, 128;
+; CHECK-NEXT:    or.b32 %r39, %r38, %r36;
+; CHECK-NEXT:    or.b32 %r40, %r39, %r35;
+; CHECK-NEXT:    bfe.u32 %r41, %r10, 21, 1;
+; CHECK-NEXT:    and.b32 %r42, %r9, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r42, 0;
+; CHECK-NEXT:    selp.b32 %r43, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r44, %r43, %r41;
+; CHECK-NEXT:    shr.u32 %r45, %r9, 20;
+; CHECK-NEXT:    and.b32 %r46, %r45, %r44;
+; CHECK-NEXT:    bfe.u32 %r47, %r9, 21, 2;
+; CHECK-NEXT:    add.s32 %r48, %r47, %r46;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r48, 3;
+; CHECK-NEXT:    selp.b32 %r49, 0, %r48, %p7;
+; CHECK-NEXT:    selp.b32 %r50, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r51, %r18, %r50;
+; CHECK-NEXT:    add.s32 %r52, %r51, 14;
+; CHECK-NEXT:    shl.b32 %r53, %r52, 2;
+; CHECK-NEXT:    or.b32 %r54, %r38, %r53;
+; CHECK-NEXT:    or.b32 %r55, %r54, %r49;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r52, 1;
+; CHECK-NEXT:    selp.b32 %r56, %r40, %r55, %p8;
+; CHECK-NEXT:    setp.gt.s32 %p9, %r49, 3;
+; CHECK-NEXT:    or.b32 %r57, %r38, 124;
+; CHECK-NEXT:    selp.b32 %r58, %r57, %r56, %p9;
+; CHECK-NEXT:    setp.eq.b32 %p10, %r52, 30;
+; CHECK-NEXT:    selp.b32 %r59, %r58, %r56, %p10;
+; CHECK-NEXT:    setp.gt.s32 %p11, %r52, 30;
+; CHECK-NEXT:    selp.b32 %r60, %r57, %r59, %p11;
+; CHECK-NEXT:    setp.eq.f32 %p12, %r2, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r61, %r38, %r60, %p12;
+; CHECK-NEXT:    abs.f32 %r62, %r2;
+; CHECK-NEXT:    setp.eq.f32 %p13, %r62, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r63, %r57, %r61, %p13;
+; CHECK-NEXT:    setp.nan.f32 %p14, %r2, %r2;
+; CHECK-NEXT:    selp.b32 %r64, 126, %r63, %p14;
+; CHECK-NEXT:    cvt.u16.u32 %rs1, %r64;
+; CHECK-NEXT:    mul.rn.f32 %r65, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r66, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p15, %r66, 8388608;
+; CHECK-NEXT:    selp.b32 %r67, %r65, %r1, %p15;
+; CHECK-NEXT:    and.b32 %r68, %r67, -2139095041;
+; CHECK-NEXT:    or.b32 %r69, %r68, 1056964608;
+; CHECK-NEXT:    add.s32 %r70, %r66, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p16, %r70, -2139095039;
+; CHECK-NEXT:    selp.f32 %r71, %r1, %r69, %p16;
+; CHECK-NEXT:    and.b32 %r72, %r71, 8388607;
+; CHECK-NEXT:    or.b32 %r73, %r72, 8388608;
+; CHECK-NEXT:    and.b32 %r74, %r65, 2139095040;
+; CHECK-NEXT:    selp.b32 %r75, %r74, %r66, %p15;
+; CHECK-NEXT:    shr.u32 %r76, %r75, 23;
+; CHECK-NEXT:    selp.b32 %r77, -25, 0, %p15;
+; CHECK-NEXT:    add.s32 %r78, %r76, %r77;
+; CHECK-NEXT:    add.s32 %r79, %r78, -126;
+; CHECK-NEXT:    selp.b32 %r80, 0, %r79, %p16;
+; CHECK-NEXT:    sub.s32 %r81, 8, %r80;
+; CHECK-NEXT:    min.u32 %r82, %r81, 31;
+; CHECK-NEXT:    shr.u32 %r83, %r73, %r82;
+; CHECK-NEXT:    and.b32 %r84, %r83, 1;
+; CHECK-NEXT:    max.u32 %r85, %r82, 1;
+; CHECK-NEXT:    add.s32 %r86, %r85, -1;
+; CHECK-NEXT:    shl.b32 %r87, %r25, %r86;
+; CHECK-NEXT:    add.s32 %r88, %r87, -1;
+; CHECK-NEXT:    and.b32 %r89, %r73, %r88;
+; CHECK-NEXT:    setp.ne.b32 %p17, %r89, 0;
+; CHECK-NEXT:    selp.b32 %r90, 1, 0, %p17;
+; CHECK-NEXT:    or.b32 %r91, %r90, %r84;
+; CHECK-NEXT:    shr.u32 %r92, %r73, %r86;
+; CHECK-NEXT:    and.b32 %r93, %r92, %r91;
+; CHECK-NEXT:    setp.ne.b32 %p18, %r82, 0;
+; CHECK-NEXT:    selp.b32 %r94, %r93, 0, %p18;
+; CHECK-NEXT:    add.s32 %r95, %r83, %r94;
+; CHECK-NEXT:    setp.gt.s32 %p19, %r95, 3;
+; CHECK-NEXT:    selp.b32 %r96, 0, %r95, %p19;
+; CHECK-NEXT:    selp.b32 %r97, 4, 0, %p19;
+; CHECK-NEXT:    shr.u32 %r98, %r1, 24;
+; CHECK-NEXT:    and.b32 %r99, %r98, 128;
+; CHECK-NEXT:    or.b32 %r100, %r99, %r97;
+; CHECK-NEXT:    or.b32 %r101, %r100, %r96;
+; CHECK-NEXT:    bfe.u32 %r102, %r72, 21, 1;
+; CHECK-NEXT:    and.b32 %r103, %r71, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p20, %r103, 0;
+; CHECK-NEXT:    selp.b32 %r104, 1, 0, %p20;
+; CHECK-NEXT:    or.b32 %r105, %r104, %r102;
+; CHECK-NEXT:    shr.u32 %r106, %r71, 20;
+; CHECK-NEXT:    and.b32 %r107, %r106, %r105;
+; CHECK-NEXT:    bfe.u32 %r108, %r71, 21, 2;
+; CHECK-NEXT:    add.s32 %r109, %r108, %r107;
+; CHECK-NEXT:    setp.gt.s32 %p21, %r109, 3;
+; CHECK-NEXT:    selp.b32 %r110, 0, %r109, %p21;
+; CHECK-NEXT:    selp.b32 %r111, 1, 0, %p21;
+; CHECK-NEXT:    add.s32 %r112, %r80, %r111;
+; CHECK-NEXT:    add.s32 %r113, %r112, 14;
+; CHECK-NEXT:    shl.b32 %r114, %r113, 2;
+; CHECK-NEXT:    or.b32 %r115, %r99, %r114;
+; CHECK-NEXT:    or.b32 %r116, %r115, %r110;
+; CHECK-NEXT:    setp.lt.s32 %p22, %r113, 1;
+; CHECK-NEXT:    selp.b32 %r117, %r101, %r116, %p22;
+; CHECK-NEXT:    setp.gt.s32 %p23, %r110, 3;
+; CHECK-NEXT:    or.b32 %r118, %r99, 124;
+; CHECK-NEXT:    selp.b32 %r119, %r118, %r117, %p23;
+; CHECK-NEXT:    setp.eq.b32 %p24, %r113, 30;
+; CHECK-NEXT:    selp.b32 %r120, %r119, %r117, %p24;
+; CHECK-NEXT:    setp.gt.s32 %p25, %r113, 30;
+; CHECK-NEXT:    selp.b32 %r121, %r118, %r120, %p25;
+; CHECK-NEXT:    setp.eq.f32 %p26, %r1, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r122, %r99, %r121, %p26;
+; CHECK-NEXT:    abs.f32 %r123, %r1;
+; CHECK-NEXT:    setp.eq.f32 %p27, %r123, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r124, %r118, %r122, %p27;
+; CHECK-NEXT:    setp.nan.f32 %p28, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r125, 126, %r124, %p28;
+; CHECK-NEXT:    cvt.u16.u32 %rs2, %r125;
+; CHECK-NEXT:    st.param.v2.b8 [func_retval0], {%rs2, %rs1};
+; CHECK-NEXT:    ret;
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float> %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
+; <2 x float> -> <2 x i8> Float8E4M3FN
+define <2 x i8> @to_f8e4m3fn_v2f32(<2 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v2f32(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<21>;
+; CHECK-NEXT:    .reg .b16 %rs<3>;
+; CHECK-NEXT:    .reg .b32 %r<114>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.v2.b32 {%r1, %r2}, [to_f8e4m3fn_v2f32_param_0];
+; CHECK-NEXT:    mul.rn.f32 %r3, %r2, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r4, %r2, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r4, 8388608;
+; CHECK-NEXT:    selp.b32 %r5, %r3, %r2, %p1;
+; CHECK-NEXT:    and.b32 %r6, %r5, -2139095041;
+; CHECK-NEXT:    or.b32 %r7, %r6, 1056964608;
+; CHECK-NEXT:    add.s32 %r8, %r4, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r8, -2139095039;
+; CHECK-NEXT:    selp.f32 %r9, %r2, %r7, %p2;
+; CHECK-NEXT:    and.b32 %r10, %r9, 8388607;
+; CHECK-NEXT:    or.b32 %r11, %r10, 8388608;
+; CHECK-NEXT:    and.b32 %r12, %r3, 2139095040;
+; CHECK-NEXT:    selp.b32 %r13, %r12, %r4, %p1;
+; CHECK-NEXT:    shr.u32 %r14, %r13, 23;
+; CHECK-NEXT:    selp.b32 %r15, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r16, %r14, %r15;
+; CHECK-NEXT:    add.s32 %r17, %r16, -126;
+; CHECK-NEXT:    selp.b32 %r18, 0, %r17, %p2;
+; CHECK-NEXT:    sub.s32 %r19, 15, %r18;
+; CHECK-NEXT:    min.u32 %r20, %r19, 31;
+; CHECK-NEXT:    shr.u32 %r21, %r11, %r20;
+; CHECK-NEXT:    and.b32 %r22, %r21, 1;
+; CHECK-NEXT:    max.u32 %r23, %r20, 1;
+; CHECK-NEXT:    add.s32 %r24, %r23, -1;
+; CHECK-NEXT:    mov.b32 %r25, 1;
+; CHECK-NEXT:    shl.b32 %r26, %r25, %r24;
+; CHECK-NEXT:    add.s32 %r27, %r26, -1;
+; CHECK-NEXT:    and.b32 %r28, %r11, %r27;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r28, 0;
+; CHECK-NEXT:    selp.b32 %r29, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r30, %r29, %r22;
+; CHECK-NEXT:    shr.u32 %r31, %r11, %r24;
+; CHECK-NEXT:    and.b32 %r32, %r31, %r30;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r20, 0;
+; CHECK-NEXT:    selp.b32 %r33, %r32, 0, %p4;
+; CHECK-NEXT:    add.s32 %r34, %r21, %r33;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r34, 7;
+; CHECK-NEXT:    selp.b32 %r35, 0, %r34, %p5;
+; CHECK-NEXT:    selp.b32 %r36, 8, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r37, %r2, 24;
+; CHECK-NEXT:    and.b32 %r38, %r37, 128;
+; CHECK-NEXT:    or.b32 %r39, %r38, %r36;
+; CHECK-NEXT:    or.b32 %r40, %r39, %r35;
+; CHECK-NEXT:    bfe.u32 %r41, %r10, 20, 1;
+; CHECK-NEXT:    and.b32 %r42, %r9, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r42, 0;
+; CHECK-NEXT:    selp.b32 %r43, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r44, %r43, %r41;
+; CHECK-NEXT:    shr.u32 %r45, %r9, 19;
+; CHECK-NEXT:    and.b32 %r46, %r45, %r44;
+; CHECK-NEXT:    bfe.u32 %r47, %r9, 20, 3;
+; CHECK-NEXT:    add.s32 %r48, %r47, %r46;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r48, 7;
+; CHECK-NEXT:    selp.b32 %r49, 0, %r48, %p7;
+; CHECK-NEXT:    selp.b32 %r50, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r51, %r18, %r50;
+; CHECK-NEXT:    add.s32 %r52, %r51, 6;
+; CHECK-NEXT:    shl.b32 %r53, %r52, 3;
+; CHECK-NEXT:    or.b32 %r54, %r38, %r53;
+; CHECK-NEXT:    or.b32 %r55, %r54, %r49;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r52, 1;
+; CHECK-NEXT:    selp.b32 %r56, %r40, %r55, %p8;
+; CHECK-NEXT:    setp.eq.f32 %p9, %r2, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r57, %r38, %r56, %p9;
+; CHECK-NEXT:    setp.nan.f32 %p10, %r2, %r2;
+; CHECK-NEXT:    selp.b32 %r58, 127, %r57, %p10;
+; CHECK-NEXT:    cvt.u16.u32 %rs1, %r58;
+; CHECK-NEXT:    mul.rn.f32 %r59, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r60, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p11, %r60, 8388608;
+; CHECK-NEXT:    selp.b32 %r61, %r59, %r1, %p11;
+; CHECK-NEXT:    and.b32 %r62, %r61, -2139095041;
+; CHECK-NEXT:    or.b32 %r63, %r62, 1056964608;
+; CHECK-NEXT:    add.s32 %r64, %r60, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p12, %r64, -2139095039;
+; CHECK-NEXT:    selp.f32 %r65, %r1, %r63, %p12;
+; CHECK-NEXT:    and.b32 %r66, %r65, 8388607;
+; CHECK-NEXT:    or.b32 %r67, %r66, 8388608;
+; CHECK-NEXT:    and.b32 %r68, %r59, 2139095040;
+; CHECK-NEXT:    selp.b32 %r69, %r68, %r60, %p11;
+; CHECK-NEXT:    shr.u32 %r70, %r69, 23;
+; CHECK-NEXT:    selp.b32 %r71, -25, 0, %p11;
+; CHECK-NEXT:    add.s32 %r72, %r70, %r71;
+; CHECK-NEXT:    add.s32 %r73, %r72, -126;
+; CHECK-NEXT:    selp.b32 %r74, 0, %r73, %p12;
+; CHECK-NEXT:    sub.s32 %r75, 15, %r74;
+; CHECK-NEXT:    min.u32 %r76, %r75, 31;
+; CHECK-NEXT:    shr.u32 %r77, %r67, %r76;
+; CHECK-NEXT:    and.b32 %r78, %r77, 1;
+; CHECK-NEXT:    max.u32 %r79, %r76, 1;
+; CHECK-NEXT:    add.s32 %r80, %r79, -1;
+; CHECK-NEXT:    shl.b32 %r81, %r25, %r80;
+; CHECK-NEXT:    add.s32 %r82, %r81, -1;
+; CHECK-NEXT:    and.b32 %r83, %r67, %r82;
+; CHECK-NEXT:    setp.ne.b32 %p13, %r83, 0;
+; CHECK-NEXT:    selp.b32 %r84, 1, 0, %p13;
+; CHECK-NEXT:    or.b32 %r85, %r84, %r78;
+; CHECK-NEXT:    shr.u32 %r86, %r67, %r80;
+; CHECK-NEXT:    and.b32 %r87, %r86, %r85;
+; CHECK-NEXT:    setp.ne.b32 %p14, %r76, 0;
+; CHECK-NEXT:    selp.b32 %r88, %r87, 0, %p14;
+; CHECK-NEXT:    add.s32 %r89, %r77, %r88;
+; CHECK-NEXT:    setp.gt.s32 %p15, %r89, 7;
+; CHECK-NEXT:    selp.b32 %r90, 0, %r89, %p15;
+; CHECK-NEXT:    selp.b32 %r91, 8, 0, %p15;
+; CHECK-NEXT:    shr.u32 %r92, %r1, 24;
+; CHECK-NEXT:    and.b32 %r93, %r92, 128;
+; CHECK-NEXT:    or.b32 %r94, %r93, %r91;
+; CHECK-NEXT:    or.b32 %r95, %r94, %r90;
+; CHECK-NEXT:    bfe.u32 %r96, %r66, 20, 1;
+; CHECK-NEXT:    and.b32 %r97, %r65, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p16, %r97, 0;
+; CHECK-NEXT:    selp.b32 %r98, 1, 0, %p16;
+; CHECK-NEXT:    or.b32 %r99, %r98, %r96;
+; CHECK-NEXT:    shr.u32 %r100, %r65, 19;
+; CHECK-NEXT:    and.b32 %r101, %r100, %r99;
+; CHECK-NEXT:    bfe.u32 %r102, %r65, 20, 3;
+; CHECK-NEXT:    add.s32 %r103, %r102, %r101;
+; CHECK-NEXT:    setp.gt.s32 %p17, %r103, 7;
+; CHECK-NEXT:    selp.b32 %r104, 0, %r103, %p17;
+; CHECK-NEXT:    selp.b32 %r105, 1, 0, %p17;
+; CHECK-NEXT:    add.s32 %r106, %r74, %r105;
+; CHECK-NEXT:    add.s32 %r107, %r106, 6;
+; CHECK-NEXT:    shl.b32 %r108, %r107, 3;
+; CHECK-NEXT:    or.b32 %r109, %r93, %r108;
+; CHECK-NEXT:    or.b32 %r110, %r109, %r104;
+; CHECK-NEXT:    setp.lt.s32 %p18, %r107, 1;
+; CHECK-NEXT:    selp.b32 %r111, %r95, %r110, %p18;
+; CHECK-NEXT:    setp.eq.f32 %p19, %r1, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r112, %r93, %r111, %p19;
+; CHECK-NEXT:    setp.nan.f32 %p20, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r113, 127, %r112, %p20;
+; CHECK-NEXT:    cvt.u16.u32 %rs2, %r113;
+; CHECK-NEXT:    st.param.v2.b8 [func_retval0], {%rs2, %rs1};
+; CHECK-NEXT:    ret;
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
+; <3 x float> -> <3 x i8> Float8E4M3FN
+define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v3f32(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<31>;
+; CHECK-NEXT:    .reg .b32 %r<174>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.v2.b32 {%r1, %r2}, [to_f8e4m3fn_v3f32_param_0];
+; CHECK-NEXT:    ld.param.b32 %r3, [to_f8e4m3fn_v3f32_param_0+8];
+; CHECK-NEXT:    mul.rn.f32 %r4, %r3, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r5, %r3, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r5, 8388608;
+; CHECK-NEXT:    selp.b32 %r6, %r4, %r3, %p1;
+; CHECK-NEXT:    and.b32 %r7, %r6, -2139095041;
+; CHECK-NEXT:    or.b32 %r8, %r7, 1056964608;
+; CHECK-NEXT:    add.s32 %r9, %r5, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r9, -2139095039;
+; CHECK-NEXT:    selp.f32 %r10, %r3, %r8, %p2;
+; CHECK-NEXT:    and.b32 %r11, %r10, 8388607;
+; CHECK-NEXT:    or.b32 %r12, %r11, 8388608;
+; CHECK-NEXT:    and.b32 %r13, %r4, 2139095040;
+; CHECK-NEXT:    selp.b32 %r14, %r13, %r5, %p1;
+; CHECK-NEXT:    shr.u32 %r15, %r14, 23;
+; CHECK-NEXT:    selp.b32 %r16, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r17, %r15, %r16;
+; CHECK-NEXT:    add.s32 %r18, %r17, -126;
+; CHECK-NEXT:    selp.b32 %r19, 0, %r18, %p2;
+; CHECK-NEXT:    sub.s32 %r20, 15, %r19;
+; CHECK-NEXT:    min.u32 %r21, %r20, 31;
+; CHECK-NEXT:    shr.u32 %r22, %r12, %r21;
+; CHECK-NEXT:    and.b32 %r23, %r22, 1;
+; CHECK-NEXT:    max.u32 %r24, %r21, 1;
+; CHECK-NEXT:    add.s32 %r25, %r24, -1;
+; CHECK-NEXT:    mov.b32 %r26, 1;
+; CHECK-NEXT:    shl.b32 %r27, %r26, %r25;
+; CHECK-NEXT:    add.s32 %r28, %r27, -1;
+; CHECK-NEXT:    and.b32 %r29, %r12, %r28;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r29, 0;
+; CHECK-NEXT:    selp.b32 %r30, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r31, %r30, %r23;
+; CHECK-NEXT:    shr.u32 %r32, %r12, %r25;
+; CHECK-NEXT:    and.b32 %r33, %r32, %r31;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r21, 0;
+; CHECK-NEXT:    selp.b32 %r34, %r33, 0, %p4;
+; CHECK-NEXT:    add.s32 %r35, %r22, %r34;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r35, 7;
+; CHECK-NEXT:    selp.b32 %r36, 0, %r35, %p5;
+; CHECK-NEXT:    selp.b32 %r37, 8, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r38, %r3, 24;
+; CHECK-NEXT:    and.b32 %r39, %r38, 128;
+; CHECK-NEXT:    or.b32 %r40, %r39, %r37;
+; CHECK-NEXT:    or.b32 %r41, %r40, %r36;
+; CHECK-NEXT:    bfe.u32 %r42, %r11, 20, 1;
+; CHECK-NEXT:    and.b32 %r43, %r10, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r43, 0;
+; CHECK-NEXT:    selp.b32 %r44, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r45, %r44, %r42;
+; CHECK-NEXT:    shr.u32 %r46, %r10, 19;
+; CHECK-NEXT:    and.b32 %r47, %r46, %r45;
+; CHECK-NEXT:    bfe.u32 %r48, %r10, 20, 3;
+; CHECK-NEXT:    add.s32 %r49, %r48, %r47;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r49, 7;
+; CHECK-NEXT:    selp.b32 %r50, 0, %r49, %p7;
+; CHECK-NEXT:    selp.b32 %r51, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r52, %r19, %r51;
+; CHECK-NEXT:    add.s32 %r53, %r52, 6;
+; CHECK-NEXT:    shl.b32 %r54, %r53, 3;
+; CHECK-NEXT:    or.b32 %r55, %r39, %r54;
+; CHECK-NEXT:    or.b32 %r56, %r55, %r50;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r53, 1;
+; CHECK-NEXT:    selp.b32 %r57, %r41, %r56, %p8;
+; CHECK-NEXT:    setp.eq.f32 %p9, %r3, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r58, %r39, %r57, %p9;
+; CHECK-NEXT:    setp.nan.f32 %p10, %r3, %r3;
+; CHECK-NEXT:    selp.b32 %r59, 127, %r58, %p10;
+; CHECK-NEXT:    mul.rn.f32 %r60, %r2, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r61, %r2, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p11, %r61, 8388608;
+; CHECK-NEXT:    selp.b32 %r62, %r60, %r2, %p11;
+; CHECK-NEXT:    and.b32 %r63, %r62, -2139095041;
+; CHECK-NEXT:    or.b32 %r64, %r63, 1056964608;
+; CHECK-NEXT:    add.s32 %r65, %r61, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p12, %r65, -2139095039;
+; CHECK-NEXT:    selp.f32 %r66, %r2, %r64, %p12;
+; CHECK-NEXT:    and.b32 %r67, %r66, 8388607;
+; CHECK-NEXT:    or.b32 %r68, %r67, 8388608;
+; CHECK-NEXT:    and.b32 %r69, %r60, 2139095040;
+; CHECK-NEXT:    selp.b32 %r70, %r69, %r61, %p11;
+; CHECK-NEXT:    shr.u32 %r71, %r70, 23;
+; CHECK-NEXT:    selp.b32 %r72, -25, 0, %p11;
+; CHECK-NEXT:    add.s32 %r73, %r71, %r72;
+; CHECK-NEXT:    add.s32 %r74, %r73, -126;
+; CHECK-NEXT:    selp.b32 %r75, 0, %r74, %p12;
+; CHECK-NEXT:    sub.s32 %r76, 15, %r75;
+; CHECK-NEXT:    min.u32 %r77, %r76, 31;
+; CHECK-NEXT:    shr.u32 %r78, %r68, %r77;
+; CHECK-NEXT:    and.b32 %r79, %r78, 1;
+; CHECK-NEXT:    max.u32 %r80, %r77, 1;
+; CHECK-NEXT:    add.s32 %r81, %r80, -1;
+; CHECK-NEXT:    shl.b32 %r82, %r26, %r81;
+; CHECK-NEXT:    add.s32 %r83, %r82, -1;
+; CHECK-NEXT:    and.b32 %r84, %r68, %r83;
+; CHECK-NEXT:    setp.ne.b32 %p13, %r84, 0;
+; CHECK-NEXT:    selp.b32 %r85, 1, 0, %p13;
+; CHECK-NEXT:    or.b32 %r86, %r85, %r79;
+; CHECK-NEXT:    shr.u32 %r87, %r68, %r81;
+; CHECK-NEXT:    and.b32 %r88, %r87, %r86;
+; CHECK-NEXT:    setp.ne.b32 %p14, %r77, 0;
+; CHECK-NEXT:    selp.b32 %r89, %r88, 0, %p14;
+; CHECK-NEXT:    add.s32 %r90, %r78, %r89;
+; CHECK-NEXT:    setp.gt.s32 %p15, %r90, 7;
+; CHECK-NEXT:    selp.b32 %r91, 0, %r90, %p15;
+; CHECK-NEXT:    selp.b32 %r92, 8, 0, %p15;
+; CHECK-NEXT:    shr.u32 %r93, %r2, 24;
+; CHECK-NEXT:    and.b32 %r94, %r93, 128;
+; CHECK-NEXT:    or.b32 %r95, %r94, %r92;
+; CHECK-NEXT:    or.b32 %r96, %r95, %r91;
+; CHECK-NEXT:    bfe.u32 %r97, %r67, 20, 1;
+; CHECK-NEXT:    and.b32 %r98, %r66, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p16, %r98, 0;
+; CHECK-NEXT:    selp.b32 %r99, 1, 0, %p16;
+; CHECK-NEXT:    or.b32 %r100, %r99, %r97;
+; CHECK-NEXT:    shr.u32 %r101, %r66, 19;
+; CHECK-NEXT:    and.b32 %r102, %r101, %r100;
+; CHECK-NEXT:    bfe.u32 %r103, %r66, 20, 3;
+; CHECK-NEXT:    add.s32 %r104, %r103, %r102;
+; CHECK-NEXT:    setp.gt.s32 %p17, %r104, 7;
+; CHECK-NEXT:    selp.b32 %r105, 0, %r104, %p17;
+; CHECK-NEXT:    selp.b32 %r106, 1, 0, %p17;
+; CHECK-NEXT:    add.s32 %r107, %r75, %r106;
+; CHECK-NEXT:    add.s32 %r108, %r107, 6;
+; CHECK-NEXT:    shl.b32 %r109, %r108, 3;
+; CHECK-NEXT:    or.b32 %r110, %r94, %r109;
+; CHECK-NEXT:    or.b32 %r111, %r110, %r105;
+; CHECK-NEXT:    setp.lt.s32 %p18, %r108, 1;
+; CHECK-NEXT:    selp.b32 %r112, %r96, %r111, %p18;
+; CHECK-NEXT:    setp.eq.f32 %p19, %r2, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r113, %r94, %r112, %p19;
+; CHECK-NEXT:    setp.nan.f32 %p20, %r2, %r2;
+; CHECK-NEXT:    selp.b32 %r114, 127, %r113, %p20;
+; CHECK-NEXT:    mul.rn.f32 %r115, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r116, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p21, %r116, 8388608;
+; CHECK-NEXT:    selp.b32 %r117, %r115, %r1, %p21;
+; CHECK-NEXT:    and.b32 %r118, %r117, -2139095041;
+; CHECK-NEXT:    or.b32 %r119, %r118, 1056964608;
+; CHECK-NEXT:    add.s32 %r120, %r116, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p22, %r120, -2139095039;
+; CHECK-NEXT:    selp.f32 %r121, %r1, %r119, %p22;
+; CHECK-NEXT:    and.b32 %r122, %r121, 8388607;
+; CHECK-NEXT:    or.b32 %r123, %r122, 8388608;
+; CHECK-NEXT:    and.b32 %r124, %r115, 2139095040;
+; CHECK-NEXT:    selp.b32 %r125, %r124, %r116, %p21;
+; CHECK-NEXT:    shr.u32 %r126, %r125, 23;
+; CHECK-NEXT:    selp.b32 %r127, -25, 0, %p21;
+; CHECK-NEXT:    add.s32 %r128, %r126, %r127;
+; CHECK-NEXT:    add.s32 %r129, %r128, -126;
+; CHECK-NEXT:    selp.b32 %r130, 0, %r129, %p22;
+; CHECK-NEXT:    sub.s32 %r131, 15, %r130;
+; CHECK-NEXT:    min.u32 %r132, %r131, 31;
+; CHECK-NEXT:    shr.u32 %r133, %r123, %r132;
+; CHECK-NEXT:    and.b32 %r134, %r133, 1;
+; CHECK-NEXT:    max.u32 %r135, %r132, 1;
+; CHECK-NEXT:    add.s32 %r136, %r135, -1;
+; CHECK-NEXT:    shl.b32 %r137, %r26, %r136;
+; CHECK-NEXT:    add.s32 %r138, %r137, -1;
+; CHECK-NEXT:    and.b32 %r139, %r123, %r138;
+; CHECK-NEXT:    setp.ne.b32 %p23, %r139, 0;
+; CHECK-NEXT:    selp.b32 %r140, 1, 0, %p23;
+; CHECK-NEXT:    or.b32 %r141, %r140, %r134;
+; CHECK-NEXT:    shr.u32 %r142, %r123, %r136;
+; CHECK-NEXT:    and.b32 %r143, %r142, %r141;
+; CHECK-NEXT:    setp.ne.b32 %p24, %r132, 0;
+; CHECK-NEXT:    selp.b32 %r144, %r143, 0, %p24;
+; CHECK-NEXT:    add.s32 %r145, %r133, %r144;
+; CHECK-NEXT:    setp.gt.s32 %p25, %r145, 7;
+; CHECK-NEXT:    selp.b32 %r146, 0, %r145, %p25;
+; CHECK-NEXT:    selp.b32 %r147, 8, 0, %p25;
+; CHECK-NEXT:    shr.u32 %r148, %r1, 24;
+; CHECK-NEXT:    and.b32 %r149, %r148, 128;
+; CHECK-NEXT:    or.b32 %r150, %r149, %r147;
+; CHECK-NEXT:    or.b32 %r151, %r150, %r146;
+; CHECK-NEXT:    bfe.u32 %r152, %r122, 20, 1;
+; CHECK-NEXT:    and.b32 %r153, %r121, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p26, %r153, 0;
+; CHECK-NEXT:    selp.b32 %r154, 1, 0, %p26;
+; CHECK-NEXT:    or.b32 %r155, %r154, %r152;
+; CHECK-NEXT:    shr.u32 %r156, %r121, 19;
+; CHECK-NEXT:    and.b32 %r157, %r156, %r155;
+; CHECK-NEXT:    bfe.u32 %r158, %r121, 20, 3;
+; CHECK-NEXT:    add.s32 %r159, %r158, %r157;
+; CHECK-NEXT:    setp.gt.s32 %p27, %r159, 7;
+; CHECK-NEXT:    selp.b32 %r160, 0, %r159, %p27;
+; CHECK-NEXT:    selp.b32 %r161, 1, 0, %p27;
+; CHECK-NEXT:    add.s32 %r162, %r130, %r161;
+; CHECK-NEXT:    add.s32 %r163, %r162, 6;
+; CHECK-NEXT:    shl.b32 %r164, %r163, 3;
+; CHECK-NEXT:    or.b32 %r165, %r149, %r164;
+; CHECK-NEXT:    or.b32 %r166, %r165, %r160;
+; CHECK-NEXT:    setp.lt.s32 %p28, %r163, 1;
+; CHECK-NEXT:    selp.b32 %r167, %r151, %r166, %p28;
+; CHECK-NEXT:    setp.eq.f32 %p29, %r1, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r168, %r149, %r167, %p29;
+; CHECK-NEXT:    setp.nan.f32 %p30, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r169, 127, %r168, %p30;
+; CHECK-NEXT:    prmt.b32 %r170, %r169, %r114, 0x3340U;
+; CHECK-NEXT:    prmt.b32 %r171, %r59, %r172, 0x3340U;
+; CHECK-NEXT:    prmt.b32 %r173, %r170, %r171, 0x5410U;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r173;
+; CHECK-NEXT:    ret;
+  %r = call <3 x i8> @llvm.convert.to.arbitrary.fp.v3i8.v3f32(<3 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <3 x i8> %r
+}
+
+; <4 x float> -> <4 x i8> Float8E4M3FN
+define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v4f32(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<41>;
+; CHECK-NEXT:    .reg .b32 %r<229>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.v4.b32 {%r1, %r2, %r3, %r4}, [to_f8e4m3fn_v4f32_param_0];
+; CHECK-NEXT:    mul.rn.f32 %r5, %r4, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r6, %r4, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r6, 8388608;
+; CHECK-NEXT:    selp.b32 %r7, %r5, %r4, %p1;
+; CHECK-NEXT:    and.b32 %r8, %r7, -2139095041;
+; CHECK-NEXT:    or.b32 %r9, %r8, 1056964608;
+; CHECK-NEXT:    add.s32 %r10, %r6, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r10, -2139095039;
+; CHECK-NEXT:    selp.f32 %r11, %r4, %r9, %p2;
+; CHECK-NEXT:    and.b32 %r12, %r11, 8388607;
+; CHECK-NEXT:    or.b32 %r13, %r12, 8388608;
+; CHECK-NEXT:    and.b32 %r14, %r5, 2139095040;
+; CHECK-NEXT:    selp.b32 %r15, %r14, %r6, %p1;
+; CHECK-NEXT:    shr.u32 %r16, %r15, 23;
+; CHECK-NEXT:    selp.b32 %r17, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r18, %r16, %r17;
+; CHECK-NEXT:    add.s32 %r19, %r18, -126;
+; CHECK-NEXT:    selp.b32 %r20, 0, %r19, %p2;
+; CHECK-NEXT:    sub.s32 %r21, 15, %r20;
+; CHECK-NEXT:    min.u32 %r22, %r21, 31;
+; CHECK-NEXT:    shr.u32 %r23, %r13, %r22;
+; CHECK-NEXT:    and.b32 %r24, %r23, 1;
+; CHECK-NEXT:    max.u32 %r25, %r22, 1;
+; CHECK-NEXT:    add.s32 %r26, %r25, -1;
+; CHECK-NEXT:    mov.b32 %r27, 1;
+; CHECK-NEXT:    shl.b32 %r28, %r27, %r26;
+; CHECK-NEXT:    add.s32 %r29, %r28, -1;
+; CHECK-NEXT:    and.b32 %r30, %r13, %r29;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r30, 0;
+; CHECK-NEXT:    selp.b32 %r31, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r32, %r31, %r24;
+; CHECK-NEXT:    shr.u32 %r33, %r13, %r26;
+; CHECK-NEXT:    and.b32 %r34, %r33, %r32;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r22, 0;
+; CHECK-NEXT:    selp.b32 %r35, %r34, 0, %p4;
+; CHECK-NEXT:    add.s32 %r36, %r23, %r35;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r36, 7;
+; CHECK-NEXT:    selp.b32 %r37, 0, %r36, %p5;
+; CHECK-NEXT:    selp.b32 %r38, 8, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r39, %r4, 24;
+; CHECK-NEXT:    and.b32 %r40, %r39, 128;
+; CHECK-NEXT:    or.b32 %r41, %r40, %r38;
+; CHECK-NEXT:    or.b32 %r42, %r41, %r37;
+; CHECK-NEXT:    bfe.u32 %r43, %r12, 20, 1;
+; CHECK-NEXT:    and.b32 %r44, %r11, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r44, 0;
+; CHECK-NEXT:    selp.b32 %r45, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r46, %r45, %r43;
+; CHECK-NEXT:    shr.u32 %r47, %r11, 19;
+; CHECK-NEXT:    and.b32 %r48, %r47, %r46;
+; CHECK-NEXT:    bfe.u32 %r49, %r11, 20, 3;
+; CHECK-NEXT:    add.s32 %r50, %r49, %r48;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r50, 7;
+; CHECK-NEXT:    selp.b32 %r51, 0, %r50, %p7;
+; CHECK-NEXT:    selp.b32 %r52, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r53, %r20, %r52;
+; CHECK-NEXT:    add.s32 %r54, %r53, 6;
+; CHECK-NEXT:    shl.b32 %r55, %r54, 3;
+; CHECK-NEXT:    or.b32 %r56, %r40, %r55;
+; CHECK-NEXT:    or.b32 %r57, %r56, %r51;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r54, 1;
+; CHECK-NEXT:    selp.b32 %r58, %r42, %r57, %p8;
+; CHECK-NEXT:    setp.eq.f32 %p9, %r4, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r59, %r40, %r58, %p9;
+; CHECK-NEXT:    setp.nan.f32 %p10, %r4, %r4;
+; CHECK-NEXT:    selp.b32 %r60, 127, %r59, %p10;
+; CHECK-NEXT:    mul.rn.f32 %r61, %r3, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r62, %r3, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p11, %r62, 8388608;
+; CHECK-NEXT:    selp.b32 %r63, %r61, %r3, %p11;
+; CHECK-NEXT:    and.b32 %r64, %r63, -2139095041;
+; CHECK-NEXT:    or.b32 %r65, %r64, 1056964608;
+; CHECK-NEXT:    add.s32 %r66, %r62, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p12, %r66, -2139095039;
+; CHECK-NEXT:    selp.f32 %r67, %r3, %r65, %p12;
+; CHECK-NEXT:    and.b32 %r68, %r67, 8388607;
+; CHECK-NEXT:    or.b32 %r69, %r68, 8388608;
+; CHECK-NEXT:    and.b32 %r70, %r61, 2139095040;
+; CHECK-NEXT:    selp.b32 %r71, %r70, %r62, %p11;
+; CHECK-NEXT:    shr.u32 %r72, %r71, 23;
+; CHECK-NEXT:    selp.b32 %r73, -25, 0, %p11;
+; CHECK-NEXT:    add.s32 %r74, %r72, %r73;
+; CHECK-NEXT:    add.s32 %r75, %r74, -126;
+; CHECK-NEXT:    selp.b32 %r76, 0, %r75, %p12;
+; CHECK-NEXT:    sub.s32 %r77, 15, %r76;
+; CHECK-NEXT:    min.u32 %r78, %r77, 31;
+; CHECK-NEXT:    shr.u32 %r79, %r69, %r78;
+; CHECK-NEXT:    and.b32 %r80, %r79, 1;
+; CHECK-NEXT:    max.u32 %r81, %r78, 1;
+; CHECK-NEXT:    add.s32 %r82, %r81, -1;
+; CHECK-NEXT:    shl.b32 %r83, %r27, %r82;
+; CHECK-NEXT:    add.s32 %r84, %r83, -1;
+; CHECK-NEXT:    and.b32 %r85, %r69, %r84;
+; CHECK-NEXT:    setp.ne.b32 %p13, %r85, 0;
+; CHECK-NEXT:    selp.b32 %r86, 1, 0, %p13;
+; CHECK-NEXT:    or.b32 %r87, %r86, %r80;
+; CHECK-NEXT:    shr.u32 %r88, %r69, %r82;
+; CHECK-NEXT:    and.b32 %r89, %r88, %r87;
+; CHECK-NEXT:    setp.ne.b32 %p14, %r78, 0;
+; CHECK-NEXT:    selp.b32 %r90, %r89, 0, %p14;
+; CHECK-NEXT:    add.s32 %r91, %r79, %r90;
+; CHECK-NEXT:    setp.gt.s32 %p15, %r91, 7;
+; CHECK-NEXT:    selp.b32 %r92, 0, %r91, %p15;
+; CHECK-NEXT:    selp.b32 %r93, 8, 0, %p15;
+; CHECK-NEXT:    shr.u32 %r94, %r3, 24;
+; CHECK-NEXT:    and.b32 %r95, %r94, 128;
+; CHECK-NEXT:    or.b32 %r96, %r95, %r93;
+; CHECK-NEXT:    or.b32 %r97, %r96, %r92;
+; CHECK-NEXT:    bfe.u32 %r98, %r68, 20, 1;
+; CHECK-NEXT:    and.b32 %r99, %r67, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p16, %r99, 0;
+; CHECK-NEXT:    selp.b32 %r100, 1, 0, %p16;
+; CHECK-NEXT:    or.b32 %r101, %r100, %r98;
+; CHECK-NEXT:    shr.u32 %r102, %r67, 19;
+; CHECK-NEXT:    and.b32 %r103, %r102, %r101;
+; CHECK-NEXT:    bfe.u32 %r104, %r67, 20, 3;
+; CHECK-NEXT:    add.s32 %r105, %r104, %r103;
+; CHECK-NEXT:    setp.gt.s32 %p17, %r105, 7;
+; CHECK-NEXT:    selp.b32 %r106, 0, %r105, %p17;
+; CHECK-NEXT:    selp.b32 %r107, 1, 0, %p17;
+; CHECK-NEXT:    add.s32 %r108, %r76, %r107;
+; CHECK-NEXT:    add.s32 %r109, %r108, 6;
+; CHECK-NEXT:    shl.b32 %r110, %r109, 3;
+; CHECK-NEXT:    or.b32 %r111, %r95, %r110;
+; CHECK-NEXT:    or.b32 %r112, %r111, %r106;
+; CHECK-NEXT:    setp.lt.s32 %p18, %r109, 1;
+; CHECK-NEXT:    selp.b32 %r113, %r97, %r112, %p18;
+; CHECK-NEXT:    setp.eq.f32 %p19, %r3, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r114, %r95, %r113, %p19;
+; CHECK-NEXT:    setp.nan.f32 %p20, %r3, %r3;
+; CHECK-NEXT:    selp.b32 %r115, 127, %r114, %p20;
+; CHECK-NEXT:    prmt.b32 %r116, %r115, %r60, 0x3340U;
+; CHECK-NEXT:    mul.rn.f32 %r117, %r2, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r118, %r2, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p21, %r118, 8388608;
+; CHECK-NEXT:    selp.b32 %r119, %r117, %r2, %p21;
+; CHECK-NEXT:    and.b32 %r120, %r119, -2139095041;
+; CHECK-NEXT:    or.b32 %r121, %r120, 1056964608;
+; CHECK-NEXT:    add.s32 %r122, %r118, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p22, %r122, -2139095039;
+; CHECK-NEXT:    selp.f32 %r123, %r2, %r121, %p22;
+; CHECK-NEXT:    and.b32 %r124, %r123, 8388607;
+; CHECK-NEXT:    or.b32 %r125, %r124, 8388608;
+; CHECK-NEXT:    and.b32 %r126, %r117, 2139095040;
+; CHECK-NEXT:    selp.b32 %r127, %r126, %r118, %p21;
+; CHECK-NEXT:    shr.u32 %r128, %r127, 23;
+; CHECK-NEXT:    selp.b32 %r129, -25, 0, %p21;
+; CHECK-NEXT:    add.s32 %r130, %r128, %r129;
+; CHECK-NEXT:    add.s32 %r131, %r130, -126;
+; CHECK-NEXT:    selp.b32 %r132, 0, %r131, %p22;
+; CHECK-NEXT:    sub.s32 %r133, 15, %r132;
+; CHECK-NEXT:    min.u32 %r134, %r133, 31;
+; CHECK-NEXT:    shr.u32 %r135, %r125, %r134;
+; CHECK-NEXT:    and.b32 %r136, %r135, 1;
+; CHECK-NEXT:    max.u32 %r137, %r134, 1;
+; CHECK-NEXT:    add.s32 %r138, %r137, -1;
+; CHECK-NEXT:    shl.b32 %r139, %r27, %r138;
+; CHECK-NEXT:    add.s32 %r140, %r139, -1;
+; CHECK-NEXT:    and.b32 %r141, %r125, %r140;
+; CHECK-NEXT:    setp.ne.b32 %p23, %r141, 0;
+; CHECK-NEXT:    selp.b32 %r142, 1, 0, %p23;
+; CHECK-NEXT:    or.b32 %r143, %r142, %r136;
+; CHECK-NEXT:    shr.u32 %r144, %r125, %r138;
+; CHECK-NEXT:    and.b32 %r145, %r144, %r143;
+; CHECK-NEXT:    setp.ne.b32 %p24, %r134, 0;
+; CHECK-NEXT:    selp.b32 %r146, %r145, 0, %p24;
+; CHECK-NEXT:    add.s32 %r147, %r135, %r146;
+; CHECK-NEXT:    setp.gt.s32 %p25, %r147, 7;
+; CHECK-NEXT:    selp.b32 %r148, 0, %r147, %p25;
+; CHECK-NEXT:    selp.b32 %r149, 8, 0, %p25;
+; CHECK-NEXT:    shr.u32 %r150, %r2, 24;
+; CHECK-NEXT:    and.b32 %r151, %r150, 128;
+; CHECK-NEXT:    or.b32 %r152, %r151, %r149;
+; CHECK-NEXT:    or.b32 %r153, %r152, %r148;
+; CHECK-NEXT:    bfe.u32 %r154, %r124, 20, 1;
+; CHECK-NEXT:    and.b32 %r155, %r123, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p26, %r155, 0;
+; CHECK-NEXT:    selp.b32 %r156, 1, 0, %p26;
+; CHECK-NEXT:    or.b32 %r157, %r156, %r154;
+; CHECK-NEXT:    shr.u32 %r158, %r123, 19;
+; CHECK-NEXT:    and.b32 %r159, %r158, %r157;
+; CHECK-NEXT:    bfe.u32 %r160, %r123, 20, 3;
+; CHECK-NEXT:    add.s32 %r161, %r160, %r159;
+; CHECK-NEXT:    setp.gt.s32 %p27, %r161, 7;
+; CHECK-NEXT:    selp.b32 %r162, 0, %r161, %p27;
+; CHECK-NEXT:    selp.b32 %r163, 1, 0, %p27;
+; CHECK-NEXT:    add.s32 %r164, %r132, %r163;
+; CHECK-NEXT:    add.s32 %r165, %r164, 6;
+; CHECK-NEXT:    shl.b32 %r166, %r165, 3;
+; CHECK-NEXT:    or.b32 %r167, %r151, %r166;
+; CHECK-NEXT:    or.b32 %r168, %r167, %r162;
+; CHECK-NEXT:    setp.lt.s32 %p28, %r165, 1;
+; CHECK-NEXT:    selp.b32 %r169, %r153, %r168, %p28;
+; CHECK-NEXT:    setp.eq.f32 %p29, %r2, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r170, %r151, %r169, %p29;
+; CHECK-NEXT:    setp.nan.f32 %p30, %r2, %r2;
+; CHECK-NEXT:    selp.b32 %r171, 127, %r170, %p30;
+; CHECK-NEXT:    mul.rn.f32 %r172, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r173, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p31, %r173, 8388608;
+; CHECK-NEXT:    selp.b32 %r174, %r172, %r1, %p31;
+; CHECK-NEXT:    and.b32 %r175, %r174, -2139095041;
+; CHECK-NEXT:    or.b32 %r176, %r175, 1056964608;
+; CHECK-NEXT:    add.s32 %r177, %r173, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p32, %r177, -2139095039;
+; CHECK-NEXT:    selp.f32 %r178, %r1, %r176, %p32;
+; CHECK-NEXT:    and.b32 %r179, %r178, 8388607;
+; CHECK-NEXT:    or.b32 %r180, %r179, 8388608;
+; CHECK-NEXT:    and.b32 %r181, %r172, 2139095040;
+; CHECK-NEXT:    selp.b32 %r182, %r181, %r173, %p31;
+; CHECK-NEXT:    shr.u32 %r183, %r182, 23;
+; CHECK-NEXT:    selp.b32 %r184, -25, 0, %p31;
+; CHECK-NEXT:    add.s32 %r185, %r183, %r184;
+; CHECK-NEXT:    add.s32 %r186, %r185, -126;
+; CHECK-NEXT:    selp.b32 %r187, 0, %r186, %p32;
+; CHECK-NEXT:    sub.s32 %r188, 15, %r187;
+; CHECK-NEXT:    min.u32 %r189, %r188, 31;
+; CHECK-NEXT:    shr.u32 %r190, %r180, %r189;
+; CHECK-NEXT:    and.b32 %r191, %r190, 1;
+; CHECK-NEXT:    max.u32 %r192, %r189, 1;
+; CHECK-NEXT:    add.s32 %r193, %r192, -1;
+; CHECK-NEXT:    shl.b32 %r194, %r27, %r193;
+; CHECK-NEXT:    add.s32 %r195, %r194, -1;
+; CHECK-NEXT:    and.b32 %r196, %r180, %r195;
+; CHECK-NEXT:    setp.ne.b32 %p33, %r196, 0;
+; CHECK-NEXT:    selp.b32 %r197, 1, 0, %p33;
+; CHECK-NEXT:    or.b32 %r198, %r197, %r191;
+; CHECK-NEXT:    shr.u32 %r199, %r180, %r193;
+; CHECK-NEXT:    and.b32 %r200, %r199, %r198;
+; CHECK-NEXT:    setp.ne.b32 %p34, %r189, 0;
+; CHECK-NEXT:    selp.b32 %r201, %r200, 0, %p34;
+; CHECK-NEXT:    add.s32 %r202, %r190, %r201;
+; CHECK-NEXT:    setp.gt.s32 %p35, %r202, 7;
+; CHECK-NEXT:    selp.b32 %r203, 0, %r202, %p35;
+; CHECK-NEXT:    selp.b32 %r204, 8, 0, %p35;
+; CHECK-NEXT:    shr.u32 %r205, %r1, 24;
+; CHECK-NEXT:    and.b32 %r206, %r205, 128;
+; CHECK-NEXT:    or.b32 %r207, %r206, %r204;
+; CHECK-NEXT:    or.b32 %r208, %r207, %r203;
+; CHECK-NEXT:    bfe.u32 %r209, %r179, 20, 1;
+; CHECK-NEXT:    and.b32 %r210, %r178, 524287;
+; CHECK-NEXT:    setp.ne.b32 %p36, %r210, 0;
+; CHECK-NEXT:    selp.b32 %r211, 1, 0, %p36;
+; CHECK-NEXT:    or.b32 %r212, %r211, %r209;
+; CHECK-NEXT:    shr.u32 %r213, %r178, 19;
+; CHECK-NEXT:    and.b32 %r214, %r213, %r212;
+; CHECK-NEXT:    bfe.u32 %r215, %r178, 20, 3;
+; CHECK-NEXT:    add.s32 %r216, %r215, %r214;
+; CHECK-NEXT:    setp.gt.s32 %p37, %r216, 7;
+; CHECK-NEXT:    selp.b32 %r217, 0, %r216, %p37;
+; CHECK-NEXT:    selp.b32 %r218, 1, 0, %p37;
+; CHECK-NEXT:    add.s32 %r219, %r187, %r218;
+; CHECK-NEXT:    add.s32 %r220, %r219, 6;
+; CHECK-NEXT:    shl.b32 %r221, %r220, 3;
+; CHECK-NEXT:    or.b32 %r222, %r206, %r221;
+; CHECK-NEXT:    or.b32 %r223, %r222, %r217;
+; CHECK-NEXT:    setp.lt.s32 %p38, %r220, 1;
+; CHECK-NEXT:    selp.b32 %r224, %r208, %r223, %p38;
+; CHECK-NEXT:    setp.eq.f32 %p39, %r1, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r225, %r206, %r224, %p39;
+; CHECK-NEXT:    setp.nan.f32 %p40, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r226, 127, %r225, %p40;
+; CHECK-NEXT:    prmt.b32 %r227, %r226, %r171, 0x3340U;
+; CHECK-NEXT:    prmt.b32 %r228, %r227, %r116, 0x5410U;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r228;
+; CHECK-NEXT:    ret;
+  %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <4 x i8> %r
+}
+
+; <4 x float> -> <4 x i8> Float8E5M2
+define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f8e5m2_v4f32(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<57>;
+; CHECK-NEXT:    .reg .b32 %r<253>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.v4.b32 {%r1, %r2, %r3, %r4}, [to_f8e5m2_v4f32_param_0];
+; CHECK-NEXT:    mul.rn.f32 %r5, %r4, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r6, %r4, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p1, %r6, 8388608;
+; CHECK-NEXT:    selp.b32 %r7, %r5, %r4, %p1;
+; CHECK-NEXT:    and.b32 %r8, %r7, -2139095041;
+; CHECK-NEXT:    or.b32 %r9, %r8, 1056964608;
+; CHECK-NEXT:    add.s32 %r10, %r6, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p2, %r10, -2139095039;
+; CHECK-NEXT:    selp.f32 %r11, %r4, %r9, %p2;
+; CHECK-NEXT:    and.b32 %r12, %r11, 8388607;
+; CHECK-NEXT:    or.b32 %r13, %r12, 8388608;
+; CHECK-NEXT:    and.b32 %r14, %r5, 2139095040;
+; CHECK-NEXT:    selp.b32 %r15, %r14, %r6, %p1;
+; CHECK-NEXT:    shr.u32 %r16, %r15, 23;
+; CHECK-NEXT:    selp.b32 %r17, -25, 0, %p1;
+; CHECK-NEXT:    add.s32 %r18, %r16, %r17;
+; CHECK-NEXT:    add.s32 %r19, %r18, -126;
+; CHECK-NEXT:    selp.b32 %r20, 0, %r19, %p2;
+; CHECK-NEXT:    sub.s32 %r21, 8, %r20;
+; CHECK-NEXT:    min.u32 %r22, %r21, 31;
+; CHECK-NEXT:    shr.u32 %r23, %r13, %r22;
+; CHECK-NEXT:    and.b32 %r24, %r23, 1;
+; CHECK-NEXT:    max.u32 %r25, %r22, 1;
+; CHECK-NEXT:    add.s32 %r26, %r25, -1;
+; CHECK-NEXT:    mov.b32 %r27, 1;
+; CHECK-NEXT:    shl.b32 %r28, %r27, %r26;
+; CHECK-NEXT:    add.s32 %r29, %r28, -1;
+; CHECK-NEXT:    and.b32 %r30, %r13, %r29;
+; CHECK-NEXT:    setp.ne.b32 %p3, %r30, 0;
+; CHECK-NEXT:    selp.b32 %r31, 1, 0, %p3;
+; CHECK-NEXT:    or.b32 %r32, %r31, %r24;
+; CHECK-NEXT:    shr.u32 %r33, %r13, %r26;
+; CHECK-NEXT:    and.b32 %r34, %r33, %r32;
+; CHECK-NEXT:    setp.ne.b32 %p4, %r22, 0;
+; CHECK-NEXT:    selp.b32 %r35, %r34, 0, %p4;
+; CHECK-NEXT:    add.s32 %r36, %r23, %r35;
+; CHECK-NEXT:    setp.gt.s32 %p5, %r36, 3;
+; CHECK-NEXT:    selp.b32 %r37, 0, %r36, %p5;
+; CHECK-NEXT:    selp.b32 %r38, 4, 0, %p5;
+; CHECK-NEXT:    shr.u32 %r39, %r4, 24;
+; CHECK-NEXT:    and.b32 %r40, %r39, 128;
+; CHECK-NEXT:    or.b32 %r41, %r40, %r38;
+; CHECK-NEXT:    or.b32 %r42, %r41, %r37;
+; CHECK-NEXT:    bfe.u32 %r43, %r12, 21, 1;
+; CHECK-NEXT:    and.b32 %r44, %r11, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p6, %r44, 0;
+; CHECK-NEXT:    selp.b32 %r45, 1, 0, %p6;
+; CHECK-NEXT:    or.b32 %r46, %r45, %r43;
+; CHECK-NEXT:    shr.u32 %r47, %r11, 20;
+; CHECK-NEXT:    and.b32 %r48, %r47, %r46;
+; CHECK-NEXT:    bfe.u32 %r49, %r11, 21, 2;
+; CHECK-NEXT:    add.s32 %r50, %r49, %r48;
+; CHECK-NEXT:    setp.gt.s32 %p7, %r50, 3;
+; CHECK-NEXT:    selp.b32 %r51, 0, %r50, %p7;
+; CHECK-NEXT:    selp.b32 %r52, 1, 0, %p7;
+; CHECK-NEXT:    add.s32 %r53, %r20, %r52;
+; CHECK-NEXT:    add.s32 %r54, %r53, 14;
+; CHECK-NEXT:    shl.b32 %r55, %r54, 2;
+; CHECK-NEXT:    or.b32 %r56, %r40, %r55;
+; CHECK-NEXT:    or.b32 %r57, %r56, %r51;
+; CHECK-NEXT:    setp.lt.s32 %p8, %r54, 1;
+; CHECK-NEXT:    selp.b32 %r58, %r42, %r57, %p8;
+; CHECK-NEXT:    setp.gt.s32 %p9, %r51, 3;
+; CHECK-NEXT:    or.b32 %r59, %r40, 124;
+; CHECK-NEXT:    selp.b32 %r60, %r59, %r58, %p9;
+; CHECK-NEXT:    setp.eq.b32 %p10, %r54, 30;
+; CHECK-NEXT:    selp.b32 %r61, %r60, %r58, %p10;
+; CHECK-NEXT:    setp.gt.s32 %p11, %r54, 30;
+; CHECK-NEXT:    selp.b32 %r62, %r59, %r61, %p11;
+; CHECK-NEXT:    setp.eq.f32 %p12, %r4, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r63, %r40, %r62, %p12;
+; CHECK-NEXT:    abs.f32 %r64, %r4;
+; CHECK-NEXT:    setp.eq.f32 %p13, %r64, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r65, %r59, %r63, %p13;
+; CHECK-NEXT:    setp.nan.f32 %p14, %r4, %r4;
+; CHECK-NEXT:    selp.b32 %r66, 126, %r65, %p14;
+; CHECK-NEXT:    mul.rn.f32 %r67, %r3, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r68, %r3, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p15, %r68, 8388608;
+; CHECK-NEXT:    selp.b32 %r69, %r67, %r3, %p15;
+; CHECK-NEXT:    and.b32 %r70, %r69, -2139095041;
+; CHECK-NEXT:    or.b32 %r71, %r70, 1056964608;
+; CHECK-NEXT:    add.s32 %r72, %r68, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p16, %r72, -2139095039;
+; CHECK-NEXT:    selp.f32 %r73, %r3, %r71, %p16;
+; CHECK-NEXT:    and.b32 %r74, %r73, 8388607;
+; CHECK-NEXT:    or.b32 %r75, %r74, 8388608;
+; CHECK-NEXT:    and.b32 %r76, %r67, 2139095040;
+; CHECK-NEXT:    selp.b32 %r77, %r76, %r68, %p15;
+; CHECK-NEXT:    shr.u32 %r78, %r77, 23;
+; CHECK-NEXT:    selp.b32 %r79, -25, 0, %p15;
+; CHECK-NEXT:    add.s32 %r80, %r78, %r79;
+; CHECK-NEXT:    add.s32 %r81, %r80, -126;
+; CHECK-NEXT:    selp.b32 %r82, 0, %r81, %p16;
+; CHECK-NEXT:    sub.s32 %r83, 8, %r82;
+; CHECK-NEXT:    min.u32 %r84, %r83, 31;
+; CHECK-NEXT:    shr.u32 %r85, %r75, %r84;
+; CHECK-NEXT:    and.b32 %r86, %r85, 1;
+; CHECK-NEXT:    max.u32 %r87, %r84, 1;
+; CHECK-NEXT:    add.s32 %r88, %r87, -1;
+; CHECK-NEXT:    shl.b32 %r89, %r27, %r88;
+; CHECK-NEXT:    add.s32 %r90, %r89, -1;
+; CHECK-NEXT:    and.b32 %r91, %r75, %r90;
+; CHECK-NEXT:    setp.ne.b32 %p17, %r91, 0;
+; CHECK-NEXT:    selp.b32 %r92, 1, 0, %p17;
+; CHECK-NEXT:    or.b32 %r93, %r92, %r86;
+; CHECK-NEXT:    shr.u32 %r94, %r75, %r88;
+; CHECK-NEXT:    and.b32 %r95, %r94, %r93;
+; CHECK-NEXT:    setp.ne.b32 %p18, %r84, 0;
+; CHECK-NEXT:    selp.b32 %r96, %r95, 0, %p18;
+; CHECK-NEXT:    add.s32 %r97, %r85, %r96;
+; CHECK-NEXT:    setp.gt.s32 %p19, %r97, 3;
+; CHECK-NEXT:    selp.b32 %r98, 0, %r97, %p19;
+; CHECK-NEXT:    selp.b32 %r99, 4, 0, %p19;
+; CHECK-NEXT:    shr.u32 %r100, %r3, 24;
+; CHECK-NEXT:    and.b32 %r101, %r100, 128;
+; CHECK-NEXT:    or.b32 %r102, %r101, %r99;
+; CHECK-NEXT:    or.b32 %r103, %r102, %r98;
+; CHECK-NEXT:    bfe.u32 %r104, %r74, 21, 1;
+; CHECK-NEXT:    and.b32 %r105, %r73, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p20, %r105, 0;
+; CHECK-NEXT:    selp.b32 %r106, 1, 0, %p20;
+; CHECK-NEXT:    or.b32 %r107, %r106, %r104;
+; CHECK-NEXT:    shr.u32 %r108, %r73, 20;
+; CHECK-NEXT:    and.b32 %r109, %r108, %r107;
+; CHECK-NEXT:    bfe.u32 %r110, %r73, 21, 2;
+; CHECK-NEXT:    add.s32 %r111, %r110, %r109;
+; CHECK-NEXT:    setp.gt.s32 %p21, %r111, 3;
+; CHECK-NEXT:    selp.b32 %r112, 0, %r111, %p21;
+; CHECK-NEXT:    selp.b32 %r113, 1, 0, %p21;
+; CHECK-NEXT:    add.s32 %r114, %r82, %r113;
+; CHECK-NEXT:    add.s32 %r115, %r114, 14;
+; CHECK-NEXT:    shl.b32 %r116, %r115, 2;
+; CHECK-NEXT:    or.b32 %r117, %r101, %r116;
+; CHECK-NEXT:    or.b32 %r118, %r117, %r112;
+; CHECK-NEXT:    setp.lt.s32 %p22, %r115, 1;
+; CHECK-NEXT:    selp.b32 %r119, %r103, %r118, %p22;
+; CHECK-NEXT:    setp.gt.s32 %p23, %r112, 3;
+; CHECK-NEXT:    or.b32 %r120, %r101, 124;
+; CHECK-NEXT:    selp.b32 %r121, %r120, %r119, %p23;
+; CHECK-NEXT:    setp.eq.b32 %p24, %r115, 30;
+; CHECK-NEXT:    selp.b32 %r122, %r121, %r119, %p24;
+; CHECK-NEXT:    setp.gt.s32 %p25, %r115, 30;
+; CHECK-NEXT:    selp.b32 %r123, %r120, %r122, %p25;
+; CHECK-NEXT:    setp.eq.f32 %p26, %r3, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r124, %r101, %r123, %p26;
+; CHECK-NEXT:    abs.f32 %r125, %r3;
+; CHECK-NEXT:    setp.eq.f32 %p27, %r125, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r126, %r120, %r124, %p27;
+; CHECK-NEXT:    setp.nan.f32 %p28, %r3, %r3;
+; CHECK-NEXT:    selp.b32 %r127, 126, %r126, %p28;
+; CHECK-NEXT:    prmt.b32 %r128, %r127, %r66, 0x3340U;
+; CHECK-NEXT:    mul.rn.f32 %r129, %r2, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r130, %r2, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p29, %r130, 8388608;
+; CHECK-NEXT:    selp.b32 %r131, %r129, %r2, %p29;
+; CHECK-NEXT:    and.b32 %r132, %r131, -2139095041;
+; CHECK-NEXT:    or.b32 %r133, %r132, 1056964608;
+; CHECK-NEXT:    add.s32 %r134, %r130, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p30, %r134, -2139095039;
+; CHECK-NEXT:    selp.f32 %r135, %r2, %r133, %p30;
+; CHECK-NEXT:    and.b32 %r136, %r135, 8388607;
+; CHECK-NEXT:    or.b32 %r137, %r136, 8388608;
+; CHECK-NEXT:    and.b32 %r138, %r129, 2139095040;
+; CHECK-NEXT:    selp.b32 %r139, %r138, %r130, %p29;
+; CHECK-NEXT:    shr.u32 %r140, %r139, 23;
+; CHECK-NEXT:    selp.b32 %r141, -25, 0, %p29;
+; CHECK-NEXT:    add.s32 %r142, %r140, %r141;
+; CHECK-NEXT:    add.s32 %r143, %r142, -126;
+; CHECK-NEXT:    selp.b32 %r144, 0, %r143, %p30;
+; CHECK-NEXT:    sub.s32 %r145, 8, %r144;
+; CHECK-NEXT:    min.u32 %r146, %r145, 31;
+; CHECK-NEXT:    shr.u32 %r147, %r137, %r146;
+; CHECK-NEXT:    and.b32 %r148, %r147, 1;
+; CHECK-NEXT:    max.u32 %r149, %r146, 1;
+; CHECK-NEXT:    add.s32 %r150, %r149, -1;
+; CHECK-NEXT:    shl.b32 %r151, %r27, %r150;
+; CHECK-NEXT:    add.s32 %r152, %r151, -1;
+; CHECK-NEXT:    and.b32 %r153, %r137, %r152;
+; CHECK-NEXT:    setp.ne.b32 %p31, %r153, 0;
+; CHECK-NEXT:    selp.b32 %r154, 1, 0, %p31;
+; CHECK-NEXT:    or.b32 %r155, %r154, %r148;
+; CHECK-NEXT:    shr.u32 %r156, %r137, %r150;
+; CHECK-NEXT:    and.b32 %r157, %r156, %r155;
+; CHECK-NEXT:    setp.ne.b32 %p32, %r146, 0;
+; CHECK-NEXT:    selp.b32 %r158, %r157, 0, %p32;
+; CHECK-NEXT:    add.s32 %r159, %r147, %r158;
+; CHECK-NEXT:    setp.gt.s32 %p33, %r159, 3;
+; CHECK-NEXT:    selp.b32 %r160, 0, %r159, %p33;
+; CHECK-NEXT:    selp.b32 %r161, 4, 0, %p33;
+; CHECK-NEXT:    shr.u32 %r162, %r2, 24;
+; CHECK-NEXT:    and.b32 %r163, %r162, 128;
+; CHECK-NEXT:    or.b32 %r164, %r163, %r161;
+; CHECK-NEXT:    or.b32 %r165, %r164, %r160;
+; CHECK-NEXT:    bfe.u32 %r166, %r136, 21, 1;
+; CHECK-NEXT:    and.b32 %r167, %r135, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p34, %r167, 0;
+; CHECK-NEXT:    selp.b32 %r168, 1, 0, %p34;
+; CHECK-NEXT:    or.b32 %r169, %r168, %r166;
+; CHECK-NEXT:    shr.u32 %r170, %r135, 20;
+; CHECK-NEXT:    and.b32 %r171, %r170, %r169;
+; CHECK-NEXT:    bfe.u32 %r172, %r135, 21, 2;
+; CHECK-NEXT:    add.s32 %r173, %r172, %r171;
+; CHECK-NEXT:    setp.gt.s32 %p35, %r173, 3;
+; CHECK-NEXT:    selp.b32 %r174, 0, %r173, %p35;
+; CHECK-NEXT:    selp.b32 %r175, 1, 0, %p35;
+; CHECK-NEXT:    add.s32 %r176, %r144, %r175;
+; CHECK-NEXT:    add.s32 %r177, %r176, 14;
+; CHECK-NEXT:    shl.b32 %r178, %r177, 2;
+; CHECK-NEXT:    or.b32 %r179, %r163, %r178;
+; CHECK-NEXT:    or.b32 %r180, %r179, %r174;
+; CHECK-NEXT:    setp.lt.s32 %p36, %r177, 1;
+; CHECK-NEXT:    selp.b32 %r181, %r165, %r180, %p36;
+; CHECK-NEXT:    setp.gt.s32 %p37, %r174, 3;
+; CHECK-NEXT:    or.b32 %r182, %r163, 124;
+; CHECK-NEXT:    selp.b32 %r183, %r182, %r181, %p37;
+; CHECK-NEXT:    setp.eq.b32 %p38, %r177, 30;
+; CHECK-NEXT:    selp.b32 %r184, %r183, %r181, %p38;
+; CHECK-NEXT:    setp.gt.s32 %p39, %r177, 30;
+; CHECK-NEXT:    selp.b32 %r185, %r182, %r184, %p39;
+; CHECK-NEXT:    setp.eq.f32 %p40, %r2, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r186, %r163, %r185, %p40;
+; CHECK-NEXT:    abs.f32 %r187, %r2;
+; CHECK-NEXT:    setp.eq.f32 %p41, %r187, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r188, %r182, %r186, %p41;
+; CHECK-NEXT:    setp.nan.f32 %p42, %r2, %r2;
+; CHECK-NEXT:    selp.b32 %r189, 126, %r188, %p42;
+; CHECK-NEXT:    mul.rn.f32 %r190, %r1, 0f4C000000;
+; CHECK-NEXT:    and.b32 %r191, %r1, 2147483647;
+; CHECK-NEXT:    setp.lt.u32 %p43, %r191, 8388608;
+; CHECK-NEXT:    selp.b32 %r192, %r190, %r1, %p43;
+; CHECK-NEXT:    and.b32 %r193, %r192, -2139095041;
+; CHECK-NEXT:    or.b32 %r194, %r193, 1056964608;
+; CHECK-NEXT:    add.s32 %r195, %r191, -2139095040;
+; CHECK-NEXT:    setp.lt.u32 %p44, %r195, -2139095039;
+; CHECK-NEXT:    selp.f32 %r196, %r1, %r194, %p44;
+; CHECK-NEXT:    and.b32 %r197, %r196, 8388607;
+; CHECK-NEXT:    or.b32 %r198, %r197, 8388608;
+; CHECK-NEXT:    and.b32 %r199, %r190, 2139095040;
+; CHECK-NEXT:    selp.b32 %r200, %r199, %r191, %p43;
+; CHECK-NEXT:    shr.u32 %r201, %r200, 23;
+; CHECK-NEXT:    selp.b32 %r202, -25, 0, %p43;
+; CHECK-NEXT:    add.s32 %r203, %r201, %r202;
+; CHECK-NEXT:    add.s32 %r204, %r203, -126;
+; CHECK-NEXT:    selp.b32 %r205, 0, %r204, %p44;
+; CHECK-NEXT:    sub.s32 %r206, 8, %r205;
+; CHECK-NEXT:    min.u32 %r207, %r206, 31;
+; CHECK-NEXT:    shr.u32 %r208, %r198, %r207;
+; CHECK-NEXT:    and.b32 %r209, %r208, 1;
+; CHECK-NEXT:    max.u32 %r210, %r207, 1;
+; CHECK-NEXT:    add.s32 %r211, %r210, -1;
+; CHECK-NEXT:    shl.b32 %r212, %r27, %r211;
+; CHECK-NEXT:    add.s32 %r213, %r212, -1;
+; CHECK-NEXT:    and.b32 %r214, %r198, %r213;
+; CHECK-NEXT:    setp.ne.b32 %p45, %r214, 0;
+; CHECK-NEXT:    selp.b32 %r215, 1, 0, %p45;
+; CHECK-NEXT:    or.b32 %r216, %r215, %r209;
+; CHECK-NEXT:    shr.u32 %r217, %r198, %r211;
+; CHECK-NEXT:    and.b32 %r218, %r217, %r216;
+; CHECK-NEXT:    setp.ne.b32 %p46, %r207, 0;
+; CHECK-NEXT:    selp.b32 %r219, %r218, 0, %p46;
+; CHECK-NEXT:    add.s32 %r220, %r208, %r219;
+; CHECK-NEXT:    setp.gt.s32 %p47, %r220, 3;
+; CHECK-NEXT:    selp.b32 %r221, 0, %r220, %p47;
+; CHECK-NEXT:    selp.b32 %r222, 4, 0, %p47;
+; CHECK-NEXT:    shr.u32 %r223, %r1, 24;
+; CHECK-NEXT:    and.b32 %r224, %r223, 128;
+; CHECK-NEXT:    or.b32 %r225, %r224, %r222;
+; CHECK-NEXT:    or.b32 %r226, %r225, %r221;
+; CHECK-NEXT:    bfe.u32 %r227, %r197, 21, 1;
+; CHECK-NEXT:    and.b32 %r228, %r196, 1048575;
+; CHECK-NEXT:    setp.ne.b32 %p48, %r228, 0;
+; CHECK-NEXT:    selp.b32 %r229, 1, 0, %p48;
+; CHECK-NEXT:    or.b32 %r230, %r229, %r227;
+; CHECK-NEXT:    shr.u32 %r231, %r196, 20;
+; CHECK-NEXT:    and.b32 %r232, %r231, %r230;
+; CHECK-NEXT:    bfe.u32 %r233, %r196, 21, 2;
+; CHECK-NEXT:    add.s32 %r234, %r233, %r232;
+; CHECK-NEXT:    setp.gt.s32 %p49, %r234, 3;
+; CHECK-NEXT:    selp.b32 %r235, 0, %r234, %p49;
+; CHECK-NEXT:    selp.b32 %r236, 1, 0, %p49;
+; CHECK-NEXT:    add.s32 %r237, %r205, %r236;
+; CHECK-NEXT:    add.s32 %r238, %r237, 14;
+; CHECK-NEXT:    shl.b32 %r239, %r238, 2;
+; CHECK-NEXT:    or.b32 %r240, %r224, %r239;
+; CHECK-NEXT:    or.b32 %r241, %r240, %r235;
+; CHECK-NEXT:    setp.lt.s32 %p50, %r238, 1;
+; CHECK-NEXT:    selp.b32 %r242, %r226, %r241, %p50;
+; CHECK-NEXT:    setp.gt.s32 %p51, %r235, 3;
+; CHECK-NEXT:    or.b32 %r243, %r224, 124;
+; CHECK-NEXT:    selp.b32 %r244, %r243, %r242, %p51;
+; CHECK-NEXT:    setp.eq.b32 %p52, %r238, 30;
+; CHECK-NEXT:    selp.b32 %r245, %r244, %r242, %p52;
+; CHECK-NEXT:    setp.gt.s32 %p53, %r238, 30;
+; CHECK-NEXT:    selp.b32 %r246, %r243, %r245, %p53;
+; CHECK-NEXT:    setp.eq.f32 %p54, %r1, 0f00000000;
+; CHECK-NEXT:    selp.b32 %r247, %r224, %r246, %p54;
+; CHECK-NEXT:    abs.f32 %r248, %r1;
+; CHECK-NEXT:    setp.eq.f32 %p55, %r248, 0f7F800000;
+; CHECK-NEXT:    selp.b32 %r249, %r243, %r247, %p55;
+; CHECK-NEXT:    setp.nan.f32 %p56, %r1, %r1;
+; CHECK-NEXT:    selp.b32 %r250, 126, %r249, %p56;
+; CHECK-NEXT:    prmt.b32 %r251, %r250, %r189, 0x3340U;
+; CHECK-NEXT:    prmt.b32 %r252, %r251, %r128, 0x5410U;
+; CHECK-NEXT:    st.param.b32 [func_retval0], %r252;
+; CHECK-NEXT:    ret;
+  %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float> %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret <4 x i8> %r
+}
+
+; <2 x half> -> <2 x i8> Float8E4M3FN
+define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v2f16(
+; CHECK:       {
+; CHECK-NEXT:    .reg .pred %p<21>;
+; CHECK-NEXT:    .reg .b16 %rs<98>;
+; CHECK-NEXT:    .reg .b32 %r<43>;
+; CHECK-EMPTY:
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    ld.param.b32 %r1, [to_f8e4m3fn_v2f16_param_0];
+; CHECK-NEXT:    mov.b32 {%rs1, %rs2}, %r1;
+; CHECK-NEXT:    mov.b16 %rs3, 0x6C00;
+; CHECK-NEXT:    mul.rn.f16 %rs4, %rs2, %rs3;
+; CHECK-NEXT:    and.b16 %rs5, %rs2, 32767;
+; CHECK-NEXT:    setp.lt.u16 %p1, %rs5, 1024;
+; CHECK-NEXT:    selp.b16 %rs6, %rs4, %rs2, %p1;
+; CHECK-NEXT:    and.b16 %rs7, %rs6, -31745;
+; CHECK-NEXT:    or.b16 %rs8, %rs7, 14336;
+; CHECK-NEXT:    add.s16 %rs9, %rs5, -31744;
+; CHECK-NEXT:    setp.lt.u16 %p2, %rs9, -31743;
+; CHECK-NEXT:    selp.b16 %rs10, %rs2, %rs8, %p2;
+; CHECK-NEXT:    mul.rn.f16 %rs11, %rs1, %rs3;
+; CHECK-NEXT:    and.b16 %rs12, %rs1, 32767;
+; CHECK-NEXT:    setp.lt.u16 %p3, %rs12, 1024;
+; CHECK-NEXT:    selp.b16 %rs13, %rs11, %rs1, %p3;
+; CHECK-NEXT:    and.b16 %rs14, %rs13, -31745;
+; CHECK-NEXT:    or.b16 %rs15, %rs14, 14336;
+; CHECK-NEXT:    add.s16 %rs16, %rs12, -31744;
+; CHECK-NEXT:    setp.lt.u16 %p4, %rs16, -31743;
+; CHECK-NEXT:    selp.b16 %rs17, %rs1, %rs15, %p4;
+; CHECK-NEXT:    mov.b32 %r2, {%rs17, %rs10};
+; CHECK-NEXT:    and.b32 %r3, %r2, 4128831;
+; CHECK-NEXT:    mov.b32 {%rs18, %rs19}, %r3;
+; CHECK-NEXT:    setp.ne.b16 %p5, %rs19, 0;
+; CHECK-NEXT:    selp.b16 %rs20, 1, 0, %p5;
+; CHECK-NEXT:    setp.ne.b16 %p6, %rs18, 0;
+; CHECK-NEXT:    selp.b16 %rs21, 1, 0, %p6;
+; CHECK-NEXT:    mov.b32 %r4, {%rs21, %rs20};
+; CHECK-NEXT:    and.b32 %r5, %r2, 67044351;
+; CHECK-NEXT:    mov.b32 {%rs22, %rs23}, %r5;
+; CHECK-NEXT:    shr.u16 %rs24, %rs23, 7;
+; CHECK-NEXT:    shr.u16 %rs25, %rs22, 7;
+; CHECK-NEXT:    mov.b32 %r6, {%rs25, %rs24};
+; CHECK-NEXT:    and.b32 %r7, %r6, 65537;
+; CHECK-NEXT:    or.b32 %r8, %r4, %r7;
+; CHECK-NEXT:    shr.u16 %rs26, %rs23, 6;
+; CHECK-NEXT:    shr.u16 %rs27, %rs22, 6;
+; CHECK-NEXT:    mov.b32 %r9, {%rs27, %rs26};
+; CHECK-NEXT:    and.b32 %r10, %r9, %r8;
+; CHECK-NEXT:    mov.b32 {%rs28, %rs29}, %r10;
+; CHECK-NEXT:    add.s16 %rs30, %rs24, %rs29;
+; CHECK-NEXT:    setp.gt.s16 %p7, %rs30, 7;
+; CHECK-NEXT:    selp.b16 %rs31, 0, %rs30, %p7;
+; CHECK-NEXT:    add.s16 %rs32, %rs25, %rs28;
+; CHECK-NEXT:    setp.gt.s16 %p8, %rs32, 7;
+; CHECK-NEXT:    selp.b16 %rs33, 0, %rs32, %p8;
+; CHECK-NEXT:    mov.b32 %r11, {%rs33, %rs31};
+; CHECK-NEXT:    selp.b16 %rs34, 1, 0, %p7;
+; CHECK-NEXT:    and.b16 %rs35, %rs4, 31744;
+; CHECK-NEXT:    selp.b16 %rs36, %rs35, %rs5, %p1;
+; CHECK-NEXT:    shr.u16 %rs37, %rs36, 10;
+; CHECK-NEXT:    cvt.u32.u16 %r12, %rs37;
+; CHECK-NEXT:    selp.b32 %r13, -12, 0, %p1;
+; CHECK-NEXT:    add.s32 %r14, %r12, %r13;
+; CHECK-NEXT:    add.s32 %r15, %r14, -14;
+; CHECK-NEXT:    selp.b32 %r16, 0, %r15, %p2;
+; CHECK-NEXT:    cvt.u16.u32 %rs38, %r16;
+; CHECK-NEXT:    add.s16 %rs39, %rs38, %rs34;
+; CHECK-NEXT:    add.s16 %rs40, %rs39, 6;
+; CHECK-NEXT:    shl.b16 %rs41, %rs40, 3;
+; CHECK-NEXT:    selp.b16 %rs42, 1, 0, %p8;
+; CHECK-NEXT:    and.b16 %rs43, %rs11, 31744;
+; CHECK-NEXT:    selp.b16 %rs44, %rs43, %rs12, %p3;
+; CHECK-NEXT:    shr.u16 %rs45, %rs44, 10;
+; CHECK-NEXT:    cvt.u32.u16 %r17, %rs45;
+; CHECK-NEXT:    selp.b32 %r18, -12, 0, %p3;
+; CHECK-NEXT:    add.s32 %r19, %r17, %r18;
+; CHECK-NEXT:    add.s32 %r20, %r19, -14;
+; CHECK-NEXT:    selp.b32 %r21, 0, %r20, %p4;
+; CHECK-NEXT:    cvt.u16.u32 %rs46, %r21;
+; CHECK-NEXT:    add.s16 %rs47, %rs46, %rs42;
+; CHECK-NEXT:    add.s16 %rs48, %rs47, 6;
+; CHECK-NEXT:    shl.b16 %rs49, %rs48, 3;
+; CHECK-NEXT:    mov.b32 %r22, {%rs49, %rs41};
+; CHECK-NEXT:    shr.u16 %rs50, %rs2, 8;
+; CHECK-NEXT:    and.b16 %rs51, %rs50, 128;
+; CHECK-NEXT:    shr.u16 %rs52, %rs1, 8;
+; CHECK-NEXT:    and.b16 %rs53, %rs52, 128;
+; CHECK-NEXT:    mov.b32 %r23, {%rs53, %rs51};
+; CHECK-NEXT:    or.b32 %r24, %r23, %r22;
+; CHECK-NEXT:    or.b32 %r25, %r24, %r11;
+; CHECK-NEXT:    mov.b32 {%rs54, %rs55}, %r25;
+; CHECK-NEXT:    sub.s16 %rs56, 2, %rs38;
+; CHECK-NEXT:    min.u16 %rs57, %rs56, 15;
+; CHECK-NEXT:    max.u16 %rs58, %rs57, 1;
+; CHECK-NEXT:    add.s16 %rs59, %rs58, -1;
+; CHECK-NEXT:    cvt.u32.u16 %r26, %rs59;
+; CHECK-NEXT:    mov.b16 %rs60, 1;
+; CHECK-NEXT:    shl.b16 %rs61, %rs60, %r26;
+; CHECK-NEXT:    add.s16 %rs62, %rs61, -1;
+; CHECK-NEXT:    sub.s16 %rs63, 2, %rs46;
+; CHECK-NEXT:    min.u16 %rs64, %rs63, 15;
+; CHECK-NEXT:    max.u16 %rs65, %rs64, 1;
+; CHECK-NEXT:    add.s16 %rs66, %rs65, -1;
+; CHECK-NEXT:    cvt.u32.u16 %r27, %rs66;
+; CHECK-NEXT:    shl.b16 %rs67, %rs60, %r27;
+; CHECK-NEXT:    add.s16 %rs68, %rs67, -1;
+; CHECK-NEXT:    mov.b32 %r28, {%rs68, %rs62};
+; CHECK-NEXT:    or.b32 %r29, %r5, 67109888;
+; CHECK-NEXT:    and.b32 %r30, %r29, %r28;
+; CHECK-NEXT:    mov.b32 {%rs69, %rs70}, %r30;
+; CHECK-NEXT:    setp.ne.b16 %p9, %rs70, 0;
+; CHECK-NEXT:    selp.b16 %rs71, 1, 0, %p9;
+; CHECK-NEXT:    setp.ne.b16 %p10, %rs69, 0;
+; CHECK-NEXT:    selp.b16 %rs72, 1, 0, %p10;
+; CHECK-NEXT:    mov.b32 %r31, {%rs72, %rs71};
+; CHECK-NEXT:    mov.b32 {%rs73, %rs74}, %r29;
+; CHECK-NEXT:    cvt.u32.u16 %r32, %rs57;
+; CHECK-NEXT:    shr.u16 %rs75, %rs74, %r32;
+; CHECK-NEXT:    cvt.u32.u16 %r33, %rs64;
+; CHECK-NEXT:    shr.u16 %rs76, %rs73, %r33;
+; CHECK-NEXT:    mov.b32 %r34, {%rs76, %rs75};
+; CHECK-NEXT:    and.b32 %r35, %r34, 65537;
+; CHECK-NEXT:    or.b32 %r36, %r31, %r35;
+; CHECK-NEXT:    shr.u16 %rs77, %rs74, %r26;
+; CHECK-NEXT:    shr.u16 %rs78, %rs73, %r27;
+; CHECK-NEXT:    mov.b32 %r37, {%rs78, %rs77};
+; CHECK-NEXT:    and.b32 %r38, %r37, %r36;
+; CHECK-NEXT:    mov.b32 {%rs79, %rs80}, %r38;
+; CHECK-NEXT:    setp.ne.b16 %p11, %rs57, 0;
+; CHECK-NEXT:    selp.b16 %rs81, %rs80, 0, %p11;
+; CHECK-NEXT:    add.s16 %rs82, %rs75, %rs81;
+; CHECK-NEXT:    setp.gt.s16 %p12, %rs82, 7;
+; CHECK-NEXT:    selp.b16 %rs83, 0, %rs82, %p12;
+; CHECK-NEXT:    setp.ne.b16 %p13, %rs64, 0;
+; CHECK-NEXT:    selp.b16 %rs84, %rs79, 0, %p13;
+; CHECK-NEXT:    add.s16 %rs85, %rs76, %rs84;
+; CHECK-NEXT:    setp.gt.s16 %p14, %rs85, 7;
+; CHECK-NEXT:    selp.b16 %rs86, 0, %rs85, %p14;
+; CHECK-NEXT:    mov.b32 %r39, {%rs86, %rs83};
+; CHECK-NEXT:    selp.b16 %rs87, 8, 0, %p12;
+; CHECK-NEXT:    selp.b16 %rs88, 8, 0, %p14;
+; CHECK-NEXT:    mov.b32 %r40, {%rs88, %rs87};
+; CHECK-NEXT:    or.b32 %r41, %r23, %r40;
+; CHECK-NEXT:    or.b32 %r42, %r41, %r39;
+; CHECK-NEXT:    mov.b32 {%rs89, %rs90}, %r42;
+; CHECK-NEXT:    setp.lt.s16 %p15, %rs40, 1;
+; CHECK-NEXT:    selp.b16 %rs91, %rs90, %rs55, %p15;
+; CHECK-NEXT:    mov.b16 %rs92, 0x0000;
+; CHECK-NEXT:    setp.eq.f16 %p16, %rs2, %rs92;
+; CHECK-NEXT:    selp.b16 %rs93, %rs51, %rs91, %p16;
+; CHECK-NEXT:    setp.nan.f16 %p17, %rs2, %rs2;
+; CHECK-NEXT:    selp.b16 %rs94, 127, %rs93, %p17;
+; CHECK-NEXT:    setp.lt.s16 %p18, %rs48, 1;
+; CHECK-NEXT:    selp.b16 %rs95, %rs89, %rs54, %p18;
+; CHECK-NEXT:    setp.eq.f16 %p19, %rs1, %rs92;
+; CHECK-NEXT:    selp.b16 %rs96, %rs53, %rs95, %p19;
+; CHECK-NEXT:    setp.nan.f16 %p20, %rs1, %rs1;
+; CHECK-NEXT:    selp.b16 %rs97, 127, %rs96, %p20;
+; CHECK-NEXT:    st.param.v2.b8 [func_retval0], {%rs97, %rs94};
+; CHECK-NEXT:    ret;
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f16(<2 x half> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
 ; Float8E5M2 from f16: half -> i8
 define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-LABEL: to_f8e5m2_from_f16(
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
index e823b0a1ed47c..41d9b6ffc9856 100644
--- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
@@ -7,6 +7,10 @@ declare i8 @llvm.convert.to.arbitrary.fp.i8.f32(float, metadata, metadata, i1)
 declare i6 @llvm.convert.to.arbitrary.fp.i6.f32(float, metadata, metadata, i1)
 declare i4 @llvm.convert.to.arbitrary.fp.i4.f32(float, metadata, metadata, i1)
 declare <4 x i4> @llvm.convert.to.arbitrary.fp.v4i4.v4f32(<4 x float>, metadata, metadata, i1)
+declare <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float>, metadata, metadata, i1)
+declare <3 x i8> @llvm.convert.to.arbitrary.fp.v3i8.v3f32(<3 x float>, metadata, metadata, i1)
+declare <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float>, metadata, metadata, i1)
+declare <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f16(<2 x half>, metadata, metadata, i1)
 
 declare i8 @llvm.convert.to.arbitrary.fp.i8.f16(half, metadata, metadata, i1)
 declare i8 @llvm.convert.to.arbitrary.fp.i8.bf16(bfloat, metadata, metadata, i1)
@@ -196,8 +200,6 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
   ret i8 %r
 }
 
-; Vector test
-
 ; <4 x float> to <4 x i4> (Float4E2M1FN)
 define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
 ; CHECK-LABEL: to_f4e2m1fn_v4f32:
@@ -345,6 +347,1753 @@ define <4 x i4> @to_f4e2m1fn_v4f32(<4 x float> %x) {
   ret <4 x i4> %r
 }
 
+; f32 <2 x float> -> <2 x i8> Float8E5M2
+define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
+; CHECK-LABEL: to_f8e5m2_v2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $56, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 112
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    movq %rsp, %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl (%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $8, %ebx
+; CHECK-NEXT:    movl $8, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r15d
+; CHECK-NEXT:    movl %r15d, %r12d
+; CHECK-NEXT:    andl $8388607, %r12d # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%r12), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %r14d
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, %r13d
+; CHECK-NEXT:    andl $1, %r13d
+; CHECK-NEXT:    orl %edi, %r13d
+; CHECK-NEXT:    andl %edx, %r13d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %r13d
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    subl %eax, %ebx
+; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %ebx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %esi
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rsi), %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r14d
+; CHECK-NEXT:    decl %r14d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testl %r14d, %edi
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    andl %r8d, %ecx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl $0, %r8d
+; CHECK-NEXT:    cmovbl %r8d, %ecx
+; CHECK-NEXT:    addl %ebp, %r13d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $4, %r13d
+; CHECK-NEXT:    cmovgel %r8d, %r13d
+; CHECK-NEXT:    movl $0, %ebp
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm2, %r8d
+; CHECK-NEXT:    shrl $24, %r8d
+; CHECK-NEXT:    andl $-128, %r8d
+; CHECK-NEXT:    leal (%r8,%r9,4), %r9d
+; CHECK-NEXT:    orl %r13d, %r9d
+; CHECK-NEXT:    shrl $21, %r12d
+; CHECK-NEXT:    movl %r12d, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $1048575, %r15d # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %r10d, %r11d
+; CHECK-NEXT:    shrl $20, %r15d
+; CHECK-NEXT:    andl %r11d, %r15d
+; CHECK-NEXT:    addl %r12d, %r15d
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $4, %r15d
+; CHECK-NEXT:    cmovgel %ebp, %r15d
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
+; CHECK-NEXT:    leal (%r14,%r10), %r11d
+; CHECK-NEXT:    leal 56(,%r11,4), %r11d
+; CHECK-NEXT:    movl %r8d, %ebx
+; CHECK-NEXT:    orl %r15d, %ebx
+; CHECK-NEXT:    orl %r11d, %ebx
+; CHECK-NEXT:    leal 14(%r14,%r10), %r10d
+; CHECK-NEXT:    testl %r10d, %r10d
+; CHECK-NEXT:    cmovlel %r9d, %ebx
+; CHECK-NEXT:    cmpl $4, %r15d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    cmpl $30, %r10d
+; CHECK-NEXT:    sete %r11b
+; CHECK-NEXT:    andb %r9b, %r11b
+; CHECK-NEXT:    cmpl $31, %r10d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    orb %r11b, %r9b
+; CHECK-NEXT:    leal 124(%r8), %r10d
+; CHECK-NEXT:    testb %r9b, %r9b
+; CHECK-NEXT:    cmovnel %r10d, %ebx
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm1, %xmm2
+; CHECK-NEXT:    cmovnel %ebx, %r8d
+; CHECK-NEXT:    cmovpl %ebx, %r8d
+; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    movaps %xmm2, %xmm3
+; CHECK-NEXT:    movaps %xmm2, %xmm4
+; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    movss {{.*#+}} xmm2 = [+Inf,0.0E+0,0.0E+0,0.0E+0]
+; CHECK-NEXT:    ucomiss %xmm2, %xmm3
+; CHECK-NEXT:    cmovnel %r8d, %r10d
+; CHECK-NEXT:    cmovpl %r8d, %r10d
+; CHECK-NEXT:    ucomiss %xmm4, %xmm4
+; CHECK-NEXT:    movl $126, %r8d
+; CHECK-NEXT:    cmovpl %r8d, %r10d
+; CHECK-NEXT:    movzbl %r10b, %r9d
+; CHECK-NEXT:    addl %edi, %ecx
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $4, %ecx
+; CHECK-NEXT:    cmovgel %ebp, %ecx
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm3, %edi
+; CHECK-NEXT:    shrl $24, %edi
+; CHECK-NEXT:    andl $-128, %edi
+; CHECK-NEXT:    leal (%rdi,%r10,4), %r10d
+; CHECK-NEXT:    orl %ecx, %r10d
+; CHECK-NEXT:    shrl $21, %esi
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $1048575, %edx # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ecx, %r11d
+; CHECK-NEXT:    shrl $20, %edx
+; CHECK-NEXT:    andl %r11d, %edx
+; CHECK-NEXT:    addl %esi, %edx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    cmovgel %ebp, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    leal (%rax,%rcx), %esi
+; CHECK-NEXT:    leal 56(,%rsi,4), %esi
+; CHECK-NEXT:    movl %edi, %r11d
+; CHECK-NEXT:    orl %edx, %r11d
+; CHECK-NEXT:    orl %esi, %r11d
+; CHECK-NEXT:    leal 14(%rax,%rcx), %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    cmovlel %r10d, %r11d
+; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    cmpl $30, %eax
+; CHECK-NEXT:    sete %dl
+; CHECK-NEXT:    andb %cl, %dl
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %dl, %al
+; CHECK-NEXT:    leal 124(%rdi), %ecx
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    cmovnel %ecx, %r11d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm3
+; CHECK-NEXT:    cmovnel %r11d, %edi
+; CHECK-NEXT:    cmovpl %r11d, %edi
+; CHECK-NEXT:    andps %xmm3, %xmm0
+; CHECK-NEXT:    ucomiss %xmm2, %xmm0
+; CHECK-NEXT:    cmovnel %edi, %ecx
+; CHECK-NEXT:    cmovpl %edi, %ecx
+; CHECK-NEXT:    ucomiss %xmm3, %xmm3
+; CHECK-NEXT:    cmovpl %r8d, %ecx
+; CHECK-NEXT:    shll $8, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    movd %ecx, %xmm0
+; CHECK-NEXT:    addq $56, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float> %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
+; <2 x float> -> <2 x i8> Float8E4M3FN
+define <2 x i8> @to_f8e4m3fn_v2f32(<2 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v2f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $56, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 112
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    movq %rsp, %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl (%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %ebx
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r15d
+; CHECK-NEXT:    movl %r15d, %r12d
+; CHECK-NEXT:    andl $8388607, %r12d # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%r12), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %r14d
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, %r13d
+; CHECK-NEXT:    andl $1, %r13d
+; CHECK-NEXT:    orl %edi, %r13d
+; CHECK-NEXT:    andl %edx, %r13d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %r13d
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    subl %eax, %ebx
+; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %ebx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %esi
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rsi), %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r14d
+; CHECK-NEXT:    decl %r14d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testl %r14d, %edi
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    andl %r8d, %ecx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl $0, %r9d
+; CHECK-NEXT:    cmovbl %r9d, %ecx
+; CHECK-NEXT:    addl %ebp, %r13d
+; CHECK-NEXT:    xorl %r8d, %r8d
+; CHECK-NEXT:    cmpl $8, %r13d
+; CHECK-NEXT:    cmovgel %r9d, %r13d
+; CHECK-NEXT:    movl $0, %ebx
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %r9d
+; CHECK-NEXT:    shrl $24, %r9d
+; CHECK-NEXT:    andl $-128, %r9d
+; CHECK-NEXT:    leal (%r9,%r8,8), %r8d
+; CHECK-NEXT:    orl %r13d, %r8d
+; CHECK-NEXT:    shrl $20, %r12d
+; CHECK-NEXT:    movl %r12d, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $524287, %r15d # imm = 0x7FFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %r10d, %r11d
+; CHECK-NEXT:    shrl $19, %r15d
+; CHECK-NEXT:    andl %r11d, %r15d
+; CHECK-NEXT:    addl %r12d, %r15d
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $8, %r15d
+; CHECK-NEXT:    cmovgel %ebx, %r15d
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
+; CHECK-NEXT:    leal (%r14,%r10), %r11d
+; CHECK-NEXT:    leal 48(,%r11,8), %r11d
+; CHECK-NEXT:    orl %r9d, %r15d
+; CHECK-NEXT:    orl %r11d, %r15d
+; CHECK-NEXT:    leal 6(%r14,%r10), %r10d
+; CHECK-NEXT:    testl %r10d, %r10d
+; CHECK-NEXT:    cmovlel %r8d, %r15d
+; CHECK-NEXT:    xorps %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r15d, %r9d
+; CHECK-NEXT:    cmovpl %r15d, %r9d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    movl $127, %r8d
+; CHECK-NEXT:    cmovpl %r8d, %r9d
+; CHECK-NEXT:    movzbl %r9b, %r9d
+; CHECK-NEXT:    addl %edi, %ecx
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $8, %ecx
+; CHECK-NEXT:    cmovgel %ebx, %ecx
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %edi
+; CHECK-NEXT:    shrl $24, %edi
+; CHECK-NEXT:    andl $-128, %edi
+; CHECK-NEXT:    leal (%rdi,%r10,8), %r10d
+; CHECK-NEXT:    orl %ecx, %r10d
+; CHECK-NEXT:    shrl $20, %esi
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $524287, %edx # imm = 0x7FFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ecx, %r11d
+; CHECK-NEXT:    shrl $19, %edx
+; CHECK-NEXT:    andl %r11d, %edx
+; CHECK-NEXT:    addl %esi, %edx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $8, %edx
+; CHECK-NEXT:    cmovgel %ebx, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    leal (%rax,%rcx), %esi
+; CHECK-NEXT:    leal 48(,%rsi,8), %esi
+; CHECK-NEXT:    orl %edi, %edx
+; CHECK-NEXT:    orl %esi, %edx
+; CHECK-NEXT:    leal 6(%rax,%rcx), %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    cmovlel %r10d, %edx
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %edx, %edi
+; CHECK-NEXT:    cmovpl %edx, %edi
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    cmovpl %r8d, %edi
+; CHECK-NEXT:    shll $8, %edi
+; CHECK-NEXT:    orl %r9d, %edi
+; CHECK-NEXT:    movd %edi, %xmm0
+; CHECK-NEXT:    addq $56, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f32(<2 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
+; <3 x float> -> <3 x i8> Float8E4M3FN
+define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v3f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $104, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 160
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %ebx
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    movl $31, %r15d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r13d
+; CHECK-NEXT:    movl %r13d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %r14d
+; CHECK-NEXT:    movl %r14d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %r14d
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r14d
+; CHECK-NEXT:    movl %r14d, %ebp
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %ebp
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %r15d, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r15d
+; CHECK-NEXT:    movl %r15d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %r12d
+; CHECK-NEXT:    movl %r12d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %r12d
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r12d
+; CHECK-NEXT:    movl %r12d, (%rsp) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r12d
+; CHECK-NEXT:    orl %edi, %r12d
+; CHECK-NEXT:    andl %edx, %r12d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %r12d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1,1]
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT:    subl %esi, %ebx
+; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    movl $31, %eax
+; CHECK-NEXT:    cmovael %eax, %ebx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    andl $8388607, %r8d # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%r8), %r9d
+; CHECK-NEXT:    movl %r9d, %eax
+; CHECK-NEXT:    shrl %cl, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    movl $1, %edx
+; CHECK-NEXT:    shll %cl, %edx
+; CHECK-NEXT:    decl %edx
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    testl %ecx, %r9d
+; CHECK-NEXT:    setne %dl
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    shrl %cl, %r9d
+; CHECK-NEXT:    movl %r9d, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    orl %edx, %r10d
+; CHECK-NEXT:    andl %eax, %r10d
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %r10d
+; CHECK-NEXT:    addl %r14d, %ebp
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $8, %ebp
+; CHECK-NEXT:    cmovgel %eax, %ebp
+; CHECK-NEXT:    movl $0, %r14d
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    shrl $24, %eax
+; CHECK-NEXT:    andl $-128, %eax
+; CHECK-NEXT:    leal (%rax,%rcx,8), %ecx
+; CHECK-NEXT:    orl %ebp, %ecx
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload
+; CHECK-NEXT:    shrl $20, %r11d
+; CHECK-NEXT:    movl %r11d, %edx
+; CHECK-NEXT:    movq %r11, %rbx
+; CHECK-NEXT:    andl $1, %edx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $524287, %r13d # imm = 0x7FFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %edx, %r11d
+; CHECK-NEXT:    shrl $19, %r13d
+; CHECK-NEXT:    andl %r11d, %r13d
+; CHECK-NEXT:    addl %ebx, %r13d
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    cmpl $8, %r13d
+; CHECK-NEXT:    cmovgel %r14d, %r13d
+; CHECK-NEXT:    setge %dl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
+; CHECK-NEXT:    leal (%rbx,%rdx), %r11d
+; CHECK-NEXT:    leal 48(,%r11,8), %r11d
+; CHECK-NEXT:    orl %eax, %r13d
+; CHECK-NEXT:    orl %r11d, %r13d
+; CHECK-NEXT:    leal 6(%rbx,%rdx), %edx
+; CHECK-NEXT:    testl %edx, %edx
+; CHECK-NEXT:    cmovlel %ecx, %r13d
+; CHECK-NEXT:    pxor %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r13d, %eax
+; CHECK-NEXT:    cmovpl %r13d, %eax
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    movl $127, %r11d
+; CHECK-NEXT:    cmovpl %r11d, %eax
+; CHECK-NEXT:    addl (%rsp), %r12d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $8, %r12d
+; CHECK-NEXT:    movl $0, %r13d
+; CHECK-NEXT:    cmovgel %r13d, %r12d
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %edx
+; CHECK-NEXT:    shrl $24, %edx
+; CHECK-NEXT:    andl $-128, %edx
+; CHECK-NEXT:    leal (%rdx,%rcx,8), %ecx
+; CHECK-NEXT:    orl %r12d, %ecx
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
+; CHECK-NEXT:    shrl $20, %r14d
+; CHECK-NEXT:    movl %r14d, %ebx
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    testl $524287, %r15d # imm = 0x7FFFF
+; CHECK-NEXT:    setne %bpl
+; CHECK-NEXT:    orl %ebx, %ebp
+; CHECK-NEXT:    shrl $19, %r15d
+; CHECK-NEXT:    andl %ebp, %r15d
+; CHECK-NEXT:    addl %r14d, %r15d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $8, %r15d
+; CHECK-NEXT:    cmovgel %r13d, %r15d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Reload
+; CHECK-NEXT:    leal (%r12,%rbx), %r14d
+; CHECK-NEXT:    leal 48(,%r14,8), %ebp
+; CHECK-NEXT:    orl %edx, %r15d
+; CHECK-NEXT:    orl %ebp, %r15d
+; CHECK-NEXT:    leal 6(%r12,%rbx), %ebx
+; CHECK-NEXT:    testl %ebx, %ebx
+; CHECK-NEXT:    cmovlel %ecx, %r15d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r15d, %edx
+; CHECK-NEXT:    cmovpl %r15d, %edx
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    cmovpl %r11d, %edx
+; CHECK-NEXT:    addl %r9d, %r10d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $8, %r10d
+; CHECK-NEXT:    cmovgel %r13d, %r10d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %ecx
+; CHECK-NEXT:    shrl $24, %ecx
+; CHECK-NEXT:    andl $-128, %ecx
+; CHECK-NEXT:    leal (%rcx,%r9,8), %r9d
+; CHECK-NEXT:    orl %r10d, %r9d
+; CHECK-NEXT:    shrl $20, %r8d
+; CHECK-NEXT:    movl %r8d, %r10d
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    testl $524287, %edi # imm = 0x7FFFF
+; CHECK-NEXT:    setne %bl
+; CHECK-NEXT:    orl %r10d, %ebx
+; CHECK-NEXT:    shrl $19, %edi
+; CHECK-NEXT:    andl %ebx, %edi
+; CHECK-NEXT:    addl %r8d, %edi
+; CHECK-NEXT:    xorl %r8d, %r8d
+; CHECK-NEXT:    cmpl $8, %edi
+; CHECK-NEXT:    cmovgel %r13d, %edi
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    leal (%rsi,%r8), %r10d
+; CHECK-NEXT:    leal 48(,%r10,8), %r10d
+; CHECK-NEXT:    orl %ecx, %edi
+; CHECK-NEXT:    orl %r10d, %edi
+; CHECK-NEXT:    leal 6(%rsi,%r8), %esi
+; CHECK-NEXT:    testl %esi, %esi
+; CHECK-NEXT:    cmovlel %r9d, %edi
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %edi, %ecx
+; CHECK-NEXT:    cmovpl %edi, %ecx
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    cmovpl %r11d, %ecx
+; CHECK-NEXT:    # kill: def $al killed $al killed $rax
+; CHECK-NEXT:    # kill: def $dl killed $dl killed $rdx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
+; CHECK-NEXT:    addq $104, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <3 x i8> @llvm.convert.to.arbitrary.fp.v3i8.v3f32(<3 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <3 x i8> %r
+}
+
+; <4 x float> -> <4 x i8> Float8E4M3FN
+define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v4f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $168, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 224
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    movl $31, %ebp
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r12d
+; CHECK-NEXT:    movl %r12d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %ebx
+; CHECK-NEXT:    movl %ebx, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebx
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebx
+; CHECK-NEXT:    movl %ebx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    orl %edi, %ebx
+; CHECK-NEXT:    andl %edx, %ebx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %ebx
+; CHECK-NEXT:    xorl %r15d, %r15d
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %ebp, %eax
+; CHECK-NEXT:    movl $31, %ebp
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r13d
+; CHECK-NEXT:    movl %r13d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %r14d
+; CHECK-NEXT:    movl %r14d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %r14d
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r14d
+; CHECK-NEXT:    movl %r14d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    orl %edi, %r14d
+; CHECK-NEXT:    andl %edx, %r14d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %r15d, %r14d
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1,1]
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %ebp, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r15d
+; CHECK-NEXT:    movl %r15d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %ebp
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $15, %edx
+; CHECK-NEXT:    subl %eax, %edx
+; CHECK-NEXT:    cmpl $31, %edx
+; CHECK-NEXT:    movl $31, %eax
+; CHECK-NEXT:    cmovael %eax, %edx
+; CHECK-NEXT:    cmpl $1, %edx
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    movl %edx, %eax
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %esi
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rsi), %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    movl $1, %r9d
+; CHECK-NEXT:    shll %cl, %r9d
+; CHECK-NEXT:    decl %r9d
+; CHECK-NEXT:    movl %r9d, %ecx
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testl %ecx, %edi
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    andl %r8d, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %ecx
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebx # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r8d, %r8d
+; CHECK-NEXT:    cmpl $8, %ebx
+; CHECK-NEXT:    cmovgel %eax, %ebx
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %r9d
+; CHECK-NEXT:    shrl $24, %r9d
+; CHECK-NEXT:    andl $-128, %r9d
+; CHECK-NEXT:    leal (%r9,%r8,8), %r8d
+; CHECK-NEXT:    orl %ebx, %r8d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload
+; CHECK-NEXT:    shrl $20, %r11d
+; CHECK-NEXT:    movl %r11d, %r10d
+; CHECK-NEXT:    movq %r11, %rbx
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $524287, %r12d # imm = 0x7FFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %r10d, %r11d
+; CHECK-NEXT:    shrl $19, %r12d
+; CHECK-NEXT:    andl %r11d, %r12d
+; CHECK-NEXT:    addl %ebx, %r12d
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $8, %r12d
+; CHECK-NEXT:    cmovgel %eax, %r12d
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
+; CHECK-NEXT:    leal (%rbx,%r10), %r11d
+; CHECK-NEXT:    leal 48(,%r11,8), %r11d
+; CHECK-NEXT:    orl %r9d, %r12d
+; CHECK-NEXT:    orl %r11d, %r12d
+; CHECK-NEXT:    leal 6(%rbx,%r10), %r10d
+; CHECK-NEXT:    testl %r10d, %r10d
+; CHECK-NEXT:    cmovlel %r8d, %r12d
+; CHECK-NEXT:    xorps %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r12d, %r9d
+; CHECK-NEXT:    cmovpl %r12d, %r9d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    movl $127, %r8d
+; CHECK-NEXT:    cmovpl %r8d, %r9d
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    cmpl $8, %r14d
+; CHECK-NEXT:    cmovgel %eax, %r14d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %r10d
+; CHECK-NEXT:    shrl $24, %r10d
+; CHECK-NEXT:    andl $-128, %r10d
+; CHECK-NEXT:    leal (%r10,%r11,8), %r11d
+; CHECK-NEXT:    orl %r14d, %r11d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
+; CHECK-NEXT:    shrl $20, %r14d
+; CHECK-NEXT:    movl %r14d, %ebx
+; CHECK-NEXT:    movq %r14, %r12
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    testl $524287, %r13d # imm = 0x7FFFF
+; CHECK-NEXT:    setne %r14b
+; CHECK-NEXT:    orl %ebx, %r14d
+; CHECK-NEXT:    shrl $19, %r13d
+; CHECK-NEXT:    andl %r14d, %r13d
+; CHECK-NEXT:    addl %r12d, %r13d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $8, %r13d
+; CHECK-NEXT:    cmovgel %eax, %r13d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Reload
+; CHECK-NEXT:    leal (%r12,%rbx), %r14d
+; CHECK-NEXT:    leal 48(,%r14,8), %r14d
+; CHECK-NEXT:    orl %r10d, %r13d
+; CHECK-NEXT:    orl %r14d, %r13d
+; CHECK-NEXT:    leal 6(%r12,%rbx), %ebx
+; CHECK-NEXT:    testl %ebx, %ebx
+; CHECK-NEXT:    cmovlel %r11d, %r13d
+; CHECK-NEXT:    movzbl %r9b, %r11d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r13d, %r10d
+; CHECK-NEXT:    cmovpl %r13d, %r10d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    cmovpl %r8d, %r10d
+; CHECK-NEXT:    movzbl %r10b, %r9d
+; CHECK-NEXT:    shll $8, %r9d
+; CHECK-NEXT:    orl %r11d, %r9d
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    cmpl $8, %ebp
+; CHECK-NEXT:    cmovgel %eax, %ebp
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %r10d
+; CHECK-NEXT:    shrl $24, %r10d
+; CHECK-NEXT:    andl $-128, %r10d
+; CHECK-NEXT:    leal (%r10,%r11,8), %r11d
+; CHECK-NEXT:    orl %ebp, %r11d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
+; CHECK-NEXT:    shrl $20, %r14d
+; CHECK-NEXT:    movl %r14d, %ebx
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    testl $524287, %r15d # imm = 0x7FFFF
+; CHECK-NEXT:    setne %bpl
+; CHECK-NEXT:    orl %ebx, %ebp
+; CHECK-NEXT:    shrl $19, %r15d
+; CHECK-NEXT:    andl %ebp, %r15d
+; CHECK-NEXT:    addl %r14d, %r15d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $8, %r15d
+; CHECK-NEXT:    cmovgel %eax, %r15d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Reload
+; CHECK-NEXT:    leal (%r12,%rbx), %r14d
+; CHECK-NEXT:    leal 48(,%r14,8), %ebp
+; CHECK-NEXT:    orl %r10d, %r15d
+; CHECK-NEXT:    orl %ebp, %r15d
+; CHECK-NEXT:    leal 6(%r12,%rbx), %ebx
+; CHECK-NEXT:    testl %ebx, %ebx
+; CHECK-NEXT:    cmovlel %r11d, %r15d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %r15d, %r10d
+; CHECK-NEXT:    cmovpl %r15d, %r10d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    cmovpl %r8d, %r10d
+; CHECK-NEXT:    movzbl %r10b, %r10d
+; CHECK-NEXT:    shll $16, %r10d
+; CHECK-NEXT:    orl %r9d, %r10d
+; CHECK-NEXT:    addl %edi, %ecx
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $8, %ecx
+; CHECK-NEXT:    cmovgel %eax, %ecx
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm1, %edi
+; CHECK-NEXT:    shrl $24, %edi
+; CHECK-NEXT:    andl $-128, %edi
+; CHECK-NEXT:    leal (%rdi,%r9,8), %r9d
+; CHECK-NEXT:    orl %ecx, %r9d
+; CHECK-NEXT:    shrl $20, %esi
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $524287, %edx # imm = 0x7FFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ecx, %r11d
+; CHECK-NEXT:    shrl $19, %edx
+; CHECK-NEXT:    andl %r11d, %edx
+; CHECK-NEXT:    addl %esi, %edx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $8, %edx
+; CHECK-NEXT:    cmovgel %eax, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
+; CHECK-NEXT:    leal (%rax,%rcx), %esi
+; CHECK-NEXT:    leal 48(,%rsi,8), %esi
+; CHECK-NEXT:    orl %edi, %edx
+; CHECK-NEXT:    orl %esi, %edx
+; CHECK-NEXT:    leal 6(%rax,%rcx), %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    cmovlel %r9d, %edx
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    cmovnel %edx, %edi
+; CHECK-NEXT:    cmovpl %edx, %edi
+; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    cmovpl %r8d, %edi
+; CHECK-NEXT:    shll $24, %edi
+; CHECK-NEXT:    orl %r10d, %edi
+; CHECK-NEXT:    movd %edi, %xmm0
+; CHECK-NEXT:    addq $168, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <4 x i8> %r
+}
+
+; <4 x float> -> <4 x i8> Float8E5M2
+define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
+; CHECK-LABEL: to_f8e5m2_v4f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $168, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 224
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $8, %ebx
+; CHECK-NEXT:    movl $8, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    movl $31, %ebp
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r12d
+; CHECK-NEXT:    movl %r12d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %r15d
+; CHECK-NEXT:    movl %r15d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %r15d
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r15d
+; CHECK-NEXT:    movl %r15d, (%rsp) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r15d
+; CHECK-NEXT:    orl %edi, %r15d
+; CHECK-NEXT:    andl %edx, %r15d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    cmovbl %ecx, %r15d
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $8, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %ebp, %eax
+; CHECK-NEXT:    movl $31, %r13d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %r14d
+; CHECK-NEXT:    movl %r14d, %edx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %ebp
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1,1]
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    movl $8, %eax
+; CHECK-NEXT:    subl %ecx, %eax
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    # kill: def $edx killed $edx def $rdx
+; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 8388608(%rdx), %r13d
+; CHECK-NEXT:    movl %r13d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    movl $1, %esi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %esi
+; CHECK-NEXT:    decl %esi
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    testl %esi, %r13d
+; CHECK-NEXT:    setne %dil
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r13d
+; CHECK-NEXT:    movl %r13d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r13d
+; CHECK-NEXT:    orl %edi, %r13d
+; CHECK-NEXT:    andl %edx, %r13d
+; CHECK-NEXT:    cmpl $1, %eax
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %r13d
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    callq frexpf at PLT
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    subl %eax, %ebx
+; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    movl $31, %eax
+; CHECK-NEXT:    cmovael %eax, %ebx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
+; CHECK-NEXT:    movl %edx, %esi
+; CHECK-NEXT:    andl $8388607, %esi # imm = 0x7FFFFF
+; CHECK-NEXT:    leal 8388608(%rsi), %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    decl %eax
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testl %eax, %edi
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    movl %ebx, %ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    orl %r9d, %ecx
+; CHECK-NEXT:    andl %r8d, %ecx
+; CHECK-NEXT:    cmpl $1, %ebx
+; CHECK-NEXT:    movl $0, %eax
+; CHECK-NEXT:    cmovbl %eax, %ecx
+; CHECK-NEXT:    addl (%rsp), %r15d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $4, %r15d
+; CHECK-NEXT:    cmovgel %eax, %r15d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm2, %r8d
+; CHECK-NEXT:    shrl $24, %r8d
+; CHECK-NEXT:    andl $-128, %r8d
+; CHECK-NEXT:    leal (%r8,%r9,4), %r9d
+; CHECK-NEXT:    orl %r15d, %r9d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload
+; CHECK-NEXT:    shrl $21, %r11d
+; CHECK-NEXT:    movl %r11d, %r10d
+; CHECK-NEXT:    movq %r11, %rbx
+; CHECK-NEXT:    andl $1, %r10d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $1048575, %r12d # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %r10d, %r11d
+; CHECK-NEXT:    shrl $20, %r12d
+; CHECK-NEXT:    andl %r11d, %r12d
+; CHECK-NEXT:    addl %ebx, %r12d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    cmpl $4, %r12d
+; CHECK-NEXT:    cmovgel %eax, %r12d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload
+; CHECK-NEXT:    leal (%r15,%r11), %r10d
+; CHECK-NEXT:    leal 56(,%r10,4), %ebx
+; CHECK-NEXT:    movl %r8d, %r10d
+; CHECK-NEXT:    orl %r12d, %r10d
+; CHECK-NEXT:    orl %ebx, %r10d
+; CHECK-NEXT:    leal 14(%r15,%r11), %r11d
+; CHECK-NEXT:    testl %r11d, %r11d
+; CHECK-NEXT:    cmovlel %r9d, %r10d
+; CHECK-NEXT:    cmpl $4, %r12d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    cmpl $30, %r11d
+; CHECK-NEXT:    sete %bl
+; CHECK-NEXT:    andb %r9b, %bl
+; CHECK-NEXT:    cmpl $31, %r11d
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    orb %bl, %r9b
+; CHECK-NEXT:    testb %r9b, %r9b
+; CHECK-NEXT:    leal 124(%r8), %r9d
+; CHECK-NEXT:    cmovnel %r9d, %r10d
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm1, %xmm2
+; CHECK-NEXT:    cmovnel %r10d, %r8d
+; CHECK-NEXT:    cmovpl %r10d, %r8d
+; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    movaps %xmm2, %xmm3
+; CHECK-NEXT:    movaps %xmm2, %xmm4
+; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    movss {{.*#+}} xmm2 = [+Inf,0.0E+0,0.0E+0,0.0E+0]
+; CHECK-NEXT:    ucomiss %xmm2, %xmm3
+; CHECK-NEXT:    cmovnel %r8d, %r9d
+; CHECK-NEXT:    cmovpl %r8d, %r9d
+; CHECK-NEXT:    ucomiss %xmm4, %xmm4
+; CHECK-NEXT:    movl $126, %r8d
+; CHECK-NEXT:    cmovpl %r8d, %r9d
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    cmpl $4, %ebp
+; CHECK-NEXT:    cmovgel %eax, %ebp
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm4 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm4, %r10d
+; CHECK-NEXT:    shrl $24, %r10d
+; CHECK-NEXT:    andl $-128, %r10d
+; CHECK-NEXT:    leal (%r10,%r11,4), %r11d
+; CHECK-NEXT:    orl %ebp, %r11d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload
+; CHECK-NEXT:    shrl $21, %r15d
+; CHECK-NEXT:    movl %r15d, %ebx
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    testl $1048575, %r14d # imm = 0xFFFFF
+; CHECK-NEXT:    setne %bpl
+; CHECK-NEXT:    orl %ebx, %ebp
+; CHECK-NEXT:    shrl $20, %r14d
+; CHECK-NEXT:    andl %ebp, %r14d
+; CHECK-NEXT:    addl %r15d, %r14d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $4, %r14d
+; CHECK-NEXT:    cmovgel %eax, %r14d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Reload
+; CHECK-NEXT:    leal (%r12,%rbx), %r15d
+; CHECK-NEXT:    leal 56(,%r15,4), %ebp
+; CHECK-NEXT:    movl %r10d, %r15d
+; CHECK-NEXT:    orl %r14d, %r15d
+; CHECK-NEXT:    orl %ebp, %r15d
+; CHECK-NEXT:    leal 14(%r12,%rbx), %ebx
+; CHECK-NEXT:    testl %ebx, %ebx
+; CHECK-NEXT:    cmovlel %r11d, %r15d
+; CHECK-NEXT:    cmpl $4, %r14d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    cmpl $30, %ebx
+; CHECK-NEXT:    sete %bpl
+; CHECK-NEXT:    andb %r11b, %bpl
+; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    orb %bpl, %r11b
+; CHECK-NEXT:    testb %r11b, %r11b
+; CHECK-NEXT:    leal 124(%r10), %r11d
+; CHECK-NEXT:    cmovnel %r11d, %r15d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm4
+; CHECK-NEXT:    cmovnel %r15d, %r10d
+; CHECK-NEXT:    cmovpl %r15d, %r10d
+; CHECK-NEXT:    movzbl %r9b, %ebx
+; CHECK-NEXT:    movaps %xmm4, %xmm3
+; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    ucomiss %xmm2, %xmm3
+; CHECK-NEXT:    cmovnel %r10d, %r11d
+; CHECK-NEXT:    cmovpl %r10d, %r11d
+; CHECK-NEXT:    ucomiss %xmm4, %xmm4
+; CHECK-NEXT:    cmovpl %r8d, %r11d
+; CHECK-NEXT:    movzbl %r11b, %r9d
+; CHECK-NEXT:    shll $8, %r9d
+; CHECK-NEXT:    orl %ebx, %r9d
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r13d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    cmpl $4, %r13d
+; CHECK-NEXT:    cmovgel %eax, %r13d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm4 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm4, %r10d
+; CHECK-NEXT:    shrl $24, %r10d
+; CHECK-NEXT:    andl $-128, %r10d
+; CHECK-NEXT:    leal (%r10,%r11,4), %r11d
+; CHECK-NEXT:    orl %r13d, %r11d
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
+; CHECK-NEXT:    shrl $21, %r14d
+; CHECK-NEXT:    movl %r14d, %ebx
+; CHECK-NEXT:    movq %r14, %r15
+; CHECK-NEXT:    andl $1, %ebx
+; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Reload
+; CHECK-NEXT:    testl $1048575, %r14d # imm = 0xFFFFF
+; CHECK-NEXT:    setne %bpl
+; CHECK-NEXT:    orl %ebx, %ebp
+; CHECK-NEXT:    shrl $20, %r14d
+; CHECK-NEXT:    andl %ebp, %r14d
+; CHECK-NEXT:    addl %r15d, %r14d
+; CHECK-NEXT:    xorl %ebx, %ebx
+; CHECK-NEXT:    cmpl $4, %r14d
+; CHECK-NEXT:    cmovgel %eax, %r14d
+; CHECK-NEXT:    movl %r14d, %r12d
+; CHECK-NEXT:    setge %bl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload
+; CHECK-NEXT:    leal (%r15,%rbx), %r14d
+; CHECK-NEXT:    leal 56(,%r14,4), %ebp
+; CHECK-NEXT:    movl %r10d, %r14d
+; CHECK-NEXT:    orl %r12d, %r14d
+; CHECK-NEXT:    orl %ebp, %r14d
+; CHECK-NEXT:    leal 14(%r15,%rbx), %ebx
+; CHECK-NEXT:    testl %ebx, %ebx
+; CHECK-NEXT:    cmovlel %r11d, %r14d
+; CHECK-NEXT:    cmpl $4, %r12d
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    cmpl $30, %ebx
+; CHECK-NEXT:    sete %bpl
+; CHECK-NEXT:    andb %r11b, %bpl
+; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    orb %bpl, %r11b
+; CHECK-NEXT:    testb %r11b, %r11b
+; CHECK-NEXT:    leal 124(%r10), %r11d
+; CHECK-NEXT:    cmovnel %r11d, %r14d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm4
+; CHECK-NEXT:    cmovnel %r14d, %r10d
+; CHECK-NEXT:    cmovpl %r14d, %r10d
+; CHECK-NEXT:    movaps %xmm4, %xmm3
+; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    ucomiss %xmm2, %xmm3
+; CHECK-NEXT:    cmovnel %r10d, %r11d
+; CHECK-NEXT:    cmovpl %r10d, %r11d
+; CHECK-NEXT:    ucomiss %xmm4, %xmm4
+; CHECK-NEXT:    cmovpl %r8d, %r11d
+; CHECK-NEXT:    movzbl %r11b, %r10d
+; CHECK-NEXT:    shll $16, %r10d
+; CHECK-NEXT:    orl %r9d, %r10d
+; CHECK-NEXT:    addl %edi, %ecx
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    cmpl $4, %ecx
+; CHECK-NEXT:    cmovgel %eax, %ecx
+; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm3, %edi
+; CHECK-NEXT:    shrl $24, %edi
+; CHECK-NEXT:    andl $-128, %edi
+; CHECK-NEXT:    leal (%rdi,%r9,4), %r9d
+; CHECK-NEXT:    orl %ecx, %r9d
+; CHECK-NEXT:    shrl $21, %esi
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testl $1048575, %edx # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    orl %ecx, %r11d
+; CHECK-NEXT:    shrl $20, %edx
+; CHECK-NEXT:    andl %r11d, %edx
+; CHECK-NEXT:    addl %esi, %edx
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    cmovgel %eax, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
+; CHECK-NEXT:    leal (%rax,%rcx), %esi
+; CHECK-NEXT:    leal 56(,%rsi,4), %esi
+; CHECK-NEXT:    movl %edi, %r11d
+; CHECK-NEXT:    orl %edx, %r11d
+; CHECK-NEXT:    orl %esi, %r11d
+; CHECK-NEXT:    leal 14(%rax,%rcx), %eax
+; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    cmovlel %r9d, %r11d
+; CHECK-NEXT:    cmpl $4, %edx
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    cmpl $30, %eax
+; CHECK-NEXT:    sete %dl
+; CHECK-NEXT:    andb %cl, %dl
+; CHECK-NEXT:    cmpl $31, %eax
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    orb %dl, %al
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    leal 124(%rdi), %eax
+; CHECK-NEXT:    cmovnel %eax, %r11d
+; CHECK-NEXT:    ucomiss %xmm1, %xmm3
+; CHECK-NEXT:    cmovnel %r11d, %edi
+; CHECK-NEXT:    cmovpl %r11d, %edi
+; CHECK-NEXT:    andps %xmm3, %xmm0
+; CHECK-NEXT:    ucomiss %xmm2, %xmm0
+; CHECK-NEXT:    cmovnel %edi, %eax
+; CHECK-NEXT:    cmovpl %edi, %eax
+; CHECK-NEXT:    ucomiss %xmm3, %xmm3
+; CHECK-NEXT:    cmovpl %r8d, %eax
+; CHECK-NEXT:    shll $24, %eax
+; CHECK-NEXT:    orl %r10d, %eax
+; CHECK-NEXT:    movd %eax, %xmm0
+; CHECK-NEXT:    addq $168, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <4 x i8> @llvm.convert.to.arbitrary.fp.v4i8.v4f32(<4 x float> %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
+  ret <4 x i8> %r
+}
+
+; <2 x half> -> <2 x i8> Float8E4M3FN
+define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) {
+; CHECK-LABEL: to_f8e4m3fn_v2f16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    pushq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    pushq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    pushq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    pushq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    subq $72, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 128
+; CHECK-NEXT:    .cfi_offset %rbx, -56
+; CHECK-NEXT:    .cfi_offset %r12, -48
+; CHECK-NEXT:    .cfi_offset %r13, -40
+; CHECK-NEXT:    .cfi_offset %r14, -32
+; CHECK-NEXT:    .cfi_offset %r15, -24
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    callq __truncsfhf2 at PLT
+; CHECK-NEXT:    pextrw $0, %xmm0, %r12d
+; CHECK-NEXT:    movl %r12d, %eax
+; CHECK-NEXT:    andl $31744, %eax # imm = 0x7C00
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    pextrw $0, %xmm0, %r15d
+; CHECK-NEXT:    movl %r15d, %ecx
+; CHECK-NEXT:    andl $32767, %ecx # imm = 0x7FFF
+; CHECK-NEXT:    cmpl $1024, %ecx # imm = 0x400
+; CHECK-NEXT:    cmovael %r15d, %r12d
+; CHECK-NEXT:    cmovael %ecx, %eax
+; CHECK-NEXT:    shrl $10, %eax
+; CHECK-NEXT:    leal -12(%rax), %edx
+; CHECK-NEXT:    cmpl $1024, %ecx # imm = 0x400
+; CHECK-NEXT:    psrld $16, %xmm0
+; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    cmovael %eax, %edx
+; CHECK-NEXT:    addl $-14, %edx
+; CHECK-NEXT:    andl $33791, %r12d # imm = 0x83FF
+; CHECK-NEXT:    orl $14336, %r12d # imm = 0x3800
+; CHECK-NEXT:    addl $-31744, %ecx # imm = 0x8400
+; CHECK-NEXT:    movzwl %cx, %eax
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpl $33792, %eax # imm = 0x8400
+; CHECK-NEXT:    cmovbel %ecx, %edx
+; CHECK-NEXT:    movq %rdx, %r14
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    cmovbel %r15d, %r12d
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    callq __truncsfhf2 at PLT
+; CHECK-NEXT:    pextrw $0, %xmm0, %ebp
+; CHECK-NEXT:    movl %ebp, %eax
+; CHECK-NEXT:    andl $31744, %eax # imm = 0x7C00
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    pextrw $0, %xmm0, %ebx
+; CHECK-NEXT:    movl %ebx, %r9d
+; CHECK-NEXT:    andl $32767, %r9d # imm = 0x7FFF
+; CHECK-NEXT:    cmpl $1024, %r9d # imm = 0x400
+; CHECK-NEXT:    cmovael %ebx, %ebp
+; CHECK-NEXT:    cmovael %r9d, %eax
+; CHECK-NEXT:    shrl $10, %eax
+; CHECK-NEXT:    leal -12(%rax), %esi
+; CHECK-NEXT:    cmpl $1024, %r9d # imm = 0x400
+; CHECK-NEXT:    cmovael %eax, %esi
+; CHECK-NEXT:    movl $2, %eax
+; CHECK-NEXT:    movl $2, %edx
+; CHECK-NEXT:    subl %r14d, %edx
+; CHECK-NEXT:    cmpw $15, %dx
+; CHECK-NEXT:    movl $15, %r13d
+; CHECK-NEXT:    cmovael %r13d, %edx
+; CHECK-NEXT:    cmpw $1, %dx
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movl %r12d, %r10d
+; CHECK-NEXT:    andl $1023, %r10d # imm = 0x3FF
+; CHECK-NEXT:    leal 1024(%r10), %edi
+; CHECK-NEXT:    movl %edi, %r14d
+; CHECK-NEXT:    shrl %cl, %r14d
+; CHECK-NEXT:    movl $1, %r8d
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r8d
+; CHECK-NEXT:    decl %r8d
+; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    testw %r8w, %di
+; CHECK-NEXT:    setne %r11b
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    movl %edi, %r8d
+; CHECK-NEXT:    andl $1, %r8d
+; CHECK-NEXT:    orl %r11d, %r8d
+; CHECK-NEXT:    movl $1, %r11d
+; CHECK-NEXT:    andl %r14d, %r8d
+; CHECK-NEXT:    cmpw $1, %dx
+; CHECK-NEXT:    movl $0, %edx
+; CHECK-NEXT:    cmovbl %edx, %r8d
+; CHECK-NEXT:    addl $-14, %esi
+; CHECK-NEXT:    andl $33791, %ebp # imm = 0x83FF
+; CHECK-NEXT:    orl $14336, %ebp # imm = 0x3800
+; CHECK-NEXT:    addl $-31744, %r9d # imm = 0x8400
+; CHECK-NEXT:    movzwl %r9w, %ecx
+; CHECK-NEXT:    cmpl $33792, %ecx # imm = 0x8400
+; CHECK-NEXT:    cmovbel %edx, %esi
+; CHECK-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    cmovbel %ebx, %ebp
+; CHECK-NEXT:    subl %esi, %eax
+; CHECK-NEXT:    cmpw $15, %ax
+; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    cmpw $1, %ax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    adcl $-1, %ecx
+; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    andl $1023, %edx # imm = 0x3FF
+; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-NEXT:    leal 1024(%rdx), %r13d
+; CHECK-NEXT:    movl %r13d, %edx
+; CHECK-NEXT:    shrl %cl, %edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %r11d
+; CHECK-NEXT:    decl %r11d
+; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    testw %r11w, %r13w
+; CHECK-NEXT:    setne %r9b
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r13d
+; CHECK-NEXT:    movl %r13d, %r14d
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    orl %r9d, %r14d
+; CHECK-NEXT:    andl %edx, %r14d
+; CHECK-NEXT:    cmpw $1, %ax
+; CHECK-NEXT:    movl $0, %ecx
+; CHECK-NEXT:    cmovbl %ecx, %r14d
+; CHECK-NEXT:    addl %edi, %r8d
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpw $8, %r8w
+; CHECK-NEXT:    cmovgel %ecx, %r8d
+; CHECK-NEXT:    movl $0, %esi
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    shrl $8, %r15d
+; CHECK-NEXT:    andl $128, %r15d
+; CHECK-NEXT:    leal (%r15,%rax,8), %eax
+; CHECK-NEXT:    orl %r8d, %eax
+; CHECK-NEXT:    shrl $7, %r10d
+; CHECK-NEXT:    movl %r10d, %ecx
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    testb $63, %r12b
+; CHECK-NEXT:    setne %dl
+; CHECK-NEXT:    orl %ecx, %edx
+; CHECK-NEXT:    shrl $6, %r12d
+; CHECK-NEXT:    andl %edx, %r12d
+; CHECK-NEXT:    addl %r10d, %r12d
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpw $8, %r12w
+; CHECK-NEXT:    cmovgel %esi, %r12d
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload
+; CHECK-NEXT:    leal (%rsi,%rcx), %edx
+; CHECK-NEXT:    leal 48(,%rdx,8), %edx
+; CHECK-NEXT:    orl %r15d, %r12d
+; CHECK-NEXT:    orl %edx, %r12d
+; CHECK-NEXT:    leal 6(%rsi,%rcx), %ecx
+; CHECK-NEXT:    testw %cx, %cx
+; CHECK-NEXT:    cmovlel %eax, %r12d
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm1, %xmm0
+; CHECK-NEXT:    cmovnel %r12d, %r15d
+; CHECK-NEXT:    cmovpl %r12d, %r15d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm0
+; CHECK-NEXT:    movl $127, %r12d
+; CHECK-NEXT:    cmovpl %r12d, %r15d
+; CHECK-NEXT:    movzbl %r15b, %r15d
+; CHECK-NEXT:    addl %r13d, %r14d
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    cmpw $8, %r14w
+; CHECK-NEXT:    movl $0, %edi
+; CHECK-NEXT:    cmovgel %edi, %r14d
+; CHECK-NEXT:    setge %al
+; CHECK-NEXT:    shrl $8, %ebx
+; CHECK-NEXT:    andl $128, %ebx
+; CHECK-NEXT:    leal (%rbx,%rax,8), %eax
+; CHECK-NEXT:    orl %r14d, %eax
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
+; CHECK-NEXT:    shrl $7, %edx
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    movq %rdx, %rsi
+; CHECK-NEXT:    andl $1, %ecx
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    testb $63, %bpl
+; CHECK-NEXT:    setne %dl
+; CHECK-NEXT:    orl %ecx, %edx
+; CHECK-NEXT:    shrl $6, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    addl %esi, %ebp
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    cmpw $8, %bp
+; CHECK-NEXT:    cmovgel %edi, %ebp
+; CHECK-NEXT:    setge %cl
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload
+; CHECK-NEXT:    leal (%rsi,%rcx), %edx
+; CHECK-NEXT:    leal 48(,%rdx,8), %edx
+; CHECK-NEXT:    orl %ebx, %ebp
+; CHECK-NEXT:    orl %edx, %ebp
+; CHECK-NEXT:    leal 6(%rsi,%rcx), %ecx
+; CHECK-NEXT:    testw %cx, %cx
+; CHECK-NEXT:    cmovlel %eax, %ebp
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; CHECK-NEXT:    callq __extendhfsf2 at PLT
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm1, %xmm0
+; CHECK-NEXT:    cmovnel %ebp, %ebx
+; CHECK-NEXT:    cmovpl %ebp, %ebx
+; CHECK-NEXT:    ucomiss %xmm0, %xmm0
+; CHECK-NEXT:    cmovpl %r12d, %ebx
+; CHECK-NEXT:    shll $8, %ebx
+; CHECK-NEXT:    orl %r15d, %ebx
+; CHECK-NEXT:    movd %ebx, %xmm0
+; CHECK-NEXT:    addq $72, %rsp
+; CHECK-NEXT:    .cfi_def_cfa_offset 56
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-NEXT:    popq %r12
+; CHECK-NEXT:    .cfi_def_cfa_offset 40
+; CHECK-NEXT:    popq %r13
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    popq %r14
+; CHECK-NEXT:    .cfi_def_cfa_offset 24
+; CHECK-NEXT:    popq %r15
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+  %r = call <2 x i8> @llvm.convert.to.arbitrary.fp.v2i8.v2f16(<2 x half> %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
+  ret <2 x i8> %r
+}
+
 ; Different source types
 
 ; f16 -> i8 (Float8E5M2)

>From f719ae1ef6bdf72fc9a5b46fe5241e3bb4adf931 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Tue, 26 May 2026 19:18:12 +0200
Subject: [PATCH 8/9] wip

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  32 +-
 .../test/CodeGen/X86/float-to-arbitrary-fp.ll | 534 +++++++++---------
 2 files changed, 274 insertions(+), 292 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index b9f334191c430..53cfd3da1782e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -9117,8 +9117,6 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
       DstNanEnc == fltNanEncoding::AllOnes)
     DstMaxMantAtMaxExp = DstMantMask - 1;
 
-  // FIXME: ConstantFP inputs may not fully fold through this expansion.
-
   // Source format parameters.
   EVT SrcVT = FloatVal.getValueType();
   const fltSemantics &SrcSem = SrcVT.getScalarType().getFltSemantics();
@@ -9152,7 +9150,7 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
   SDValue FPZero = DAG.getConstantFP(0.0, dl, SrcVT);
   SDValue FPInf = DAG.getConstantFP(APFloat::getInf(SrcSem), dl, SrcVT);
   SDValue AbsVal = DAG.getNode(ISD::FABS, dl, SrcVT, FloatVal);
-  SDValue IsNaN = DAG.getSetCC(dl, FPSetCCVT, FloatVal, FloatVal, ISD::SETUO);
+  SDValue IsNaN = DAG.getSetCC(dl, FPSetCCVT, FloatVal, FPZero, ISD::SETUO);
   SDValue IsInf = DAG.getSetCC(dl, FPSetCCVT, AbsVal, FPInf, ISD::SETOEQ);
   SDValue IsZero = DAG.getSetCC(dl, FPSetCCVT, FloatVal, FPZero, ISD::SETOEQ);
 
@@ -9161,10 +9159,7 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
   // those inputs are detected above and override the final result.
   EVT FrexpExpScalarVT =
       getValueType(DAG.getDataLayout(), Type::getInt32Ty(*DAG.getContext()));
-  EVT FrexpExpVT = SrcVT.isVector()
-                       ? EVT::getVectorVT(*DAG.getContext(), FrexpExpScalarVT,
-                                          SrcVT.getVectorElementCount())
-                       : FrexpExpScalarVT;
+  EVT FrexpExpVT = SrcVT.changeElementType(*DAG.getContext(), FrexpExpScalarVT);
   SDValue Frexp =
       DAG.getNode(ISD::FFREXP, dl, DAG.getVTList(SrcVT, FrexpExpVT), FloatVal);
   SDValue FrexpFrac = Frexp.getValue(0);
@@ -9228,11 +9223,10 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
     // Check bit at position Shift - 1 aka the round bit.
     SDValue RoundBit;
     if (Shift >= 1) {
-      RoundBit = DAG.getNode(
-          ISD::AND, dl, IntVT,
-          DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant,
-                      DAG.getShiftAmountConstant(Shift - 1, IntVT, dl)),
-          One);
+      SDValue RoundBitShift = DAG.getShiftAmountConstant(Shift - 1, IntVT, dl);
+      SDValue ShiftedMant =
+          DAG.getNode(ISD::SRL, dl, IntVT, EffSrcMant, RoundBitShift);
+      RoundBit = DAG.getNode(ISD::AND, dl, IntVT, ShiftedMant, One);
     } else {
       RoundBit = Zero;
     }
@@ -9298,15 +9292,11 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
     SDValue FullSrcMant =
         DAG.getNode(ISD::OR, dl, IntVT, EffSrcMant, ImplicitOne);
 
-    // Total right shift = (SrcMant - DstMant) + DenormShift
-    SDValue TotalShift;
-    if (SrcMant >= DstMant) {
-      TotalShift = DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
-                               DAG.getConstant(SrcMant - DstMant, dl, IntVT));
-    } else {
-      TotalShift = DAG.getNode(ISD::SUB, dl, IntVT, DenormShift,
-                               DAG.getConstant(DstMant - SrcMant, dl, IntVT));
-    }
+    // Total right shift = DenormShift + (SrcMant - DstMant).
+    int64_t MantDelta = static_cast<int64_t>(SrcMant) - DstMant;
+    SDValue TotalShift =
+        DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
+                    DAG.getSignedConstant(MantDelta, dl, IntVT));
 
     // Clamp total shift to avoid UB, then trancate denorm mantissa.
     SDValue MaxShift = DAG.getConstant(SrcBits - 1, dl, IntVT);
diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
index 41d9b6ffc9856..1cdccaf110d30 100644
--- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
+++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll
@@ -65,8 +65,8 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-NEXT:    cmpl $4, %r10d
 ; CHECK-NEXT:    cmovgel %ecx, %r10d
 ; CHECK-NEXT:    setge %r8b
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm2, %eax
 ; CHECK-NEXT:    shrl $24, %eax
 ; CHECK-NEXT:    andl $-128, %eax
 ; CHECK-NEXT:    leal (%rax,%r8,4), %r8d
@@ -105,15 +105,15 @@ define i8 @to_f8e5m2_dynamic(float %x) {
 ; CHECK-NEXT:    testb %cl, %cl
 ; CHECK-NEXT:    cmovnel %edx, %r9d
 ; CHECK-NEXT:    pxor %xmm0, %xmm0
-; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
 ; CHECK-NEXT:    cmovnel %r9d, %eax
 ; CHECK-NEXT:    cmovpl %r9d, %eax
-; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
-; CHECK-NEXT:    andps %xmm1, %xmm0
-; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    andps %xmm2, %xmm1
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
 ; CHECK-NEXT:    cmovnel %eax, %edx
 ; CHECK-NEXT:    cmovpl %eax, %edx
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
 ; CHECK-NEXT:    movl $126, %eax
 ; CHECK-NEXT:    cmovnpl %edx, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
@@ -151,8 +151,8 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-NEXT:    cmpl $4, %edi
 ; CHECK-NEXT:    cmovgel %ecx, %edi
 ; CHECK-NEXT:    setge %r8b
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
+; CHECK-NEXT:    movd %xmm2, %eax
 ; CHECK-NEXT:    shrl $24, %eax
 ; CHECK-NEXT:    andl $-128, %eax
 ; CHECK-NEXT:    leal (%rax,%r8,4), %r8d
@@ -181,15 +181,15 @@ define i8 @to_f8e5m2_round_towardzero(float %x) {
 ; CHECK-NEXT:    testb %dl, %dl
 ; CHECK-NEXT:    cmovnel %esi, %ecx
 ; CHECK-NEXT:    pxor %xmm0, %xmm0
-; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
 ; CHECK-NEXT:    cmovnel %ecx, %eax
 ; CHECK-NEXT:    cmovpl %ecx, %eax
-; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
-; CHECK-NEXT:    andps %xmm1, %xmm0
-; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    andps %xmm2, %xmm1
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
 ; CHECK-NEXT:    cmovnel %eax, %esi
 ; CHECK-NEXT:    cmovpl %eax, %esi
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
 ; CHECK-NEXT:    movl $126, %eax
 ; CHECK-NEXT:    cmovnpl %esi, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
@@ -371,10 +371,12 @@ define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    .cfi_offset %r14, -32
 ; CHECK-NEXT:    .cfi_offset %r15, -24
 ; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; CHECK-NEXT:    movq %rsp, %rdi
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl (%rsp), %ecx
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
 ; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
 ; CHECK-NEXT:    movl $8, %ebx
 ; CHECK-NEXT:    movl $8, %eax
@@ -408,12 +410,10 @@ define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    cmovbl %ecx, %r13d
-; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    movq %rsp, %rdi
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    callq frexpf at PLT
-; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT:    movl (%rsp), %eax
 ; CHECK-NEXT:    subl %eax, %ebx
 ; CHECK-NEXT:    cmpl $31, %ebx
 ; CHECK-NEXT:    movl $31, %ecx
@@ -440,20 +440,20 @@ define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    orl %r9d, %ecx
 ; CHECK-NEXT:    andl %r8d, %ecx
 ; CHECK-NEXT:    cmpl $1, %ebx
-; CHECK-NEXT:    movl $0, %r8d
-; CHECK-NEXT:    cmovbl %r8d, %ecx
+; CHECK-NEXT:    movl $0, %r9d
+; CHECK-NEXT:    cmovbl %r9d, %ecx
 ; CHECK-NEXT:    addl %ebp, %r13d
-; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    xorl %r8d, %r8d
 ; CHECK-NEXT:    cmpl $4, %r13d
-; CHECK-NEXT:    cmovgel %r8d, %r13d
+; CHECK-NEXT:    cmovgel %r9d, %r13d
 ; CHECK-NEXT:    movl $0, %ebp
-; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    setge %r8b
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm2, %r8d
-; CHECK-NEXT:    shrl $24, %r8d
-; CHECK-NEXT:    andl $-128, %r8d
-; CHECK-NEXT:    leal (%r8,%r9,4), %r9d
-; CHECK-NEXT:    orl %r13d, %r9d
+; CHECK-NEXT:    movd %xmm2, %r9d
+; CHECK-NEXT:    shrl $24, %r9d
+; CHECK-NEXT:    andl $-128, %r9d
+; CHECK-NEXT:    leal (%r9,%r8,4), %r8d
+; CHECK-NEXT:    orl %r13d, %r8d
 ; CHECK-NEXT:    shrl $21, %r12d
 ; CHECK-NEXT:    movl %r12d, %r10d
 ; CHECK-NEXT:    andl $1, %r10d
@@ -471,39 +471,38 @@ define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
 ; CHECK-NEXT:    leal (%r14,%r10), %r11d
 ; CHECK-NEXT:    leal 56(,%r11,4), %r11d
-; CHECK-NEXT:    movl %r8d, %ebx
+; CHECK-NEXT:    movl %r9d, %ebx
 ; CHECK-NEXT:    orl %r15d, %ebx
 ; CHECK-NEXT:    orl %r11d, %ebx
 ; CHECK-NEXT:    leal 14(%r14,%r10), %r10d
 ; CHECK-NEXT:    testl %r10d, %r10d
-; CHECK-NEXT:    cmovlel %r9d, %ebx
+; CHECK-NEXT:    cmovlel %r8d, %ebx
 ; CHECK-NEXT:    cmpl $4, %r15d
-; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    setge %r8b
 ; CHECK-NEXT:    cmpl $30, %r10d
 ; CHECK-NEXT:    sete %r11b
-; CHECK-NEXT:    andb %r9b, %r11b
+; CHECK-NEXT:    andb %r8b, %r11b
 ; CHECK-NEXT:    cmpl $31, %r10d
-; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    orb %r11b, %r9b
-; CHECK-NEXT:    leal 124(%r8), %r10d
-; CHECK-NEXT:    testb %r9b, %r9b
-; CHECK-NEXT:    cmovnel %r10d, %ebx
-; CHECK-NEXT:    xorps %xmm1, %xmm1
-; CHECK-NEXT:    ucomiss %xmm1, %xmm2
-; CHECK-NEXT:    cmovnel %ebx, %r8d
-; CHECK-NEXT:    cmovpl %ebx, %r8d
-; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    orb %r11b, %r10b
+; CHECK-NEXT:    leal 124(%r9), %r8d
+; CHECK-NEXT:    testb %r10b, %r10b
+; CHECK-NEXT:    cmovnel %r8d, %ebx
+; CHECK-NEXT:    pxor %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
+; CHECK-NEXT:    cmovnel %ebx, %r9d
+; CHECK-NEXT:    cmovpl %ebx, %r9d
+; CHECK-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
 ; CHECK-NEXT:    movaps %xmm2, %xmm3
 ; CHECK-NEXT:    movaps %xmm2, %xmm4
-; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    andps %xmm1, %xmm3
 ; CHECK-NEXT:    movss {{.*#+}} xmm2 = [+Inf,0.0E+0,0.0E+0,0.0E+0]
 ; CHECK-NEXT:    ucomiss %xmm2, %xmm3
-; CHECK-NEXT:    cmovnel %r8d, %r10d
-; CHECK-NEXT:    cmovpl %r8d, %r10d
-; CHECK-NEXT:    ucomiss %xmm4, %xmm4
-; CHECK-NEXT:    movl $126, %r8d
-; CHECK-NEXT:    cmovpl %r8d, %r10d
-; CHECK-NEXT:    movzbl %r10b, %r9d
+; CHECK-NEXT:    cmovnel %r9d, %r8d
+; CHECK-NEXT:    cmovpl %r9d, %r8d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm4
+; CHECK-NEXT:    movl $126, %r9d
+; CHECK-NEXT:    cmovpl %r9d, %r8d
 ; CHECK-NEXT:    addl %edi, %ecx
 ; CHECK-NEXT:    xorl %r10d, %r10d
 ; CHECK-NEXT:    cmpl $4, %ecx
@@ -548,18 +547,19 @@ define <2 x i8> @to_f8e5m2_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    leal 124(%rdi), %ecx
 ; CHECK-NEXT:    testb %al, %al
 ; CHECK-NEXT:    cmovnel %ecx, %r11d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm3
+; CHECK-NEXT:    ucomiss %xmm0, %xmm3
 ; CHECK-NEXT:    cmovnel %r11d, %edi
 ; CHECK-NEXT:    cmovpl %r11d, %edi
-; CHECK-NEXT:    andps %xmm3, %xmm0
-; CHECK-NEXT:    ucomiss %xmm2, %xmm0
+; CHECK-NEXT:    andps %xmm3, %xmm1
+; CHECK-NEXT:    ucomiss %xmm2, %xmm1
 ; CHECK-NEXT:    cmovnel %edi, %ecx
 ; CHECK-NEXT:    cmovpl %edi, %ecx
-; CHECK-NEXT:    ucomiss %xmm3, %xmm3
-; CHECK-NEXT:    cmovpl %r8d, %ecx
-; CHECK-NEXT:    shll $8, %ecx
-; CHECK-NEXT:    orl %r9d, %ecx
-; CHECK-NEXT:    movd %ecx, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm3
+; CHECK-NEXT:    cmovpl %r9d, %ecx
+; CHECK-NEXT:    movzbl %cl, %eax
+; CHECK-NEXT:    shll $8, %r8d
+; CHECK-NEXT:    orl %eax, %r8d
+; CHECK-NEXT:    movd %r8d, %xmm0
 ; CHECK-NEXT:    addq $56, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 56
 ; CHECK-NEXT:    popq %rbx
@@ -712,7 +712,6 @@ define <2 x i8> @to_f8e4m3fn_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %r15d, %r9d
 ; CHECK-NEXT:    cmovpl %r15d, %r9d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    movl $127, %r8d
 ; CHECK-NEXT:    cmovpl %r8d, %r9d
 ; CHECK-NEXT:    movzbl %r9b, %r9d
@@ -751,7 +750,6 @@ define <2 x i8> @to_f8e4m3fn_v2f32(<2 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %edx, %edi
 ; CHECK-NEXT:    cmovpl %edx, %edi
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    cmovpl %r8d, %edi
 ; CHECK-NEXT:    shll $8, %edi
 ; CHECK-NEXT:    orl %r9d, %edi
@@ -818,25 +816,25 @@ define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
 ; CHECK-NEXT:    movl %r13d, %edx
 ; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
 ; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    leal 8388608(%rdx), %r14d
-; CHECK-NEXT:    movl %r14d, %edx
+; CHECK-NEXT:    leal 8388608(%rdx), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
 ; CHECK-NEXT:    shrl %cl, %edx
 ; CHECK-NEXT:    movl $1, %esi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    shll %cl, %esi
 ; CHECK-NEXT:    decl %esi
 ; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %r14d
+; CHECK-NEXT:    testl %esi, %ebp
 ; CHECK-NEXT:    setne %dil
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r14d
-; CHECK-NEXT:    movl %r14d, %ebp
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    orl %edi, %ebp
-; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, %r14d
+; CHECK-NEXT:    andl $1, %r14d
+; CHECK-NEXT:    orl %edi, %r14d
+; CHECK-NEXT:    andl %edx, %r14d
 ; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    cmovbl %ecx, %ebp
+; CHECK-NEXT:    cmovbl %ecx, %r14d
 ; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
 ; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
@@ -910,18 +908,18 @@ define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
 ; CHECK-NEXT:    cmpl $1, %ebx
 ; CHECK-NEXT:    movl $0, %eax
 ; CHECK-NEXT:    cmovbl %eax, %r10d
-; CHECK-NEXT:    addl %r14d, %ebp
+; CHECK-NEXT:    addl %ebp, %r14d
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    cmpl $8, %ebp
-; CHECK-NEXT:    cmovgel %eax, %ebp
-; CHECK-NEXT:    movl $0, %r14d
+; CHECK-NEXT:    cmpl $8, %r14d
+; CHECK-NEXT:    cmovgel %eax, %r14d
+; CHECK-NEXT:    movl $0, %ebp
 ; CHECK-NEXT:    setge %cl
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; CHECK-NEXT:    movd %xmm1, %eax
 ; CHECK-NEXT:    shrl $24, %eax
 ; CHECK-NEXT:    andl $-128, %eax
 ; CHECK-NEXT:    leal (%rax,%rcx,8), %ecx
-; CHECK-NEXT:    orl %ebp, %ecx
+; CHECK-NEXT:    orl %r14d, %ecx
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload
 ; CHECK-NEXT:    shrl $20, %r11d
 ; CHECK-NEXT:    movl %r11d, %edx
@@ -936,7 +934,7 @@ define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
 ; CHECK-NEXT:    addl %ebx, %r13d
 ; CHECK-NEXT:    xorl %edx, %edx
 ; CHECK-NEXT:    cmpl $8, %r13d
-; CHECK-NEXT:    cmovgel %r14d, %r13d
+; CHECK-NEXT:    cmovgel %ebp, %r13d
 ; CHECK-NEXT:    setge %dl
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload
 ; CHECK-NEXT:    leal (%rbx,%rdx), %r11d
@@ -950,7 +948,6 @@ define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %r13d, %eax
 ; CHECK-NEXT:    cmovpl %r13d, %eax
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    movl $127, %r11d
 ; CHECK-NEXT:    cmovpl %r11d, %eax
 ; CHECK-NEXT:    addl (%rsp), %r12d # 4-byte Folded Reload
@@ -991,7 +988,6 @@ define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %r15d, %edx
 ; CHECK-NEXT:    cmovpl %r15d, %edx
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    cmovpl %r11d, %edx
 ; CHECK-NEXT:    addl %r9d, %r10d
 ; CHECK-NEXT:    xorl %r9d, %r9d
@@ -1028,7 +1024,6 @@ define <3 x i8> @to_f8e4m3fn_v3f32(<3 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %edi, %ecx
 ; CHECK-NEXT:    cmovpl %edi, %ecx
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    cmovpl %r11d, %ecx
 ; CHECK-NEXT:    # kill: def $al killed $al killed $rax
 ; CHECK-NEXT:    # kill: def $dl killed $dl killed $rdx
@@ -1266,7 +1261,6 @@ define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %r12d, %r9d
 ; CHECK-NEXT:    cmovpl %r12d, %r9d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    movl $127, %r8d
 ; CHECK-NEXT:    cmovpl %r8d, %r9d
 ; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Folded Reload
@@ -1308,7 +1302,6 @@ define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %r13d, %r10d
 ; CHECK-NEXT:    cmovpl %r13d, %r10d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    cmovpl %r8d, %r10d
 ; CHECK-NEXT:    movzbl %r10b, %r9d
 ; CHECK-NEXT:    shll $8, %r9d
@@ -1350,7 +1343,6 @@ define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %r15d, %r10d
 ; CHECK-NEXT:    cmovpl %r15d, %r10d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    cmovpl %r8d, %r10d
 ; CHECK-NEXT:    movzbl %r10b, %r10d
 ; CHECK-NEXT:    shll $16, %r10d
@@ -1391,7 +1383,6 @@ define <4 x i8> @to_f8e4m3fn_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    cmovnel %edx, %edi
 ; CHECK-NEXT:    cmovpl %edx, %edi
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
 ; CHECK-NEXT:    cmovpl %r8d, %edi
 ; CHECK-NEXT:    shll $24, %edi
 ; CHECK-NEXT:    orl %r10d, %edi
@@ -1439,7 +1430,9 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    .cfi_offset %r14, -32
 ; CHECK-NEXT:    .cfi_offset %r15, -24
 ; CHECK-NEXT:    .cfi_offset %rbp, -16
-; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
 ; CHECK-NEXT:    callq frexpf at PLT
 ; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
@@ -1450,7 +1443,7 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    cmpl $31, %eax
 ; CHECK-NEXT:    movl $31, %ecx
 ; CHECK-NEXT:    cmovael %ecx, %eax
-; CHECK-NEXT:    movl $31, %ebp
+; CHECK-NEXT:    movl $31, %r14d
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
@@ -1477,18 +1470,16 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    cmovbl %ecx, %r15d
-; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; CHECK-NEXT:    xorl %ebp, %ebp
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    callq frexpf at PLT
 ; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
 ; CHECK-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
 ; CHECK-NEXT:    movl $8, %eax
 ; CHECK-NEXT:    subl %ecx, %eax
 ; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    cmovael %ebp, %eax
-; CHECK-NEXT:    movl $31, %r13d
+; CHECK-NEXT:    cmovael %r14d, %eax
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
@@ -1496,25 +1487,24 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    movl %r14d, %edx
 ; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
 ; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    leal 8388608(%rdx), %ebp
-; CHECK-NEXT:    movl %ebp, %edx
+; CHECK-NEXT:    leal 8388608(%rdx), %r13d
+; CHECK-NEXT:    movl %r13d, %edx
 ; CHECK-NEXT:    shrl %cl, %edx
 ; CHECK-NEXT:    movl $1, %esi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    shll %cl, %esi
 ; CHECK-NEXT:    decl %esi
 ; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %ebp
+; CHECK-NEXT:    testl %esi, %r13d
 ; CHECK-NEXT:    setne %dil
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %ebp
-; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %ebp
-; CHECK-NEXT:    orl %edi, %ebp
-; CHECK-NEXT:    andl %edx, %ebp
+; CHECK-NEXT:    shrl %cl, %r13d
+; CHECK-NEXT:    movl %r13d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %r13d
+; CHECK-NEXT:    orl %edi, %r13d
+; CHECK-NEXT:    andl %edx, %r13d
 ; CHECK-NEXT:    cmpl $1, %eax
-; CHECK-NEXT:    movl $0, %eax
-; CHECK-NEXT:    cmovbl %eax, %ebp
+; CHECK-NEXT:    cmovbl %ebp, %r13d
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1,1]
 ; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
@@ -1525,7 +1515,8 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    movl $8, %eax
 ; CHECK-NEXT:    subl %ecx, %eax
 ; CHECK-NEXT:    cmpl $31, %eax
-; CHECK-NEXT:    cmovael %r13d, %eax
+; CHECK-NEXT:    movl $31, %ecx
+; CHECK-NEXT:    cmovael %ecx, %eax
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl %eax, %ecx
 ; CHECK-NEXT:    adcl $-1, %ecx
@@ -1534,25 +1525,25 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    # kill: def $edx killed $edx def $rdx
 ; CHECK-NEXT:    andl $8388607, %edx # imm = 0x7FFFFF
 ; CHECK-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
-; CHECK-NEXT:    leal 8388608(%rdx), %r13d
-; CHECK-NEXT:    movl %r13d, %edx
+; CHECK-NEXT:    leal 8388608(%rdx), %ebp
+; CHECK-NEXT:    movl %ebp, %edx
 ; CHECK-NEXT:    shrl %cl, %edx
 ; CHECK-NEXT:    movl $1, %esi
 ; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    shll %cl, %esi
 ; CHECK-NEXT:    decl %esi
 ; CHECK-NEXT:    xorl %edi, %edi
-; CHECK-NEXT:    testl %esi, %r13d
+; CHECK-NEXT:    testl %esi, %ebp
 ; CHECK-NEXT:    setne %dil
 ; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    shrl %cl, %r13d
-; CHECK-NEXT:    movl %r13d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    andl $1, %r13d
-; CHECK-NEXT:    orl %edi, %r13d
-; CHECK-NEXT:    andl %edx, %r13d
+; CHECK-NEXT:    shrl %cl, %ebp
+; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    orl %edi, %ebp
+; CHECK-NEXT:    andl %edx, %ebp
 ; CHECK-NEXT:    cmpl $1, %eax
 ; CHECK-NEXT:    movl $0, %eax
-; CHECK-NEXT:    cmovbl %eax, %r13d
+; CHECK-NEXT:    cmovbl %eax, %ebp
 ; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
 ; CHECK-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
@@ -1590,16 +1581,16 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    movl $0, %eax
 ; CHECK-NEXT:    cmovbl %eax, %ecx
 ; CHECK-NEXT:    addl (%rsp), %r15d # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    xorl %r8d, %r8d
 ; CHECK-NEXT:    cmpl $4, %r15d
 ; CHECK-NEXT:    cmovgel %eax, %r15d
-; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    setge %r8b
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm2, %r8d
-; CHECK-NEXT:    shrl $24, %r8d
-; CHECK-NEXT:    andl $-128, %r8d
-; CHECK-NEXT:    leal (%r8,%r9,4), %r9d
-; CHECK-NEXT:    orl %r15d, %r9d
+; CHECK-NEXT:    movd %xmm2, %r9d
+; CHECK-NEXT:    shrl $24, %r9d
+; CHECK-NEXT:    andl $-128, %r9d
+; CHECK-NEXT:    leal (%r9,%r8,4), %r8d
+; CHECK-NEXT:    orl %r15d, %r8d
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload
 ; CHECK-NEXT:    shrl $21, %r11d
 ; CHECK-NEXT:    movl %r11d, %r10d
@@ -1619,180 +1610,175 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload
 ; CHECK-NEXT:    leal (%r15,%r11), %r10d
 ; CHECK-NEXT:    leal 56(,%r10,4), %ebx
-; CHECK-NEXT:    movl %r8d, %r10d
+; CHECK-NEXT:    movl %r9d, %r10d
 ; CHECK-NEXT:    orl %r12d, %r10d
 ; CHECK-NEXT:    orl %ebx, %r10d
 ; CHECK-NEXT:    leal 14(%r15,%r11), %r11d
 ; CHECK-NEXT:    testl %r11d, %r11d
-; CHECK-NEXT:    cmovlel %r9d, %r10d
+; CHECK-NEXT:    cmovlel %r8d, %r10d
 ; CHECK-NEXT:    cmpl $4, %r12d
-; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    setge %r8b
 ; CHECK-NEXT:    cmpl $30, %r11d
 ; CHECK-NEXT:    sete %bl
-; CHECK-NEXT:    andb %r9b, %bl
+; CHECK-NEXT:    andb %r8b, %bl
 ; CHECK-NEXT:    cmpl $31, %r11d
-; CHECK-NEXT:    setge %r9b
-; CHECK-NEXT:    orb %bl, %r9b
-; CHECK-NEXT:    testb %r9b, %r9b
-; CHECK-NEXT:    leal 124(%r8), %r9d
-; CHECK-NEXT:    cmovnel %r9d, %r10d
-; CHECK-NEXT:    xorps %xmm1, %xmm1
-; CHECK-NEXT:    ucomiss %xmm1, %xmm2
-; CHECK-NEXT:    cmovnel %r10d, %r8d
-; CHECK-NEXT:    cmovpl %r10d, %r8d
-; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    setge %r8b
+; CHECK-NEXT:    orb %bl, %r8b
+; CHECK-NEXT:    testb %r8b, %r8b
+; CHECK-NEXT:    leal 124(%r9), %r8d
+; CHECK-NEXT:    cmovnel %r8d, %r10d
+; CHECK-NEXT:    xorps %xmm0, %xmm0
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
+; CHECK-NEXT:    cmovnel %r10d, %r9d
+; CHECK-NEXT:    cmovpl %r10d, %r9d
+; CHECK-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
 ; CHECK-NEXT:    movaps %xmm2, %xmm3
 ; CHECK-NEXT:    movaps %xmm2, %xmm4
-; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    andps %xmm1, %xmm3
 ; CHECK-NEXT:    movss {{.*#+}} xmm2 = [+Inf,0.0E+0,0.0E+0,0.0E+0]
 ; CHECK-NEXT:    ucomiss %xmm2, %xmm3
-; CHECK-NEXT:    cmovnel %r8d, %r9d
-; CHECK-NEXT:    cmovpl %r8d, %r9d
-; CHECK-NEXT:    ucomiss %xmm4, %xmm4
-; CHECK-NEXT:    movl $126, %r8d
-; CHECK-NEXT:    cmovpl %r8d, %r9d
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
-; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    cmpl $4, %ebp
-; CHECK-NEXT:    cmovgel %eax, %ebp
-; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    cmovnel %r9d, %r8d
+; CHECK-NEXT:    cmovpl %r9d, %r8d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm4
+; CHECK-NEXT:    movl $126, %r9d
+; CHECK-NEXT:    cmovpl %r9d, %r8d
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r13d # 4-byte Folded Reload
+; CHECK-NEXT:    xorl %r10d, %r10d
+; CHECK-NEXT:    cmpl $4, %r13d
+; CHECK-NEXT:    cmovgel %eax, %r13d
+; CHECK-NEXT:    setge %r10b
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm4 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm4, %r10d
-; CHECK-NEXT:    shrl $24, %r10d
-; CHECK-NEXT:    andl $-128, %r10d
-; CHECK-NEXT:    leal (%r10,%r11,4), %r11d
-; CHECK-NEXT:    orl %ebp, %r11d
+; CHECK-NEXT:    movd %xmm4, %r11d
+; CHECK-NEXT:    shrl $24, %r11d
+; CHECK-NEXT:    andl $-128, %r11d
+; CHECK-NEXT:    leal (%r11,%r10,4), %r10d
+; CHECK-NEXT:    orl %r13d, %r10d
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload
 ; CHECK-NEXT:    shrl $21, %r15d
 ; CHECK-NEXT:    movl %r15d, %ebx
+; CHECK-NEXT:    movq %r15, %r12
 ; CHECK-NEXT:    andl $1, %ebx
-; CHECK-NEXT:    xorl %ebp, %ebp
+; CHECK-NEXT:    xorl %r15d, %r15d
 ; CHECK-NEXT:    testl $1048575, %r14d # imm = 0xFFFFF
-; CHECK-NEXT:    setne %bpl
-; CHECK-NEXT:    orl %ebx, %ebp
+; CHECK-NEXT:    setne %r15b
+; CHECK-NEXT:    orl %ebx, %r15d
 ; CHECK-NEXT:    shrl $20, %r14d
-; CHECK-NEXT:    andl %ebp, %r14d
-; CHECK-NEXT:    addl %r15d, %r14d
+; CHECK-NEXT:    andl %r15d, %r14d
+; CHECK-NEXT:    addl %r12d, %r14d
 ; CHECK-NEXT:    xorl %ebx, %ebx
 ; CHECK-NEXT:    cmpl $4, %r14d
 ; CHECK-NEXT:    cmovgel %eax, %r14d
 ; CHECK-NEXT:    setge %bl
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Reload
-; CHECK-NEXT:    leal (%r12,%rbx), %r15d
-; CHECK-NEXT:    leal 56(,%r15,4), %ebp
-; CHECK-NEXT:    movl %r10d, %r15d
-; CHECK-NEXT:    orl %r14d, %r15d
-; CHECK-NEXT:    orl %ebp, %r15d
-; CHECK-NEXT:    leal 14(%r12,%rbx), %ebx
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Reload
+; CHECK-NEXT:    leal (%r13,%rbx), %r15d
+; CHECK-NEXT:    leal 56(,%r15,4), %r15d
+; CHECK-NEXT:    movl %r11d, %r12d
+; CHECK-NEXT:    orl %r14d, %r12d
+; CHECK-NEXT:    orl %r15d, %r12d
+; CHECK-NEXT:    leal 14(%r13,%rbx), %ebx
 ; CHECK-NEXT:    testl %ebx, %ebx
-; CHECK-NEXT:    cmovlel %r11d, %r15d
+; CHECK-NEXT:    cmovlel %r10d, %r12d
 ; CHECK-NEXT:    cmpl $4, %r14d
-; CHECK-NEXT:    setge %r11b
+; CHECK-NEXT:    setge %r10b
 ; CHECK-NEXT:    cmpl $30, %ebx
-; CHECK-NEXT:    sete %bpl
-; CHECK-NEXT:    andb %r11b, %bpl
+; CHECK-NEXT:    sete %r14b
+; CHECK-NEXT:    andb %r10b, %r14b
 ; CHECK-NEXT:    cmpl $31, %ebx
-; CHECK-NEXT:    setge %r11b
-; CHECK-NEXT:    orb %bpl, %r11b
-; CHECK-NEXT:    testb %r11b, %r11b
-; CHECK-NEXT:    leal 124(%r10), %r11d
-; CHECK-NEXT:    cmovnel %r11d, %r15d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm4
-; CHECK-NEXT:    cmovnel %r15d, %r10d
-; CHECK-NEXT:    cmovpl %r15d, %r10d
-; CHECK-NEXT:    movzbl %r9b, %ebx
+; CHECK-NEXT:    setge %r10b
+; CHECK-NEXT:    orb %r14b, %r10b
+; CHECK-NEXT:    testb %r10b, %r10b
+; CHECK-NEXT:    leal 124(%r11), %r10d
+; CHECK-NEXT:    cmovnel %r10d, %r12d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm4
+; CHECK-NEXT:    cmovnel %r12d, %r11d
+; CHECK-NEXT:    cmovpl %r12d, %r11d
 ; CHECK-NEXT:    movaps %xmm4, %xmm3
-; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    andps %xmm1, %xmm3
 ; CHECK-NEXT:    ucomiss %xmm2, %xmm3
-; CHECK-NEXT:    cmovnel %r10d, %r11d
-; CHECK-NEXT:    cmovpl %r10d, %r11d
-; CHECK-NEXT:    ucomiss %xmm4, %xmm4
-; CHECK-NEXT:    cmovpl %r8d, %r11d
-; CHECK-NEXT:    movzbl %r11b, %r9d
-; CHECK-NEXT:    shll $8, %r9d
-; CHECK-NEXT:    orl %ebx, %r9d
-; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %r13d # 4-byte Folded Reload
+; CHECK-NEXT:    cmovnel %r11d, %r10d
+; CHECK-NEXT:    cmovpl %r11d, %r10d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm4
+; CHECK-NEXT:    cmovpl %r9d, %r10d
+; CHECK-NEXT:    addl {{[-0-9]+}}(%r{{[sb]}}p), %ebp # 4-byte Folded Reload
 ; CHECK-NEXT:    xorl %r11d, %r11d
-; CHECK-NEXT:    cmpl $4, %r13d
-; CHECK-NEXT:    cmovgel %eax, %r13d
+; CHECK-NEXT:    cmpl $4, %ebp
+; CHECK-NEXT:    cmovgel %eax, %ebp
 ; CHECK-NEXT:    setge %r11b
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm4 # 16-byte Reload
-; CHECK-NEXT:    movd %xmm4, %r10d
-; CHECK-NEXT:    shrl $24, %r10d
-; CHECK-NEXT:    andl $-128, %r10d
-; CHECK-NEXT:    leal (%r10,%r11,4), %r11d
-; CHECK-NEXT:    orl %r13d, %r11d
+; CHECK-NEXT:    movd %xmm4, %ebx
+; CHECK-NEXT:    shrl $24, %ebx
+; CHECK-NEXT:    andl $-128, %ebx
+; CHECK-NEXT:    leal (%rbx,%r11,4), %r11d
+; CHECK-NEXT:    orl %ebp, %r11d
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload
 ; CHECK-NEXT:    shrl $21, %r14d
-; CHECK-NEXT:    movl %r14d, %ebx
+; CHECK-NEXT:    movl %r14d, %ebp
 ; CHECK-NEXT:    movq %r14, %r15
-; CHECK-NEXT:    andl $1, %ebx
-; CHECK-NEXT:    xorl %ebp, %ebp
-; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Reload
-; CHECK-NEXT:    testl $1048575, %r14d # imm = 0xFFFFF
-; CHECK-NEXT:    setne %bpl
-; CHECK-NEXT:    orl %ebx, %ebp
-; CHECK-NEXT:    shrl $20, %r14d
-; CHECK-NEXT:    andl %ebp, %r14d
-; CHECK-NEXT:    addl %r15d, %r14d
-; CHECK-NEXT:    xorl %ebx, %ebx
-; CHECK-NEXT:    cmpl $4, %r14d
-; CHECK-NEXT:    cmovgel %eax, %r14d
-; CHECK-NEXT:    movl %r14d, %r12d
-; CHECK-NEXT:    setge %bl
-; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload
-; CHECK-NEXT:    leal (%r15,%rbx), %r14d
-; CHECK-NEXT:    leal 56(,%r14,4), %ebp
-; CHECK-NEXT:    movl %r10d, %r14d
-; CHECK-NEXT:    orl %r12d, %r14d
+; CHECK-NEXT:    andl $1, %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %r12d # 4-byte Reload
+; CHECK-NEXT:    testl $1048575, %r12d # imm = 0xFFFFF
+; CHECK-NEXT:    setne %r14b
 ; CHECK-NEXT:    orl %ebp, %r14d
-; CHECK-NEXT:    leal 14(%r15,%rbx), %ebx
-; CHECK-NEXT:    testl %ebx, %ebx
-; CHECK-NEXT:    cmovlel %r11d, %r14d
-; CHECK-NEXT:    cmpl $4, %r12d
+; CHECK-NEXT:    movl %r12d, %ebp
+; CHECK-NEXT:    shrl $20, %ebp
+; CHECK-NEXT:    andl %r14d, %ebp
+; CHECK-NEXT:    addl %r15d, %ebp
+; CHECK-NEXT:    xorl %r14d, %r14d
+; CHECK-NEXT:    cmpl $4, %ebp
+; CHECK-NEXT:    cmovgel %eax, %ebp
+; CHECK-NEXT:    movl %ebp, %r13d
+; CHECK-NEXT:    setge %r14b
+; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Reload
+; CHECK-NEXT:    leal (%r12,%r14), %r15d
+; CHECK-NEXT:    leal 56(,%r15,4), %ebp
+; CHECK-NEXT:    movl %ebx, %r15d
+; CHECK-NEXT:    orl %r13d, %r15d
+; CHECK-NEXT:    orl %ebp, %r15d
+; CHECK-NEXT:    leal 14(%r12,%r14), %ebp
+; CHECK-NEXT:    testl %ebp, %ebp
+; CHECK-NEXT:    cmovlel %r11d, %r15d
+; CHECK-NEXT:    cmpl $4, %r13d
 ; CHECK-NEXT:    setge %r11b
-; CHECK-NEXT:    cmpl $30, %ebx
-; CHECK-NEXT:    sete %bpl
-; CHECK-NEXT:    andb %r11b, %bpl
-; CHECK-NEXT:    cmpl $31, %ebx
+; CHECK-NEXT:    cmpl $30, %ebp
+; CHECK-NEXT:    sete %r14b
+; CHECK-NEXT:    andb %r11b, %r14b
+; CHECK-NEXT:    cmpl $31, %ebp
 ; CHECK-NEXT:    setge %r11b
-; CHECK-NEXT:    orb %bpl, %r11b
+; CHECK-NEXT:    orb %r14b, %r11b
 ; CHECK-NEXT:    testb %r11b, %r11b
-; CHECK-NEXT:    leal 124(%r10), %r11d
-; CHECK-NEXT:    cmovnel %r11d, %r14d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm4
-; CHECK-NEXT:    cmovnel %r14d, %r10d
-; CHECK-NEXT:    cmovpl %r14d, %r10d
+; CHECK-NEXT:    leal 124(%rbx), %r11d
+; CHECK-NEXT:    cmovnel %r11d, %r15d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm4
+; CHECK-NEXT:    cmovnel %r15d, %ebx
+; CHECK-NEXT:    cmovpl %r15d, %ebx
 ; CHECK-NEXT:    movaps %xmm4, %xmm3
-; CHECK-NEXT:    andps %xmm0, %xmm3
+; CHECK-NEXT:    andps %xmm1, %xmm3
 ; CHECK-NEXT:    ucomiss %xmm2, %xmm3
-; CHECK-NEXT:    cmovnel %r10d, %r11d
-; CHECK-NEXT:    cmovpl %r10d, %r11d
-; CHECK-NEXT:    ucomiss %xmm4, %xmm4
-; CHECK-NEXT:    cmovpl %r8d, %r11d
-; CHECK-NEXT:    movzbl %r11b, %r10d
-; CHECK-NEXT:    shll $16, %r10d
-; CHECK-NEXT:    orl %r9d, %r10d
+; CHECK-NEXT:    cmovnel %ebx, %r11d
+; CHECK-NEXT:    cmovpl %ebx, %r11d
+; CHECK-NEXT:    ucomiss %xmm0, %xmm4
+; CHECK-NEXT:    cmovpl %r9d, %r11d
 ; CHECK-NEXT:    addl %edi, %ecx
-; CHECK-NEXT:    xorl %r9d, %r9d
+; CHECK-NEXT:    xorl %ebx, %ebx
 ; CHECK-NEXT:    cmpl $4, %ecx
 ; CHECK-NEXT:    cmovgel %eax, %ecx
-; CHECK-NEXT:    setge %r9b
+; CHECK-NEXT:    setge %bl
 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
 ; CHECK-NEXT:    movd %xmm3, %edi
 ; CHECK-NEXT:    shrl $24, %edi
 ; CHECK-NEXT:    andl $-128, %edi
-; CHECK-NEXT:    leal (%rdi,%r9,4), %r9d
-; CHECK-NEXT:    orl %ecx, %r9d
+; CHECK-NEXT:    leal (%rdi,%rbx,4), %ebx
+; CHECK-NEXT:    orl %ecx, %ebx
 ; CHECK-NEXT:    shrl $21, %esi
 ; CHECK-NEXT:    movl %esi, %ecx
 ; CHECK-NEXT:    andl $1, %ecx
-; CHECK-NEXT:    xorl %r11d, %r11d
+; CHECK-NEXT:    xorl %ebp, %ebp
 ; CHECK-NEXT:    testl $1048575, %edx # imm = 0xFFFFF
-; CHECK-NEXT:    setne %r11b
-; CHECK-NEXT:    orl %ecx, %r11d
+; CHECK-NEXT:    setne %bpl
+; CHECK-NEXT:    orl %ecx, %ebp
 ; CHECK-NEXT:    shrl $20, %edx
-; CHECK-NEXT:    andl %r11d, %edx
+; CHECK-NEXT:    andl %ebp, %edx
 ; CHECK-NEXT:    addl %esi, %edx
 ; CHECK-NEXT:    xorl %ecx, %ecx
 ; CHECK-NEXT:    cmpl $4, %edx
@@ -1801,12 +1787,12 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
 ; CHECK-NEXT:    leal (%rax,%rcx), %esi
 ; CHECK-NEXT:    leal 56(,%rsi,4), %esi
-; CHECK-NEXT:    movl %edi, %r11d
-; CHECK-NEXT:    orl %edx, %r11d
-; CHECK-NEXT:    orl %esi, %r11d
+; CHECK-NEXT:    movl %edi, %ebp
+; CHECK-NEXT:    orl %edx, %ebp
+; CHECK-NEXT:    orl %esi, %ebp
 ; CHECK-NEXT:    leal 14(%rax,%rcx), %eax
 ; CHECK-NEXT:    testl %eax, %eax
-; CHECK-NEXT:    cmovlel %r9d, %r11d
+; CHECK-NEXT:    cmovlel %ebx, %ebp
 ; CHECK-NEXT:    cmpl $4, %edx
 ; CHECK-NEXT:    setge %cl
 ; CHECK-NEXT:    cmpl $30, %eax
@@ -1817,18 +1803,25 @@ define <4 x i8> @to_f8e5m2_v4f32(<4 x float> %x) {
 ; CHECK-NEXT:    orb %dl, %al
 ; CHECK-NEXT:    testb %al, %al
 ; CHECK-NEXT:    leal 124(%rdi), %eax
-; CHECK-NEXT:    cmovnel %eax, %r11d
-; CHECK-NEXT:    ucomiss %xmm1, %xmm3
-; CHECK-NEXT:    cmovnel %r11d, %edi
-; CHECK-NEXT:    cmovpl %r11d, %edi
-; CHECK-NEXT:    andps %xmm3, %xmm0
-; CHECK-NEXT:    ucomiss %xmm2, %xmm0
+; CHECK-NEXT:    cmovnel %eax, %ebp
+; CHECK-NEXT:    ucomiss %xmm0, %xmm3
+; CHECK-NEXT:    cmovnel %ebp, %edi
+; CHECK-NEXT:    cmovpl %ebp, %edi
+; CHECK-NEXT:    andps %xmm3, %xmm1
+; CHECK-NEXT:    ucomiss %xmm2, %xmm1
 ; CHECK-NEXT:    cmovnel %edi, %eax
 ; CHECK-NEXT:    cmovpl %edi, %eax
-; CHECK-NEXT:    ucomiss %xmm3, %xmm3
-; CHECK-NEXT:    cmovpl %r8d, %eax
+; CHECK-NEXT:    ucomiss %xmm0, %xmm3
+; CHECK-NEXT:    cmovpl %r9d, %eax
+; CHECK-NEXT:    movzbl %r10b, %ecx
+; CHECK-NEXT:    movzbl %r8b, %edx
+; CHECK-NEXT:    shll $8, %edx
+; CHECK-NEXT:    orl %ecx, %edx
+; CHECK-NEXT:    movzbl %r11b, %ecx
+; CHECK-NEXT:    shll $16, %ecx
+; CHECK-NEXT:    orl %edx, %ecx
 ; CHECK-NEXT:    shll $24, %eax
-; CHECK-NEXT:    orl %r10d, %eax
+; CHECK-NEXT:    orl %ecx, %eax
 ; CHECK-NEXT:    movd %eax, %xmm0
 ; CHECK-NEXT:    addq $168, %rsp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 56
@@ -2026,7 +2019,6 @@ define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) {
 ; CHECK-NEXT:    ucomiss %xmm1, %xmm0
 ; CHECK-NEXT:    cmovnel %r12d, %r15d
 ; CHECK-NEXT:    cmovpl %r12d, %r15d
-; CHECK-NEXT:    ucomiss %xmm0, %xmm0
 ; CHECK-NEXT:    movl $127, %r12d
 ; CHECK-NEXT:    cmovpl %r12d, %r15d
 ; CHECK-NEXT:    movzbl %r15b, %r15d
@@ -2070,7 +2062,6 @@ define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) {
 ; CHECK-NEXT:    ucomiss %xmm1, %xmm0
 ; CHECK-NEXT:    cmovnel %ebp, %ebx
 ; CHECK-NEXT:    cmovpl %ebp, %ebx
-; CHECK-NEXT:    ucomiss %xmm0, %xmm0
 ; CHECK-NEXT:    cmovpl %r12d, %ebx
 ; CHECK-NEXT:    shll $8, %ebx
 ; CHECK-NEXT:    orl %r15d, %ebx
@@ -2220,9 +2211,10 @@ define i8 @to_f8e5m2_from_f16(half %x) {
 ; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    cmovnel %ebx, %r14d
 ; CHECK-NEXT:    cmovpl %ebx, %r14d
-; CHECK-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
-; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
-; CHECK-NEXT:    ucomiss %xmm0, %xmm0
+; CHECK-NEXT:    xorps %xmm0, %xmm0
+; CHECK-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload
+; CHECK-NEXT:    # xmm1 = mem[0],zero,zero,zero
+; CHECK-NEXT:    ucomiss %xmm0, %xmm1
 ; CHECK-NEXT:    movl $126, %eax
 ; CHECK-NEXT:    cmovnpl %r14d, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
@@ -2329,16 +2321,16 @@ define i8 @to_f8e5m2_from_bf16(bfloat %x) {
 ; CHECK-NEXT:    testb %al, %al
 ; CHECK-NEXT:    cmovnel %ecx, %r8d
 ; CHECK-NEXT:    pxor %xmm0, %xmm0
-; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; CHECK-NEXT:    ucomiss %xmm0, %xmm1
+; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
 ; CHECK-NEXT:    cmovnel %r8d, %ebx
 ; CHECK-NEXT:    cmovpl %r8d, %ebx
-; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
-; CHECK-NEXT:    andps %xmm1, %xmm0
-; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; CHECK-NEXT:    andps %xmm2, %xmm1
+; CHECK-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
 ; CHECK-NEXT:    cmovnel %ebx, %ecx
 ; CHECK-NEXT:    cmovpl %ebx, %ecx
-; CHECK-NEXT:    ucomiss %xmm1, %xmm1
+; CHECK-NEXT:    ucomiss %xmm0, %xmm2
 ; CHECK-NEXT:    movl $126, %eax
 ; CHECK-NEXT:    cmovnpl %ecx, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
@@ -2402,8 +2394,8 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-NEXT:    cmpq $4, %r9
 ; CHECK-NEXT:    cmovgeq %rcx, %r9
 ; CHECK-NEXT:    setge %dl
-; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; CHECK-NEXT:    movq %xmm1, %rax
+; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
+; CHECK-NEXT:    movq %xmm2, %rax
 ; CHECK-NEXT:    shrq $63, %rax
 ; CHECK-NEXT:    shll $7, %eax
 ; CHECK-NEXT:    leal (%rax,%rdx,4), %edx
@@ -2443,15 +2435,15 @@ define i8 @to_f8e5m2_from_f64(double %x) {
 ; CHECK-NEXT:    testb %cl, %cl
 ; CHECK-NEXT:    cmovneq %rdx, %r9
 ; CHECK-NEXT:    pxor %xmm0, %xmm0
-; CHECK-NEXT:    ucomisd %xmm0, %xmm1
+; CHECK-NEXT:    ucomisd %xmm0, %xmm2
 ; CHECK-NEXT:    cmovneq %r9, %rax
 ; CHECK-NEXT:    cmovpq %r9, %rax
-; CHECK-NEXT:    movapd {{.*#+}} xmm0 = [NaN,NaN]
-; CHECK-NEXT:    andpd %xmm1, %xmm0
-; CHECK-NEXT:    ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; CHECK-NEXT:    andpd %xmm2, %xmm1
+; CHECK-NEXT:    ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
 ; CHECK-NEXT:    cmovneq %rax, %rdx
 ; CHECK-NEXT:    cmovpq %rax, %rdx
-; CHECK-NEXT:    ucomisd %xmm1, %xmm1
+; CHECK-NEXT:    ucomisd %xmm0, %xmm2
 ; CHECK-NEXT:    movl $126, %eax
 ; CHECK-NEXT:    cmovnpq %rdx, %rax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $rax

>From 1c9e03e1499fc1e3abb710dcadf931ba62d0802d Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Thu, 11 Jun 2026 02:47:51 +0200
Subject: [PATCH 9/9] address comments

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   | 44 ++++++++++---------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index b31f294d71e96..1bbbea37b02d2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -9133,10 +9133,7 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
   // Work in the source integer type. Match the destination shape so the
   // expansion stays vector when ResVT is a vector.
   EVT IntScalarVT = EVT::getIntegerVT(*DAG.getContext(), SrcBits);
-  EVT IntVT = ResVT.isVector()
-                  ? EVT::getVectorVT(*DAG.getContext(), IntScalarVT,
-                                     ResVT.getVectorElementCount())
-                  : IntScalarVT;
+  EVT IntVT = ResVT.changeElementType(*DAG.getContext(), IntScalarVT);
   EVT SetCCVT =
       getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), IntVT);
   EVT FPSetCCVT =
@@ -9175,22 +9172,22 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
                                    DAG.getConstant(SrcMantMask, dl, IntVT));
 
   SDValue FrexpExpExt = DAG.getSExtOrTrunc(FrexpExp, dl, IntVT);
-  SDValue NewExp = DAG.getNode(
-      ISD::ADD, dl, IntVT, FrexpExpExt,
-      DAG.getConstant(APInt(SrcBits, DstBias - 1, true), dl, IntVT));
+  SDValue NewExp = DAG.getNode(ISD::ADD, dl, IntVT, FrexpExpExt,
+                               DAG.getConstant(DstBias - 1, dl, IntVT));
 
   // Compute rounding increment given the round bit, sticky bits, and LSB
   // of the truncated mantissa.
   auto ComputeRoundUp = [&](SDValue RoundBit, SDValue StickyBits,
                             SDValue LSB) -> SDValue {
-    if (RoundMode == RoundingMode::NearestTiesToEven) {
+    switch (RoundMode) {
+    case RoundingMode::NearestTiesToEven: {
       // Round up if round_bit && (sticky || lsb)
       SDValue StickyOrLSB = DAG.getNode(ISD::OR, dl, IntVT, StickyBits, LSB);
       return DAG.getNode(ISD::AND, dl, IntVT, RoundBit, StickyOrLSB);
     }
-    if (RoundMode == RoundingMode::TowardZero)
+    case RoundingMode::TowardZero:
       return Zero;
-    if (RoundMode == RoundingMode::TowardPositive) {
+    case RoundingMode::TowardPositive: {
       // Round up if positive and any truncated bits are set.
       SDValue AnyTruncBits =
           DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
@@ -9201,7 +9198,7 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
           DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsPositive);
       return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
     }
-    if (RoundMode == RoundingMode::TowardNegative) {
+    case RoundingMode::TowardNegative: {
       // Round up if negative and any truncated bits are set (to -Inf).
       SDValue AnyTruncBits =
           DAG.getNode(ISD::OR, dl, IntVT, RoundBit, StickyBits);
@@ -9212,9 +9209,11 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
           DAG.getNode(ISD::AND, dl, SetCCVT, HasTruncBits, IsNegative);
       return DAG.getNode(ISD::ZERO_EXTEND, dl, IntVT, DoRound);
     }
-    assert(RoundMode == RoundingMode::NearestTiesToAway &&
-           "Unsupported rounding mode; should have been rejected above");
-    return RoundBit;
+    case RoundingMode::NearestTiesToAway:
+      return RoundBit;
+    default:
+      llvm_unreachable("unsupported rounding mode");
+    }
   };
 
   // Round mantissa from SrcMant bits to DstMant bits.
@@ -9239,7 +9238,7 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
     // OR of all bits below the round bit to get sticky bits.
     SDValue StickyBits;
     if (Shift >= 2) {
-      uint64_t StickyMask = (1ULL << (Shift - 1)) - 1;
+      uint64_t StickyMask = maskTrailingOnes<uint64_t>(Shift - 1);
       StickyBits = DAG.getNode(ISD::AND, dl, IntVT, EffSrcMant,
                                DAG.getConstant(StickyMask, dl, IntVT));
       StickyBits = DAG.getSetCC(dl, SetCCVT, StickyBits, Zero, ISD::SETNE);
@@ -9303,12 +9302,14 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
         DAG.getNode(ISD::ADD, dl, IntVT, DenormShift,
                     DAG.getSignedConstant(MantDelta, dl, IntVT));
 
-    // Clamp total shift to avoid UB, then trancate denorm mantissa.
+    // Clamp total shift to avoid UB, then truncate denorm mantissa.
+    EVT ShiftVT = getShiftAmountTy(IntVT, DAG.getDataLayout());
     SDValue MaxShift = DAG.getConstant(SrcBits - 1, dl, IntVT);
     SDValue ClampedShift =
         DAG.getNode(ISD::UMIN, dl, IntVT, TotalShift, MaxShift);
     SDValue DenormTruncMant =
-        DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, ClampedShift);
+        DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant,
+                    DAG.getZExtOrTrunc(ClampedShift, dl, ShiftVT));
 
     // Rounding for denorm path.
     SDValue DenormRoundUp;
@@ -9318,15 +9319,16 @@ SDValue TargetLowering::expandCONVERT_TO_ARBITRARY_FP(SDNode *Node,
       // shift nodes with invalid shift amounts.
       SDValue SafeShift = DAG.getNode(ISD::UMAX, dl, IntVT, ClampedShift, One);
       SDValue RoundBitPos = DAG.getNode(ISD::SUB, dl, IntVT, SafeShift, One);
+      SDValue RoundBitPosAmt = DAG.getZExtOrTrunc(RoundBitPos, dl, ShiftVT);
       SDValue DenormRoundBit = DAG.getNode(
           ISD::AND, dl, IntVT,
-          DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, RoundBitPos), One);
+          DAG.getNode(ISD::SRL, dl, IntVT, FullSrcMant, RoundBitPosAmt), One);
 
       // Sticky: all bits below round bit.
       // sticky_mask = (1 << RoundBitPos) - 1
-      SDValue StickyMask =
-          DAG.getNode(ISD::SUB, dl, IntVT,
-                      DAG.getNode(ISD::SHL, dl, IntVT, One, RoundBitPos), One);
+      SDValue StickyMask = DAG.getNode(
+          ISD::SUB, dl, IntVT,
+          DAG.getNode(ISD::SHL, dl, IntVT, One, RoundBitPosAmt), One);
       SDValue DenormStickyBits =
           DAG.getNode(ISD::AND, dl, IntVT, FullSrcMant, StickyMask);
       SDValue HasSticky = DAG.getNode(



More information about the llvm-commits mailing list