summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-08-30 02:44:00 +0000
committerNate Begeman <natebegeman@mac.com>2005-08-30 02:44:00 +0000
commit43144a2fe04beaac68c7235d02c03c7862a411d9 (patch)
tree92cc9dd9b6080e7131229494d8eee6a058f27e7f /llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parentc9d1e370a538c09971f390abcb5b0645551956c2 (diff)
downloadbcm5719-llvm-43144a2fe04beaac68c7235d02c03c7862a411d9.tar.gz
bcm5719-llvm-43144a2fe04beaac68c7235d02c03c7862a411d9.zip
Add support for AssertSext and AssertZext, folding other extensions with
them. This allows for elminination of redundant extends in the entry blocks of functions on PowerPC. Add support for i32 x i32 -> i64 multiplies, by recognizing when the inputs to ISD::MUL in ExpandOp are actually just extended i32 values and not real i64 values. this allows us to codegen int mulhs(int a, int b) { return ((long long)a * b) >> 32; } as: _mulhs: mulhw r3, r4, r3 blr instead of: _mulhs: mulhwu r2, r4, r3 srawi r5, r3, 31 mullw r5, r4, r5 add r2, r2, r5 srawi r4, r4, 31 mullw r3, r4, r3 add r3, r2, r3 blr with a similar improvement on x86. llvm-svn: 23147
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index dab757ef8a2..c929806ed11 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -631,7 +631,8 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy);
MVT::ValueType ExtDstTy = N1.getValueType();
unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy);
-
+
+ if (Cond == ISD::SETEQ || Cond == ISD::SETNE) {
// If the extended part has any inconsistent bits, it cannot ever
// compare equal. In other words, they have to be all ones or all
// zeros.
@@ -644,6 +645,7 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy),
getConstant(C2 & (~0ULL >> 64-ExtSrcTyBits), ExtDstTy),
Cond);
+ }
}
uint64_t MinVal, MaxVal;
@@ -1192,6 +1194,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
assert(EVT <= VT && "Not rounding down!");
break;
}
+ case ISD::AssertSext:
+ case ISD::AssertZext:
case ISD::SIGN_EXTEND_INREG: {
MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
assert(VT == N1.getValueType() && "Not an inreg extend!");
@@ -1394,6 +1398,14 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
// we know the result of the AND will be the AND mask itself.
return N2;
}
+ } else if (N1.getOpcode() == ISD::AssertZext) {
+ // If we are masking out the part of our input that was already masked
+ // out, just return the input directly.
+ unsigned ExtendBits =
+ MVT::getSizeInBits(cast<VTSDNode>(N1.getOperand(1))->getVT());
+ uint64_t ExtendMask = (1ULL << ExtendBits) - 1;
+ if (ExtendMask == C2)
+ return N1.getOperand(0);
}
break;
case ISD::OR:
@@ -1579,14 +1591,15 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
if (EVT == VT) return N1; // Not actually extending
// If we are sign extending an extension, use the original source.
- if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
+ if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG ||
+ N1.getOpcode() == ISD::AssertSext)
if (cast<VTSDNode>(N1.getOperand(1))->getVT() <= EVT)
return N1;
// If we are sign extending a sextload, return just the load.
if (N1.getOpcode() == ISD::SEXTLOAD)
if (cast<VTSDNode>(N1.getOperand(3))->getVT() <= EVT)
- return N1;
+ return N1;
// If we are extending the result of a setcc, and we already know the
// contents of the top bits, eliminate the extension.
@@ -1594,7 +1607,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
TLI.getSetCCResultContents() ==
TargetLowering::ZeroOrNegativeOneSetCCResult)
return N1;
-
+
// If we are sign extending the result of an (and X, C) operation, and we
// know the extended bits are zeros already, don't do the extend.
if (N1.getOpcode() == ISD::AND)
@@ -2195,6 +2208,8 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::VALUETYPE: return "ValueType";
case ISD::EntryToken: return "EntryToken";
case ISD::TokenFactor: return "TokenFactor";
+ case ISD::AssertSext: return "AssertSext";
+ case ISD::AssertZext: return "AssertZext";
case ISD::Constant: return "Constant";
case ISD::TargetConstant: return "TargetConstant";
case ISD::ConstantFP: return "ConstantFP";
OpenPOWER on IntegriCloud