summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@codeaurora.org>2016-06-03 20:05:49 +0000
committerChad Rosier <mcrosier@codeaurora.org>2016-06-03 20:05:49 +0000
commitbe879ea751bf04d80aa3940c49193396ff0b85c0 (patch)
tree6c67021076e854790ba086f7f5e82219a0a14b20 /llvm/lib
parent6e8511527204b2d8546393b041422ef0076977d8 (diff)
downloadbcm5719-llvm-be879ea751bf04d80aa3940c49193396ff0b85c0.tar.gz
bcm5719-llvm-be879ea751bf04d80aa3940c49193396ff0b85c0.zip
[AArch64] Spot SBFX-compatible code expressed with sign_extend.
This is very similar to r271677, but for extracts from i32 with the SIGN_EXTEND acting on a arithmetic shift. llvm-svn: 271717
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index d5f03d08c0a..dfa391916d5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -164,6 +164,7 @@ public:
void SelectPostStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc);
bool tryBitfieldExtractOp(SDNode *N);
+ bool tryBitfieldExtractOpFromSExt(SDNode *N);
bool tryBitfieldInsertOp(SDNode *N);
bool tryBitfieldInsertInZeroOp(SDNode *N);
@@ -1650,6 +1651,30 @@ static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0,
return true;
}
+bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *N) {
+ assert(N->getOpcode() == ISD::SIGN_EXTEND);
+
+ EVT VT = N->getValueType(0);
+ EVT NarrowVT = N->getOperand(0)->getValueType(0);
+ if (VT != MVT::i64 || NarrowVT != MVT::i32)
+ return false;
+
+ uint64_t ShiftImm;
+ SDValue Op = N->getOperand(0);
+ if (!isOpcWithIntImmediate(Op.getNode(), ISD::SRA, ShiftImm))
+ return false;
+
+ SDLoc dl(N);
+ // Extend the incoming operand of the shift to 64-bits.
+ SDValue Opd0 = Widen(CurDAG, Op.getOperand(0));
+ unsigned Immr = ShiftImm;
+ unsigned Imms = NarrowVT.getSizeInBits() - 1;
+ SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
+ CurDAG->getTargetConstant(Imms, dl, VT)};
+ CurDAG->SelectNodeTo(N, AArch64::SBFMXri, VT, Ops);
+ return true;
+}
+
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc,
SDValue &Opd0, unsigned &Immr, unsigned &Imms,
unsigned NumberOfIgnoredLowBits = 0,
@@ -2588,6 +2613,11 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) {
return;
break;
+ case ISD::SIGN_EXTEND:
+ if (tryBitfieldExtractOpFromSExt(Node))
+ return;
+ break;
+
case ISD::OR:
if (tryBitfieldInsertOp(Node))
return;
OpenPOWER on IntegriCloud