diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -448,12 +448,22 @@ // Handle cases such as i8 -> <1 x i1> EVT ValueSVT = ValueVT.getVectorElementType(); if (ValueVT.getVectorNumElements() == 1 && ValueSVT != PartEVT) { - if (ValueSVT.getSizeInBits() == PartEVT.getSizeInBits()) + unsigned ValueSize = ValueSVT.getSizeInBits(); + if (ValueSize == PartEVT.getSizeInBits()) { Val = DAG.getNode(ISD::BITCAST, DL, ValueSVT, Val); - else + } else if (ValueSVT.isFloatingPoint() && PartEVT.isInteger()) { + // It's possible a scalar floating point type gets softened to integer and + // then promoted to a larger integer. If PartEVT is the larger integer + // we need to truncate it and then bitcast to the FP type. + assert(ValueSVT.bitsLT(PartEVT) && "Unexpected types"); + EVT IntermediateType = EVT::getIntegerVT(*DAG.getContext(), ValueSize); + Val = DAG.getNode(ISD::TRUNCATE, DL, IntermediateType, Val); + Val = DAG.getBitcast(ValueSVT, Val); + } else { Val = ValueVT.isFloatingPoint() ? DAG.getFPExtendOrRound(Val, DL, ValueSVT) : DAG.getAnyExtOrTrunc(Val, DL, ValueSVT); + } } return DAG.getBuildVector(ValueVT, DL, Val); @@ -679,7 +689,11 @@ SDValue Widened = widenVectorToPartType(DAG, Val, DL, WidenVT); Val = DAG.getAnyExtOrTrunc(Widened, DL, PartVT); } else { - if (ValueVT.getVectorElementCount().isScalar()) { + // Don't extract an integer from a float vector. This can happen if the + // FP type gets softened to integer and then promoted. The promotion + // prevents it from being picked up by the earlier bitcast case. + if (ValueVT.getVectorElementCount().isScalar() && + (!ValueVT.isFloatingPoint() || !PartVT.isInteger())) { Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, PartVT, Val, DAG.getVectorIdxConstant(0, DL)); } else { diff --git a/llvm/test/CodeGen/RISCV/pr58025.ll b/llvm/test/CodeGen/RISCV/pr58025.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/pr58025.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=riscv64 | FileCheck %s + +define void @f() { +; CHECK-LABEL: f: +; CHECK: # %bb.0: # %BB +; CHECK-NEXT: lui a0, 260096 +; CHECK-NEXT: addi sp, sp, -16 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: sw a0, 12(sp) +; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: ret +BB: + %B = fdiv <1 x float> , + %PTR = alloca <1 x float> + br label %BB1 + +BB1: ; preds = %BB + store <1 x float> %B, <1 x float>* %PTR + ret void +}