From 0144de52621146df4756cc3ed6fc7b527e215c4b Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Wed, 1 Jun 2016 12:01:01 +0000 Subject: [PATCH] [ARM] Add additional matching for UBFX instructions This adds an additional matcher to select UBFX(..) from SRL(AND(..)) in ARMISelDAGToDAG to help with code size. Patch by David Green. Differential Revision: http://reviews.llvm.org/D20667 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271384 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 21 +++++++++++++++++++++ test/CodeGen/ARM/bfx.ll | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index ac86e0bafaf..0aacd674d62 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -2418,6 +2418,27 @@ bool ARMDAGToDAGISel::tryV6T2BitfieldExtractOp(SDNode *N, bool isSigned) { } } + // Or we are looking for a shift of an and, with a mask operand + if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, And_imm) && + isShiftedMask_32(And_imm)) { + unsigned Srl_imm = 0; + unsigned LSB = countTrailingZeros(And_imm); + // Shift must be the same as the ands lsb + if (isInt32Immediate(N->getOperand(1), Srl_imm) && Srl_imm == LSB) { + assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); + unsigned MSB = 31 - countLeadingZeros(And_imm); + // Note: The width operand is encoded as width-1. + unsigned Width = MSB - LSB; + SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); + SDValue Ops[] = { N->getOperand(0).getOperand(0), + CurDAG->getTargetConstant(Srl_imm, dl, MVT::i32), + CurDAG->getTargetConstant(Width, dl, MVT::i32), + getAL(CurDAG, dl), Reg0 }; + CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); + return true; + } + } + if (N->getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned Width = cast(N->getOperand(1))->getVT().getSizeInBits(); unsigned LSB = 0; diff --git a/test/CodeGen/ARM/bfx.ll b/test/CodeGen/ARM/bfx.ll index edb0c1a5a54..629060218e4 100644 --- a/test/CodeGen/ARM/bfx.ll +++ b/test/CodeGen/ARM/bfx.ll @@ -51,3 +51,19 @@ entry: %add7 = add i32 %add, %2 ret i32 %add7 } + +define i32 @ubfx3(i32 %a) { +; CHECK: ubfx3 +; CHECK: ubfx r0, r0, #11, #1 + %t1 = and i32 %a, 2048 + %t2 = lshr i32 %t1, 11 + ret i32 %t2 +} + +define i32 @ubfx4(i32 %a) { +; CHECK: ubfx4 +; CHECK: ubfx r0, r0, #7, #3 + %t1 = and i32 %a, 896 + %t2 = lshr i32 %t1, 7 + ret i32 %t2 +}