summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAlex Bradbury <asb@lowrisc.org>2018-11-30 09:56:54 +0000
committerAlex Bradbury <asb@lowrisc.org>2018-11-30 09:56:54 +0000
commite0e62e97dfddb01a6f2e32d2f951c317a7478f9a (patch)
tree258079ea1dc9509b8bfb1fc63de9a416143bbb04 /llvm/lib
parentdeaa3e2068cf14834e4063729887bb19eb4a9c2d (diff)
downloadbcm5719-llvm-e0e62e97dfddb01a6f2e32d2f951c317a7478f9a.tar.gz
bcm5719-llvm-e0e62e97dfddb01a6f2e32d2f951c317a7478f9a.zip
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp18
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h14
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp4
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.h1
4 files changed, 27 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 2b1df0165d3..b55a73253c7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -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:
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 8b7c57cbb3b..5bb5995e35c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -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);
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d8c63a4020f..15fd29e8f45 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -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.
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index a99e2c2f53b..6970900bb06 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -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;
OpenPOWER on IntegriCloud