[llvm] r271384 - [ARM] Add additional matching for UBFX instructions

Oliver Stannard via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 1 05:20:45 PDT 2016


Author: olista01
Date: Wed Jun  1 07:01:01 2016
New Revision: 271384

URL: http://llvm.org/viewvc/llvm-project?rev=271384&view=rev
Log:
[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


Modified:
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/ARM/bfx.ll

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=271384&r1=271383&r2=271384&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed Jun  1 07:01:01 2016
@@ -2418,6 +2418,27 @@ bool ARMDAGToDAGISel::tryV6T2BitfieldExt
     }
   }
 
+  // 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<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits();
     unsigned LSB = 0;

Modified: llvm/trunk/test/CodeGen/ARM/bfx.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/bfx.ll?rev=271384&r1=271383&r2=271384&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/bfx.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/bfx.ll Wed Jun  1 07:01:01 2016
@@ -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
+}




More information about the llvm-commits mailing list