mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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
This commit is contained in:
parent
2ee1cc737e
commit
a775bf75c7
@ -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;
|
||||
|
10
test/CodeGen/AArch64/bitfield-extract.ll
Normal file
10
test/CodeGen/AArch64/bitfield-extract.ll
Normal file
@ -0,0 +1,10 @@
|
||||
; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
; CHECK: sbfx {{x[0-9]+}}, x0, #23, #9
|
||||
define i64 @test1(i32 %a) {
|
||||
%tmp = ashr i32 %a, 23
|
||||
%ext = sext i32 %tmp to i64
|
||||
%res = add i64 %ext, 1
|
||||
ret i64 %res
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user