[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.
This commit is contained in:
Craig Topper 2021-08-08 18:29:22 -07:00
parent 6606936322
commit 2f3b738960
2 changed files with 26 additions and 23 deletions

View File

@ -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);

View File

@ -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