forked from OSchip/llvm-project
[TargetLowering][RISCV] Introduce isSExtCheaperThanZExt hook and implement for RISC-V
DAGTypeLegalizer::PromoteSetCCOperands currently prefers to zero-extend operands when it is able to do so. For some targets this is more expensive than a sign-extension, which is also a valid choice. Introduce the isSExtCheaperThanZExt hook and use it in the new SExtOrZExtPromotedInteger helper. On RISC-V, we prefer sign-extension for FromTy == MVT::i32 and ToTy == MVT::i64, as it can be performed using a single instruction. Differential Revision: https://reviews.llvm.org/D52978 llvm-svn: 347977
This commit is contained in:
parent
deaa3e2068
commit
e0e62e97df
|
@ -2220,6 +2220,12 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Return true if sign-extension from FromTy to ToTy is cheaper than
|
||||
/// zero-extension.
|
||||
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return true if the target supplies and combines to a paired load
|
||||
/// two loaded values of type LoadedType next to each other in memory.
|
||||
/// RequiredAlignment gives the minimal alignment constraints that must be met
|
||||
|
|
|
@ -1063,9 +1063,10 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
|
||||
void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
|
||||
ISD::CondCode CCCode) {
|
||||
// We have to insert explicit sign or zero extends. Note that we could
|
||||
// insert sign extends for ALL conditions, but zero extend is cheaper on
|
||||
// many machines (an AND instead of two shifts), so prefer it.
|
||||
// We have to insert explicit sign or zero extends. Note that we could
|
||||
// insert sign extends for ALL conditions. For those operations where either
|
||||
// zero or sign extension would be valid, use SExtOrZExtPromotedInteger
|
||||
// which will choose the cheapest for the target.
|
||||
switch (CCCode) {
|
||||
default: llvm_unreachable("Unknown integer comparison!");
|
||||
case ISD::SETEQ:
|
||||
|
@ -1086,8 +1087,8 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
|
|||
NewLHS = OpL;
|
||||
NewRHS = OpR;
|
||||
} else {
|
||||
NewLHS = ZExtPromotedInteger(NewLHS);
|
||||
NewRHS = ZExtPromotedInteger(NewRHS);
|
||||
NewLHS = SExtOrZExtPromotedInteger(NewLHS);
|
||||
NewRHS = SExtOrZExtPromotedInteger(NewRHS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1095,11 +1096,8 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
|
|||
case ISD::SETUGT:
|
||||
case ISD::SETULE:
|
||||
case ISD::SETULT:
|
||||
// ALL of these operations will work if we either sign or zero extend
|
||||
// the operands (including the unsigned comparisons!). Zero extend is
|
||||
// usually a simpler/cheaper operation, so prefer it.
|
||||
NewLHS = ZExtPromotedInteger(NewLHS);
|
||||
NewRHS = ZExtPromotedInteger(NewRHS);
|
||||
NewLHS = SExtOrZExtPromotedInteger(NewLHS);
|
||||
NewRHS = SExtOrZExtPromotedInteger(NewRHS);
|
||||
break;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETGT:
|
||||
|
|
|
@ -281,6 +281,20 @@ private:
|
|||
return DAG.getZeroExtendInReg(Op, dl, OldVT.getScalarType());
|
||||
}
|
||||
|
||||
// Get a promoted operand and sign or zero extend it to the final size
|
||||
// (depending on TargetLoweringInfo::isSExtCheaperThanZExt). For a given
|
||||
// subtarget and type, the choice of sign or zero-extension will be
|
||||
// consistent.
|
||||
SDValue SExtOrZExtPromotedInteger(SDValue Op) {
|
||||
EVT OldVT = Op.getValueType();
|
||||
SDLoc DL(Op);
|
||||
Op = GetPromotedInteger(Op);
|
||||
if (TLI.isSExtCheaperThanZExt(OldVT, Op.getValueType()))
|
||||
return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Op.getValueType(), Op,
|
||||
DAG.getValueType(OldVT));
|
||||
return DAG.getZeroExtendInReg(Op, DL, OldVT.getScalarType());
|
||||
}
|
||||
|
||||
// Integer Result Promotion.
|
||||
void PromoteIntegerResult(SDNode *N, unsigned ResNo);
|
||||
SDValue PromoteIntRes_MERGE_VALUES(SDNode *N, unsigned ResNo);
|
||||
|
|
|
@ -267,6 +267,10 @@ bool RISCVTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
|
|||
return TargetLowering::isZExtFree(Val, VT2);
|
||||
}
|
||||
|
||||
bool RISCVTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const {
|
||||
return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
|
||||
}
|
||||
|
||||
// Changes the condition code and swaps operands if necessary, so the SetCC
|
||||
// operation matches one of the comparisons supported directly in the RISC-V
|
||||
// ISA.
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
|
||||
bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
|
||||
bool isZExtFree(SDValue Val, EVT VT2) const override;
|
||||
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
|
||||
|
||||
// Provide custom lowering hooks for some operations.
|
||||
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
|
||||
|
|
|
@ -51,8 +51,7 @@ define i32 @sltiu(i32 %a) nounwind {
|
|||
;
|
||||
; RV64I-LABEL: sltiu:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sltiu a0, a0, 3
|
||||
; RV64I-NEXT: ret
|
||||
%1 = icmp ult i32 %a, 3
|
||||
|
@ -213,10 +212,8 @@ define i32 @sltu(i32 %a, i32 %b) nounwind {
|
|||
;
|
||||
; RV64I-LABEL: sltu:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a1, a1, 32
|
||||
; RV64I-NEXT: srli a1, a1, 32
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: sext.w a1, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sltu a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = icmp ult i32 %a, %b
|
||||
|
|
Loading…
Reference in New Issue