diff options
author | Hal Finkel <hfinkel@anl.gov> | 2014-03-01 21:36:57 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2014-03-01 21:36:57 +0000 |
commit | 46043edc565288dc3dff7eba97d09922bc530549 (patch) | |
tree | a4f39e94eb424630526a094428aca2b96f15beeb /llvm/lib/Target/PowerPC/PPCISelLowering.cpp | |
parent | 228687411979c3047fb58fd5f4ed999abddd4cb4 (diff) | |
download | bcm5719-llvm-46043edc565288dc3dff7eba97d09922bc530549.tar.gz bcm5719-llvm-46043edc565288dc3dff7eba97d09922bc530549.zip |
Remove extra truncs/exts around i32 bit operations on PPC64
This generalizes the code to eliminate extra truncs/exts around i1 bit
operations to also do the same on PPC64 for i32 bit operations. This eliminates
a fairly prevalent code wart:
int foo(int a) {
return a == 5 ? 7 : 8;
}
On PPC64, because of the extension implied by the ABI, this would generate:
cmplwi 0, 3, 5
li 12, 8
li 4, 7
isel 3, 4, 12, 2
rldicl 3, 3, 0, 32
blr
where the 'rldicl 3, 3, 0, 32', the extension, is completely unnecessary. At
least for the single-BB case (which is all that the DAG combine mechanism can
handle), this unnecessary extension is no longer generated.
llvm-svn: 202600
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 94 |
1 files changed, 82 insertions, 12 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index f56f0cf84cc..7dc47be0d51 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -563,10 +563,11 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setTargetDAGCombine(ISD::BSWAP); setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); + setTargetDAGCombine(ISD::SIGN_EXTEND); + setTargetDAGCombine(ISD::ZERO_EXTEND); + setTargetDAGCombine(ISD::ANY_EXTEND); + if (Subtarget->useCRBits()) { - setTargetDAGCombine(ISD::SIGN_EXTEND); - setTargetDAGCombine(ISD::ZERO_EXTEND); - setTargetDAGCombine(ISD::ANY_EXTEND); setTargetDAGCombine(ISD::TRUNCATE); setTargetDAGCombine(ISD::SETCC); setTargetDAGCombine(ISD::SELECT_CC); @@ -7294,6 +7295,20 @@ SDValue PPCTargetLowering::DAGCombineTruncBoolExt(SDNode *N, SDNode *User = *UI; if (User != N && !Visited.count(User)) return SDValue(); + + // Make sure that we're not going to promote the non-output-value + // operand(s) or SELECT or SELECT_CC. + // FIXME: Although we could sometimes handle this, and it does occur in + // practice that one of the condition inputs to the select is also one of + // the outputs, we currently can't deal with this. + if (User->getOpcode() == ISD::SELECT) { + if (User->getOperand(0) == Inputs[i]) + return SDValue(); + } else if (User->getOpcode() == ISD::SELECT_CC) { + if (User->getOperand(0) == Inputs[i] || + User->getOperand(1) == Inputs[i]) + return SDValue(); + } } } @@ -7304,6 +7319,20 @@ SDValue PPCTargetLowering::DAGCombineTruncBoolExt(SDNode *N, SDNode *User = *UI; if (User != N && !Visited.count(User)) return SDValue(); + + // Make sure that we're not going to promote the non-output-value + // operand(s) or SELECT or SELECT_CC. + // FIXME: Although we could sometimes handle this, and it does occur in + // practice that one of the condition inputs to the select is also one of + // the outputs, we currently can't deal with this. + if (User->getOpcode() == ISD::SELECT) { + if (User->getOperand(0) == PromOps[i]) + return SDValue(); + } else if (User->getOpcode() == ISD::SELECT_CC) { + if (User->getOperand(0) == PromOps[i] || + User->getOperand(1) == PromOps[i]) + return SDValue(); + } } } @@ -7391,8 +7420,6 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, SelectionDAG &DAG = DCI.DAG; SDLoc dl(N); - assert(PPCSubTarget.useCRBits() && - "Expecting to be tracking CR bits"); // If we're tracking CR bits, we need to be careful that we don't have: // zext(binary-ops(trunc(x), trunc(y))) // or @@ -7402,11 +7429,19 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, // bits are set as required by the final extension, we still may need to do // some masking to get the proper behavior. + // This same functionality is important on PPC64 when dealing with + // 32-to-64-bit extensions; these occur often when 32-bit values are used as + // the return values of functions. Because it is so similar, it is handled + // here as well. + if (N->getValueType(0) != MVT::i32 && N->getValueType(0) != MVT::i64) return SDValue(); - if (N->getOperand(0).getValueType() != MVT::i1) + if (!((N->getOperand(0).getValueType() == MVT::i1 && + PPCSubTarget.useCRBits()) || + (N->getOperand(0).getValueType() == MVT::i32 && + PPCSubTarget.isPPC64()))) return SDValue(); if (N->getOperand(0).getOpcode() != ISD::AND && @@ -7468,6 +7503,20 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, SDNode *User = *UI; if (User != N && !Visited.count(User)) return SDValue(); + + // Make sure that we're not going to promote the non-output-value + // operand(s) or SELECT or SELECT_CC. + // FIXME: Although we could sometimes handle this, and it does occur in + // practice that one of the condition inputs to the select is also one of + // the outputs, we currently can't deal with this. + if (User->getOpcode() == ISD::SELECT) { + if (User->getOperand(0) == Inputs[i]) + return SDValue(); + } else if (User->getOpcode() == ISD::SELECT_CC) { + if (User->getOperand(0) == Inputs[i] || + User->getOperand(1) == Inputs[i]) + return SDValue(); + } } } @@ -7478,9 +7527,24 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, SDNode *User = *UI; if (User != N && !Visited.count(User)) return SDValue(); + + // Make sure that we're not going to promote the non-output-value + // operand(s) or SELECT or SELECT_CC. + // FIXME: Although we could sometimes handle this, and it does occur in + // practice that one of the condition inputs to the select is also one of + // the outputs, we currently can't deal with this. + if (User->getOpcode() == ISD::SELECT) { + if (User->getOperand(0) == PromOps[i]) + return SDValue(); + } else if (User->getOpcode() == ISD::SELECT_CC) { + if (User->getOperand(0) == PromOps[i] || + User->getOperand(1) == PromOps[i]) + return SDValue(); + } } } + unsigned PromBits = N->getOperand(0).getValueSizeInBits(); bool ReallyNeedsExt = false; if (N->getOpcode() != ISD::ANY_EXTEND) { // If all of the inputs are not already sign/zero extended, then @@ -7491,12 +7555,15 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, unsigned OpBits = Inputs[i].getOperand(0).getValueSizeInBits(); + assert(PromBits < OpBits && "Truncation not to a smaller bit count?"); + if ((N->getOpcode() == ISD::ZERO_EXTEND && !DAG.MaskedValueIsZero(Inputs[i].getOperand(0), - APInt::getHighBitsSet(OpBits, - OpBits-1))) || + APInt::getHighBitsSet(OpBits, + OpBits-PromBits))) || (N->getOpcode() == ISD::SIGN_EXTEND && - DAG.ComputeNumSignBits(Inputs[i].getOperand(0)) != OpBits)) { + DAG.ComputeNumSignBits(Inputs[i].getOperand(0)) < + (OpBits-(PromBits-1)))) { ReallyNeedsExt = true; break; } @@ -7580,16 +7647,19 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, if (!ReallyNeedsExt) return N->getOperand(0); - // To zero extend, just mask off everything except for the first bit. + // To zero extend, just mask off everything except for the first bit (in the + // i1 case). if (N->getOpcode() == ISD::ZERO_EXTEND) return DAG.getNode(ISD::AND, dl, N->getValueType(0), N->getOperand(0), - DAG.getConstant(1, N->getValueType(0))); + DAG.getConstant(APInt::getLowBitsSet( + N->getValueSizeInBits(0), PromBits), + N->getValueType(0))); assert(N->getOpcode() == ISD::SIGN_EXTEND && "Invalid extension type"); EVT ShiftAmountTy = getShiftAmountTy(N->getValueType(0)); SDValue ShiftCst = - DAG.getConstant(N->getValueSizeInBits(0)-1, ShiftAmountTy); + DAG.getConstant(N->getValueSizeInBits(0)-PromBits, ShiftAmountTy); return DAG.getNode(ISD::SRA, dl, N->getValueType(0), DAG.getNode(ISD::SHL, dl, N->getValueType(0), N->getOperand(0), ShiftCst), ShiftCst); |