mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[RISCV] Have sexti32 also recognize AssertZExt from types smaller than i32.
An i64 AssertZExt from a type smaller than i32 has at least 33 leading zeros which mean it has at least 33 sign bits. Since we have a couple patterns that use two sexti32, I've switched to a ComplexPattern so tablegen didn't have to generate 9 different permutations. As noted in the FIXME, maybe we should just call computeNumSignBits, but we don't have tests that benefit from that yet. Reviewed By: luismarques Differential Revision: https://reviews.llvm.org/D97130
This commit is contained in:
parent
782b2539f9
commit
44d510a3c6
@ -1123,6 +1123,27 @@ bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RISCVDAGToDAGISel::selectSExti32(SDValue N, SDValue &Val) {
|
||||
if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
|
||||
cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
|
||||
Val = N.getOperand(0);
|
||||
return true;
|
||||
}
|
||||
// FIXME: Should we just call computeNumSignBits here?
|
||||
if (N.getOpcode() == ISD::AssertSext &&
|
||||
cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32)) {
|
||||
Val = N;
|
||||
return true;
|
||||
}
|
||||
if (N.getOpcode() == ISD::AssertZext &&
|
||||
cast<VTSDNode>(N->getOperand(1))->getVT().bitsLT(MVT::i32)) {
|
||||
Val = N;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Match (srl (and val, mask), imm) where the result would be a
|
||||
// zero-extended 32-bit integer. i.e. the mask is 0xffffffff or the result
|
||||
// is equivalent to this (SimplifyDemandedBits may have removed lower bits
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
return selectShiftMask(N, 32, ShAmt);
|
||||
}
|
||||
|
||||
bool selectSExti32(SDValue N, SDValue &Val);
|
||||
|
||||
bool MatchSRLIW(SDNode *N) const;
|
||||
bool MatchSLLIUW(SDNode *N) const;
|
||||
|
||||
|
@ -848,9 +848,7 @@ def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
|
||||
def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
|
||||
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
|
||||
}]>;
|
||||
def sexti32 : PatFrags<(ops node:$src),
|
||||
[(sext_inreg node:$src, i32),
|
||||
(assertsexti32 node:$src)]>;
|
||||
def sexti32 : ComplexPattern<i64, 1, "selectSExti32">;
|
||||
def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
|
||||
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
|
||||
}]>;
|
||||
|
@ -356,7 +356,7 @@ def : Pat<(sext_inreg (assertzexti32 (fp_to_uint FPR64:$rs1)), i32),
|
||||
(FCVT_WU_D $rs1, 0b001)>;
|
||||
|
||||
// [u]int32->fp
|
||||
def : Pat<(sint_to_fp (i64 (sexti32 GPR:$rs1))), (FCVT_D_W $rs1)>;
|
||||
def : Pat<(sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_D_W $rs1)>;
|
||||
def : Pat<(uint_to_fp (i64 (zexti32 GPR:$rs1))), (FCVT_D_WU $rs1)>;
|
||||
|
||||
def : Pat<(i64 (fp_to_sint FPR64:$rs1)), (FCVT_L_D FPR64:$rs1, 0b001)>;
|
||||
|
@ -400,7 +400,7 @@ def : Pat<(i64 (fp_to_sint FPR32:$rs1)), (FCVT_L_S $rs1, 0b001)>;
|
||||
def : Pat<(i64 (fp_to_uint FPR32:$rs1)), (FCVT_LU_S $rs1, 0b001)>;
|
||||
|
||||
// [u]int->fp. Match GCC and default to using dynamic rounding mode.
|
||||
def : Pat<(sint_to_fp (i64 (sexti32 GPR:$rs1))), (FCVT_S_W $rs1, 0b111)>;
|
||||
def : Pat<(sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_S_W $rs1, 0b111)>;
|
||||
def : Pat<(uint_to_fp (i64 (zexti32 GPR:$rs1))), (FCVT_S_WU $rs1, 0b111)>;
|
||||
def : Pat<(sint_to_fp (i64 GPR:$rs1)), (FCVT_S_L $rs1, 0b111)>;
|
||||
def : Pat<(uint_to_fp (i64 GPR:$rs1)), (FCVT_S_LU $rs1, 0b111)>;
|
||||
|
@ -91,6 +91,6 @@ def : Pat<(and (riscv_remuw (assertzexti32 GPR:$rs1),
|
||||
// Although the sexti32 operands may not have originated from an i32 srem,
|
||||
// this pattern is safe as it is impossible for two sign extended inputs to
|
||||
// produce a result where res[63:32]=0 and res[31]=1.
|
||||
def : Pat<(srem (sexti32 GPR:$rs1), (sexti32 GPR:$rs2)),
|
||||
def : Pat<(srem (sexti32 (i64 GPR:$rs1)), (sexti32 (i64 GPR:$rs2))),
|
||||
(REMW GPR:$rs1, GPR:$rs2)>;
|
||||
} // Predicates = [HasStdExtM, IsRV64]
|
||||
|
@ -357,7 +357,7 @@ def : Pat<(i64 (fp_to_sint FPR16:$rs1)), (FCVT_L_H $rs1, 0b001)>;
|
||||
def : Pat<(i64 (fp_to_uint FPR16:$rs1)), (FCVT_LU_H $rs1, 0b001)>;
|
||||
|
||||
// [u]int->fp. Match GCC and default to using dynamic rounding mode.
|
||||
def : Pat<(sint_to_fp (i64 (sexti32 GPR:$rs1))), (FCVT_H_W $rs1, 0b111)>;
|
||||
def : Pat<(sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_H_W $rs1, 0b111)>;
|
||||
def : Pat<(uint_to_fp (i64 (zexti32 GPR:$rs1))), (FCVT_H_WU $rs1, 0b111)>;
|
||||
def : Pat<(sint_to_fp (i64 GPR:$rs1)), (FCVT_H_L $rs1, 0b111)>;
|
||||
def : Pat<(uint_to_fp (i64 GPR:$rs1)), (FCVT_H_LU $rs1, 0b111)>;
|
||||
|
@ -1109,7 +1109,7 @@ define signext i16 @sext_remw_sext_sext_i16(i16 signext %a, i16 signext %b) noun
|
||||
define signext i32 @sext_i32_remw_zext_sext_i16(i16 zeroext %0, i16 signext %1) nounwind {
|
||||
; RV64IM-LABEL: sext_i32_remw_zext_sext_i16:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: rem a0, a0, a1
|
||||
; RV64IM-NEXT: remw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%3 = sext i16 %1 to i32
|
||||
%4 = zext i16 %0 to i32
|
||||
@ -1120,7 +1120,7 @@ define signext i32 @sext_i32_remw_zext_sext_i16(i16 zeroext %0, i16 signext %1)
|
||||
define signext i32 @sext_i32_remw_sext_zext_i16(i16 signext %a, i16 zeroext %b) nounwind {
|
||||
; RV64IM-LABEL: sext_i32_remw_sext_zext_i16:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: rem a0, a0, a1
|
||||
; RV64IM-NEXT: remw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = sext i16 %a to i32
|
||||
%2 = zext i16 %b to i32
|
||||
|
Loading…
Reference in New Issue
Block a user