]> granicus.if.org Git - llvm/commitdiff
[ARM GlobalISel] Import MOVi32imm into GlobalISel
authorDiana Picus <diana.picus@linaro.org>
Mon, 14 Jan 2019 12:04:08 +0000 (12:04 +0000)
committerDiana Picus <diana.picus@linaro.org>
Mon, 14 Jan 2019 12:04:08 +0000 (12:04 +0000)
Make it possible for TableGen to produce code for selecting MOVi32imm.
This allows reasonably recent ARM targets to select a lot more constants
than before.

We achieve this by adding GISelPredicateCode to arm_i32imm. It's
impossible to use the exact same code for both DAGISel and GlobalISel,
since one uses "Subtarget->" and the other "STI." to refer to the
subtarget. Moreover, in GlobalISel we don't have ready access to the
MachineFunction, so we need to add a bit of code for obtaining it from
the instruction that we're selecting. This is also the reason why it
needs to remain a PatLeaf instead of the more specific IntImmLeaf.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351056 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir

index 46bdeba6bbd3a7cf92daac733ccfbc2913bdf6ea..13abdc9687ecb3be09fb3488b5e4b5484e8633f6 100644 (file)
@@ -722,7 +722,20 @@ def arm_i32imm : PatLeaf<(imm), [{
   if (Subtarget->useMovt(*MF))
     return true;
   return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
-}]>;
+}]> {
+  // Ideally this would be an IntImmLeaf, but then we wouldn't have access to
+  // the MachineFunction.
+  let GISelPredicateCode = [{
+    const auto &MF = *MI.getParent()->getParent();
+    if (STI.useMovt(MF))
+      return true;
+
+    const auto &MO = MI.getOperand(1);
+    if (!MO.isCImm())
+      return false;
+    return ARM_AM::isSOImmTwoPartVal(MO.getCImm()->getZExtValue());
+  }];
+}
 
 /// imm0_1 predicate - Immediate in the range [0,1].
 def Imm0_1AsmOperand: ImmAsmOperand<0,1> { let Name = "Imm0_1"; }
index 4b9812c50d15b5c98c22de06a6d6b32f0fe40f14..f030a5aa01d08d779ddab1e1155faea08f672623 100644 (file)
   define void @test_stores() #0 { ret void }
 
   define void @test_gep() { ret void }
+
+  define void @test_MOVi32imm() #3 { ret void }
+
   define void @test_constant_imm() { ret void }
   define void @test_constant_cimm() { ret void }
+
   define void @test_pointer_constant_unconstrained() { ret void }
   define void @test_pointer_constant_constrained() { ret void }
 
@@ -1481,6 +1485,23 @@ body:             |
     BX_RET 14, $noreg, implicit $r0
 ...
 ---
+name:            test_MOVi32imm
+# CHECK-LABEL: name: test_MOVi32imm
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+body:             |
+  bb.0:
+    %0(s32) = G_CONSTANT 65537
+    ; CHECK: %[[C:[0-9]+]]:gpr = MOVi32imm 65537
+
+    $r0 = COPY %0(s32)
+    BX_RET 14, $noreg, implicit $r0
+...
+---
 name:            test_constant_imm
 # CHECK-LABEL: name: test_constant_imm
 legalized:       true