[llvm] b0785cd - [GlobalISel][ARM] Support missing case for G_CONSTANT (#80555)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 6 21:53:25 PST 2024


Author: Serge Pavlov
Date: 2024-02-07T12:53:20+07:00
New Revision: b0785cd1cbf97dbd4eb39647ff22771ef0a7cfea

URL: https://github.com/llvm/llvm-project/commit/b0785cd1cbf97dbd4eb39647ff22771ef0a7cfea
DIFF: https://github.com/llvm/llvm-project/commit/b0785cd1cbf97dbd4eb39647ff22771ef0a7cfea.diff

LOG: [GlobalISel][ARM] Support missing case for G_CONSTANT (#80555)

Global Instruction Selector could not select the code:

    %0:gprb(s32) = G_CONSTANT i32 -1

In DAG selector the similar code is selected to the instruction MVNi
using custom operand `mod_imm_not`. Changing its definition from
`PatLeaf` to `ImmLeaf` and providing counterpart for `imm_not_XFORM`
make the relevant rule available for GlobalISel too.

Added: 
    llvm/test/CodeGen/ARM/GlobalISel/select-const.mir

Modified: 
    llvm/lib/Target/ARM/ARMInstrInfo.td
    llvm/lib/Target/ARM/ARMInstructionSelector.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 812b5730875d5..074dea36b6414 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -379,6 +379,8 @@ def imm_neg_XFORM : SDNodeXForm<imm, [{
 def imm_not_XFORM : SDNodeXForm<imm, [{
   return CurDAG->getTargetConstant(~(int)N->getZExtValue(), SDLoc(N), MVT::i32);
 }]>;
+def gi_imm_not_XFORM : GICustomOperandRenderer<"renderInvertedImm">,
+  GISDNodeXFormEquiv<imm_not_XFORM>;
 
 // asr_imm_XFORM - Returns a shift immediate with bit {5} set to 1
 def asr_imm_XFORM : SDNodeXForm<imm, [{
@@ -830,8 +832,8 @@ def mod_imm : Operand<i32>, ImmLeaf<i32, [{
 // instructions, which use mod_imm.
 
 def ModImmNotAsmOperand : AsmOperandClass { let Name = "ModImmNot"; }
-def mod_imm_not : Operand<i32>, PatLeaf<(imm), [{
-    return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
+def mod_imm_not : Operand<i32>, ImmLeaf<i32, [{
+    return ARM_AM::getSOImmVal(~(uint32_t)Imm) != -1;
   }], imm_not_XFORM> {
   let ParserMatchClass = ModImmNotAsmOperand;
 }

diff  --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
index f391058a70514..3b3c380e1e1b3 100644
--- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
+++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
@@ -142,6 +142,8 @@ class ARMInstructionSelector : public InstructionSelector {
                        int OpIdx = -1) const;
   void renderVFPF64Imm(MachineInstrBuilder &New, const MachineInstr &Old,
                        int OpIdx = -1) const;
+  void renderInvertedImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
+                         int OpIdx = -1) const;
 
 #define GET_GLOBALISEL_PREDICATES_DECL
 #include "ARMGenGlobalISel.inc"
@@ -835,6 +837,15 @@ void ARMInstructionSelector::renderVFPF64Imm(
   NewInstBuilder.addImm(FPImmEncoding);
 }
 
+void ARMInstructionSelector::renderInvertedImm(MachineInstrBuilder &MIB,
+                                               const MachineInstr &MI,
+                                               int OpIdx) const {
+  assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
+         "Expected G_CONSTANT");
+  int64_t CVal = MI.getOperand(1).getCImm()->getSExtValue();
+  MIB.addImm(~CVal);
+}
+
 bool ARMInstructionSelector::select(MachineInstr &I) {
   assert(I.getParent() && "Instruction should be in a basic block!");
   assert(I.getParent()->getParent() && "Instruction should be in a function!");

diff  --git a/llvm/test/CodeGen/ARM/GlobalISel/select-const.mir b/llvm/test/CodeGen/ARM/GlobalISel/select-const.mir
new file mode 100644
index 0000000000000..5a1ea32a91c9e
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/GlobalISel/select-const.mir
@@ -0,0 +1,25 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -mtriple arm-- -mattr=+v6 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            get_inverted
+legalized:       true
+regBankSelected: true
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gprb }
+body:             |
+  bb.0:
+    liveins: $r0
+    ; CHECK-LABEL: name: get_inverted
+    ; CHECK: liveins: $r0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[MVNi:%[0-9]+]]:gpr = MVNi 0, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r0 = COPY [[MVNi]]
+    ; CHECK-NEXT: MOVPCLR 14 /* CC::al */, $noreg, implicit $r0
+    %0:gprb(s32) = G_CONSTANT i32 -1
+    $r0 = COPY %0(s32)
+    MOVPCLR 14 /* CC::al */, $noreg, implicit $r0
+
+...


        


More information about the llvm-commits mailing list