[llvm] [DAG] Support soft half promotion of insert_vector_elt (PR #194994)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 29 19:53:02 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Philip Reames (preames)

<details>
<summary>Changes</summary>

This is relevant when we have _either_ fp16 or bf16 minimal support, but not the other and we need to lower an insert for the other.  We already have existing support for extract but the insert case appears to get missed.

---
Full diff: https://github.com/llvm/llvm-project/pull/194994.diff


3 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (+11) 
- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h (+1) 
- (added) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-soft-promote-half.ll (+77) 


``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 25f4f75eaedea..9467f6406293a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -3198,6 +3198,8 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
   case ISD::FP_EXTEND:  Res = SoftPromoteHalfOp_FP_EXTEND(N); break;
   case ISD::SELECT_CC:  Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break;
   case ISD::SETCC:      Res = SoftPromoteHalfOp_SETCC(N); break;
+  case ISD::INSERT_VECTOR_ELT:
+    Res = SoftPromoteHalfOp_INSERT_VECTOR_ELT(N); break;
   case ISD::STORE:      Res = SoftPromoteHalfOp_STORE(N, OpNo); break;
   case ISD::ATOMIC_STORE:
     Res = SoftPromoteHalfOp_ATOMIC_STORE(N, OpNo);
@@ -3351,6 +3353,15 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SETCC(SDNode *N) {
   return DAG.getSetCC(SDLoc(N), N->getValueType(0), Op0, Op1, CCCode);
 }
 
+SDValue DAGTypeLegalizer::SoftPromoteHalfOp_INSERT_VECTOR_ELT(SDNode *N) {
+  SDValue NewVec = BitConvertVectorToIntegerVector(N->getOperand(0));
+  SDValue NewElt = GetSoftPromotedHalf(N->getOperand(1));
+  SDValue NewIns = DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N),
+                               NewVec.getValueType(), NewVec, NewElt,
+                               N->getOperand(2));
+  return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), NewIns);
+}
+
 SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo) {
   assert(OpNo == 1 && "Can only soften the stored value!");
   StoreSDNode *ST = cast<StoreSDNode>(N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 89698a2c77123..1b29e38513fb9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -806,6 +806,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N);
   SDValue SoftPromoteHalfOp_SETCC(SDNode *N);
   SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);
+  SDValue SoftPromoteHalfOp_INSERT_VECTOR_ELT(SDNode *N);
   SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo);
   SDValue SoftPromoteHalfOp_ATOMIC_STORE(SDNode *N, unsigned OpNo);
   SDValue SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo);
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-soft-promote-half.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-soft-promote-half.ll
new file mode 100644
index 0000000000000..6d0b4536b489b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-soft-promote-half.ll
@@ -0,0 +1,77 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefix=V
+; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfbfmin -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefix=ZVFBFMIN
+; RUN: llc -mtriple=riscv64 -mattr=+v,+zvfhmin -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefix=ZVFHMIN
+
+define <4 x bfloat> @insertelt_v4bf16(<4 x bfloat> %v, bfloat %elt) {
+; V-LABEL: insertelt_v4bf16:
+; V:       # %bb.0:
+; V-NEXT:    fmv.x.w a1, fa4
+; V-NEXT:    fmv.x.w a2, fa1
+; V-NEXT:    fmv.x.w a3, fa2
+; V-NEXT:    fmv.x.w a4, fa3
+; V-NEXT:    sh a1, 0(a0)
+; V-NEXT:    sh a2, 2(a0)
+; V-NEXT:    sh a3, 4(a0)
+; V-NEXT:    sh a4, 6(a0)
+; V-NEXT:    ret
+;
+; ZVFBFMIN-LABEL: insertelt_v4bf16:
+; ZVFBFMIN:       # %bb.0:
+; ZVFBFMIN-NEXT:    fmv.x.w a0, fa0
+; ZVFBFMIN-NEXT:    vsetivli zero, 4, e16, m1, tu, ma
+; ZVFBFMIN-NEXT:    vmv.s.x v8, a0
+; ZVFBFMIN-NEXT:    ret
+;
+; ZVFHMIN-LABEL: insertelt_v4bf16:
+; ZVFHMIN:       # %bb.0:
+; ZVFHMIN-NEXT:    fmv.x.w a1, fa4
+; ZVFHMIN-NEXT:    fmv.x.w a2, fa1
+; ZVFHMIN-NEXT:    fmv.x.w a3, fa2
+; ZVFHMIN-NEXT:    fmv.x.w a4, fa3
+; ZVFHMIN-NEXT:    sh a1, 0(a0)
+; ZVFHMIN-NEXT:    sh a2, 2(a0)
+; ZVFHMIN-NEXT:    sh a3, 4(a0)
+; ZVFHMIN-NEXT:    sh a4, 6(a0)
+; ZVFHMIN-NEXT:    ret
+  %r = insertelement <4 x bfloat> %v, bfloat %elt, i32 0
+  ret <4 x bfloat> %r
+}
+
+define <4 x half> @insertelt_v4f16(<4 x half> %v, half %elt) {
+; V-LABEL: insertelt_v4f16:
+; V:       # %bb.0:
+; V-NEXT:    fmv.x.w a2, fa0
+; V-NEXT:    lh a3, 8(a1)
+; V-NEXT:    lh a4, 16(a1)
+; V-NEXT:    lh a1, 24(a1)
+; V-NEXT:    sh a2, 0(a0)
+; V-NEXT:    sh a3, 2(a0)
+; V-NEXT:    sh a4, 4(a0)
+; V-NEXT:    sh a1, 6(a0)
+; V-NEXT:    ret
+;
+; ZVFBFMIN-LABEL: insertelt_v4f16:
+; ZVFBFMIN:       # %bb.0:
+; ZVFBFMIN-NEXT:    fmv.x.w a2, fa0
+; ZVFBFMIN-NEXT:    lh a3, 8(a1)
+; ZVFBFMIN-NEXT:    lh a4, 16(a1)
+; ZVFBFMIN-NEXT:    lh a1, 24(a1)
+; ZVFBFMIN-NEXT:    sh a2, 0(a0)
+; ZVFBFMIN-NEXT:    sh a3, 2(a0)
+; ZVFBFMIN-NEXT:    sh a4, 4(a0)
+; ZVFBFMIN-NEXT:    sh a1, 6(a0)
+; ZVFBFMIN-NEXT:    ret
+;
+; ZVFHMIN-LABEL: insertelt_v4f16:
+; ZVFHMIN:       # %bb.0:
+; ZVFHMIN-NEXT:    fmv.x.w a0, fa0
+; ZVFHMIN-NEXT:    vsetivli zero, 4, e16, m1, tu, ma
+; ZVFHMIN-NEXT:    vmv.s.x v8, a0
+; ZVFHMIN-NEXT:    ret
+  %r = insertelement <4 x half> %v, half %elt, i32 0
+  ret <4 x half> %r
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/194994


More information about the llvm-commits mailing list