From aeb27f133af224f4899998586e8f9d0f7dc0c907 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 1 Jun 2022 08:13:49 -0700 Subject: [PATCH] [RISCV] Fix i64<->f64 and i32<->f32 bitcasts with VLS vectors enabled. We enable a custom handler to optimize conversions between scalars and fixed vectors. Unfortunately, the custom handler picks up scalar to scalar conversions as well. If the scalar types are both legal, we wouldn't match any of the fixed vector cases and would return SDValue() causing the LegalizeDAG to expand the bitcast through memory. This patch fixes this by checking if it's a scalar to scalar conversion and returns `Op` if both types are legal. Differential Revision: https://reviews.llvm.org/D126739 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 36 ++++++++++++++-------- .../CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll | 6 +--- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 16a71e1..ad1bfeb 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2969,6 +2969,30 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, SDValue Op0 = Op.getOperand(0); EVT Op0VT = Op0.getValueType(); MVT XLenVT = Subtarget.getXLenVT(); + if (VT == MVT::f16 && Op0VT == MVT::i16 && Subtarget.hasStdExtZfh()) { + SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Op0); + SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::f16, NewOp0); + return FPConv; + } + if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.is64Bit() && + Subtarget.hasStdExtF()) { + SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0); + SDValue FPConv = + DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, NewOp0); + return FPConv; + } + + // Consider other scalar<->scalar casts as legal if the types are legal. + // Otherwise expand them. + if (!VT.isVector() && !Op0VT.isVector()) { + if (isTypeLegal(VT) && isTypeLegal(Op0VT)) + return Op; + return SDValue(); + } + + assert(!VT.isScalableVector() && !Op0VT.isScalableVector() && + "Unexpected types"); + if (VT.isFixedLengthVector()) { // We can handle fixed length vector bitcasts with a simple replacement // in isel. @@ -2998,18 +3022,6 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, BVec, DAG.getConstant(0, DL, XLenVT)); } - if (VT == MVT::f16 && Op0VT == MVT::i16 && Subtarget.hasStdExtZfh()) { - SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, Op0); - SDValue FPConv = DAG.getNode(RISCVISD::FMV_H_X, DL, MVT::f16, NewOp0); - return FPConv; - } - if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.is64Bit() && - Subtarget.hasStdExtF()) { - SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0); - SDValue FPConv = - DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, NewOp0); - return FPConv; - } return SDValue(); } case ISD::INTRINSIC_WO_CHAIN: diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll index ff0e9af..836871f 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll @@ -426,11 +426,7 @@ define double @bitcast_v1i64_f64(<1 x i64> %a) { ; ; RV64ELEN32-LABEL: bitcast_v1i64_f64: ; RV64ELEN32: # %bb.0: -; RV64ELEN32-NEXT: addi sp, sp, -16 -; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 -; RV64ELEN32-NEXT: sd a0, 8(sp) -; RV64ELEN32-NEXT: fld fa0, 8(sp) -; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: fmv.d.x fa0, a0 ; RV64ELEN32-NEXT: ret %b = bitcast <1 x i64> %a to double ret double %b -- 2.7.4