forked from OSchip/llvm-project
[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:
parent
6606936322
commit
2f3b738960
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue