summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-10-19 16:58:59 +0000
committerSanjay Patel <spatel@rotateright.com>2016-10-19 16:58:59 +0000
commit3a3aaf67e07ade866b9500a9466086a68d0dd70c (patch)
tree15006d3cec17160af880cfd3669c039ad95dd5ea /llvm/lib/CodeGen/SelectionDAG
parent383803230bba0c0dea3d93d9eb4f97d6fa8f3718 (diff)
downloadbcm5719-llvm-3a3aaf67e07ade866b9500a9466086a68d0dd70c.tar.gz
bcm5719-llvm-3a3aaf67e07ade866b9500a9466086a68d0dd70c.zip
[DAG] optimize negation of bool
Use mask and negate for legalization of i1 source type with SIGN_EXTEND_INREG. With the mask, this should be no worse than 2 shifts. The mask can be eliminated in some cases, so that should be better than 2 shifts. This change exposed some missing folds related to negation: https://reviews.llvm.org/rL284239 https://reviews.llvm.org/rL284395 There may be others, so please let me know if you see any regressions. Differential Revision: https://reviews.llvm.org/D25485 llvm-svn: 284611
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp21
1 files changed, 19 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 66d80089fcb..c468a0fabc1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2926,10 +2926,27 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
Results.push_back(Tmp1);
break;
case ISD::SIGN_EXTEND_INREG: {
- // NOTE: we could fall back on load/store here too for targets without
- // SAR. However, it is doubtful that any exist.
EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
EVT VT = Node->getValueType(0);
+
+ // An in-register sign-extend of a boolean is a negation:
+ // 'true' (1) sign-extended is -1.
+ // 'false' (0) sign-extended is 0.
+ // However, we must mask the high bits of the source operand because the
+ // SIGN_EXTEND_INREG does not guarantee that the high bits are already zero.
+
+ // TODO: Do this for vectors too?
+ if (ExtraVT.getSizeInBits() == 1) {
+ SDValue One = DAG.getConstant(1, dl, VT);
+ SDValue And = DAG.getNode(ISD::AND, dl, VT, Node->getOperand(0), One);
+ SDValue Zero = DAG.getConstant(0, dl, VT);
+ SDValue Neg = DAG.getNode(ISD::SUB, dl, VT, Zero, And);
+ Results.push_back(Neg);
+ break;
+ }
+
+ // NOTE: we could fall back on load/store here too for targets without
+ // SRA. However, it is doubtful that any exist.
EVT ShiftAmountTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
if (VT.isVector())
ShiftAmountTy = VT;
OpenPOWER on IntegriCloud