Commit 2f3b7389 authored by Craig Topper's avatar Craig Topper
Browse files

[RISCV] Add optimizations for FMV_X_ANYEXTH similar to FMV_X_ANYEXTW_RV64.

This enables the fneg and fabs combines we have for FMV_X_ANYEXTW_RV64.
parent 66069363
Loading
Loading
Loading
Loading
+16 −11
Original line number Diff line number Diff line
@@ -6103,14 +6103,19 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,

    break;
  }
  case RISCVISD::FMV_X_ANYEXTH:
  case RISCVISD::FMV_X_ANYEXTW_RV64: {
    SDLoc DL(N);
    SDValue Op0 = N->getOperand(0);
    MVT VT = N->getSimpleValueType(0);
    // If the input to FMV_X_ANYEXTW_RV64 is just FMV_W_X_RV64 then the
    // conversion is unnecessary and can be replaced with an ANY_EXTEND
    // of the FMV_W_X_RV64 operand.
    if (Op0->getOpcode() == RISCVISD::FMV_W_X_RV64) {
      assert(Op0.getOperand(0).getValueType() == MVT::i64 &&
    // conversion is unnecessary and can be replaced with the FMV_W_X_RV64
    // operand. Similar for FMV_X_ANYEXTH and FMV_H_X.
    if ((N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 &&
         Op0->getOpcode() == RISCVISD::FMV_W_X_RV64) ||
        (N->getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
         Op0->getOpcode() == RISCVISD::FMV_H_X)) {
      assert(Op0.getOperand(0).getValueType() == VT &&
             "Unexpected value type!");
      return Op0.getOperand(0);
    }
@@ -6122,16 +6127,16 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
    if (!(Op0.getOpcode() == ISD::FNEG || Op0.getOpcode() == ISD::FABS) ||
        !Op0.getNode()->hasOneUse())
      break;
    SDValue NewFMV = DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64,
                                 Op0.getOperand(0));
    APInt SignBit = APInt::getSignMask(32).sext(64);
    SDValue NewFMV = DAG.getNode(N->getOpcode(), DL, VT, Op0.getOperand(0));
    unsigned FPBits = N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 ? 32 : 16;
    APInt SignBit = APInt::getSignMask(FPBits).sextOrSelf(VT.getSizeInBits());
    if (Op0.getOpcode() == ISD::FNEG)
      return DAG.getNode(ISD::XOR, DL, MVT::i64, NewFMV,
                         DAG.getConstant(SignBit, DL, MVT::i64));
      return DAG.getNode(ISD::XOR, DL, VT, NewFMV,
                         DAG.getConstant(SignBit, DL, VT));

    assert(Op0.getOpcode() == ISD::FABS);
    return DAG.getNode(ISD::AND, DL, MVT::i64, NewFMV,
                       DAG.getConstant(~SignBit, DL, MVT::i64));
    return DAG.getNode(ISD::AND, DL, VT, NewFMV,
                       DAG.getConstant(~SignBit, DL, VT));
  }
  case ISD::AND:
    return performANDCombine(N, DCI, Subtarget);
+10 −12
Original line number Diff line number Diff line
@@ -23,9 +23,8 @@ define half @fneg(half %a) nounwind {
;
; RV32IZFH-LABEL: fneg:
; RV32IZFH:       # %bb.0:
; RV32IZFH-NEXT:    fmv.h.x ft0, a0
; RV32IZFH-NEXT:    fneg.h ft0, ft0
; RV32IZFH-NEXT:    fmv.x.h a0, ft0
; RV32IZFH-NEXT:    lui a1, 1048568
; RV32IZFH-NEXT:    xor a0, a0, a1
; RV32IZFH-NEXT:    ret
;
; RV64I-LABEL: fneg:
@@ -36,9 +35,8 @@ define half @fneg(half %a) nounwind {
;
; RV64IZFH-LABEL: fneg:
; RV64IZFH:       # %bb.0:
; RV64IZFH-NEXT:    fmv.h.x ft0, a0
; RV64IZFH-NEXT:    fneg.h ft0, ft0
; RV64IZFH-NEXT:    fmv.x.h a0, ft0
; RV64IZFH-NEXT:    lui a1, 1048568
; RV64IZFH-NEXT:    xor a0, a0, a1
; RV64IZFH-NEXT:    ret
  %1 = fneg half %a
  ret half %1
@@ -56,9 +54,9 @@ define half @fabs(half %a) nounwind {
;
; RV32IZFH-LABEL: fabs:
; RV32IZFH:       # %bb.0:
; RV32IZFH-NEXT:    fmv.h.x ft0, a0
; RV32IZFH-NEXT:    fabs.h ft0, ft0
; RV32IZFH-NEXT:    fmv.x.h a0, ft0
; RV32IZFH-NEXT:    lui a1, 8
; RV32IZFH-NEXT:    addi a1, a1, -1
; RV32IZFH-NEXT:    and a0, a0, a1
; RV32IZFH-NEXT:    ret
;
; RV64I-LABEL: fabs:
@@ -70,9 +68,9 @@ define half @fabs(half %a) nounwind {
;
; RV64IZFH-LABEL: fabs:
; RV64IZFH:       # %bb.0:
; RV64IZFH-NEXT:    fmv.h.x ft0, a0
; RV64IZFH-NEXT:    fabs.h ft0, ft0
; RV64IZFH-NEXT:    fmv.x.h a0, ft0
; RV64IZFH-NEXT:    lui a1, 8
; RV64IZFH-NEXT:    addiw a1, a1, -1
; RV64IZFH-NEXT:    and a0, a0, a1
; RV64IZFH-NEXT:    ret
  %1 = call half @llvm.fabs.f16(half %a)
  ret half %1