[llvm] r213754 - ARM: spot SBFX-compatbile code expressed with sign_extend_inreg

Tim Northover tnorthover at apple.com
Wed Jul 23 06:59:12 PDT 2014


Author: tnorthover
Date: Wed Jul 23 08:59:12 2014
New Revision: 213754

URL: http://llvm.org/viewvc/llvm-project?rev=213754&view=rev
Log:
ARM: spot SBFX-compatbile code expressed with sign_extend_inreg

We were assuming all SBFX-like operations would have the shl/asr form, but
often when the field being extracted is an i8 or i16, we end up with a
SIGN_EXTEND_INREG acting on a shift instead. Simple enough to check for though.

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/ARM/sbfx.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-sxt_rot.ll

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=213754&r1=213753&r2=213754&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed Jul 23 08:59:12 2014
@@ -2361,6 +2361,25 @@ SDNode *ARMDAGToDAGISel::SelectV6T2Bitfi
       return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
     }
   }
+
+  if (N->getOpcode() == ISD::SIGN_EXTEND_INREG) {
+    unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits();
+    unsigned LSB = 0;
+    if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, LSB) &&
+        !isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRA, LSB))
+      return nullptr;
+
+    if (LSB + Width > 32)
+      return nullptr;
+
+    SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
+    SDValue Ops[] = { N->getOperand(0).getOperand(0),
+                      CurDAG->getTargetConstant(LSB, MVT::i32),
+                      CurDAG->getTargetConstant(Width - 1, MVT::i32),
+                      getAL(CurDAG), Reg0 };
+    return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
+  }
+
   return nullptr;
 }
 
@@ -2509,6 +2528,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *
     if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false))
       return I;
     break;
+  case ISD::SIGN_EXTEND_INREG:
   case ISD::SRA:
     if (SDNode *I = SelectV6T2BitfieldExtractOp(N, true))
       return I;

Modified: llvm/trunk/test/CodeGen/ARM/sbfx.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/sbfx.ll?rev=213754&r1=213753&r2=213754&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/sbfx.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/sbfx.ll Wed Jul 23 08:59:12 2014
@@ -45,3 +45,21 @@ entry:
     %tmp2 = ashr i32 %tmp, 1
     ret i32 %tmp2
 }
+
+define signext i8 @f6(i32 %a) {
+; CHECK-LABEL: f6:
+; CHECK: sbfx r0, r0, #23, #8
+
+  %tmp = lshr i32 %a, 23
+  %res = trunc i32 %tmp to i8
+  ret i8 %res
+}
+
+define signext i8 @f7(i32 %a) {
+; CHECK-LABEL: f7:
+; CHECK-NOT: sbfx
+
+  %tmp = lshr i32 %a, 25
+  %res = trunc i32 %tmp to i8
+  ret i8 %res
+}

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-sxt_rot.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-sxt_rot.ll?rev=213754&r1=213753&r2=213754&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-sxt_rot.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-sxt_rot.ll Wed Jul 23 08:59:12 2014
@@ -10,8 +10,7 @@ define i32 @test0(i8 %A) {
 
 define signext i8 @test1(i32 %A)  {
 ; CHECK-LABEL: test1:
-; CHECK: lsrs r0, r0, #8
-; CHECK: sxtb r0, r0
+; CHECK: sbfx r0, r0, #8, #8
 	%B = lshr i32 %A, 8
 	%C = shl i32 %A, 24
 	%D = or i32 %B, %C





More information about the llvm-commits mailing list