Skip to content

Commit b0785cd

Browse files
authored
[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.
1 parent adbf21f commit b0785cd

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ def imm_neg_XFORM : SDNodeXForm<imm, [{
379379
def imm_not_XFORM : SDNodeXForm<imm, [{
380380
return CurDAG->getTargetConstant(~(int)N->getZExtValue(), SDLoc(N), MVT::i32);
381381
}]>;
382+
def gi_imm_not_XFORM : GICustomOperandRenderer<"renderInvertedImm">,
383+
GISDNodeXFormEquiv<imm_not_XFORM>;
382384

383385
// asr_imm_XFORM - Returns a shift immediate with bit {5} set to 1
384386
def asr_imm_XFORM : SDNodeXForm<imm, [{
@@ -830,8 +832,8 @@ def mod_imm : Operand<i32>, ImmLeaf<i32, [{
830832
// instructions, which use mod_imm.
831833

832834
def ModImmNotAsmOperand : AsmOperandClass { let Name = "ModImmNot"; }
833-
def mod_imm_not : Operand<i32>, PatLeaf<(imm), [{
834-
return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
835+
def mod_imm_not : Operand<i32>, ImmLeaf<i32, [{
836+
return ARM_AM::getSOImmVal(~(uint32_t)Imm) != -1;
835837
}], imm_not_XFORM> {
836838
let ParserMatchClass = ModImmNotAsmOperand;
837839
}

llvm/lib/Target/ARM/ARMInstructionSelector.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ class ARMInstructionSelector : public InstructionSelector {
142142
int OpIdx = -1) const;
143143
void renderVFPF64Imm(MachineInstrBuilder &New, const MachineInstr &Old,
144144
int OpIdx = -1) const;
145+
void renderInvertedImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
146+
int OpIdx = -1) const;
145147

146148
#define GET_GLOBALISEL_PREDICATES_DECL
147149
#include "ARMGenGlobalISel.inc"
@@ -835,6 +837,15 @@ void ARMInstructionSelector::renderVFPF64Imm(
835837
NewInstBuilder.addImm(FPImmEncoding);
836838
}
837839

840+
void ARMInstructionSelector::renderInvertedImm(MachineInstrBuilder &MIB,
841+
const MachineInstr &MI,
842+
int OpIdx) const {
843+
assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
844+
"Expected G_CONSTANT");
845+
int64_t CVal = MI.getOperand(1).getCImm()->getSExtValue();
846+
MIB.addImm(~CVal);
847+
}
848+
838849
bool ARMInstructionSelector::select(MachineInstr &I) {
839850
assert(I.getParent() && "Instruction should be in a basic block!");
840851
assert(I.getParent()->getParent() && "Instruction should be in a function!");
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc -mtriple arm-- -mattr=+v6 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
3+
4+
---
5+
name: get_inverted
6+
legalized: true
7+
regBankSelected: true
8+
selected: false
9+
tracksRegLiveness: true
10+
registers:
11+
- { id: 0, class: gprb }
12+
body: |
13+
bb.0:
14+
liveins: $r0
15+
; CHECK-LABEL: name: get_inverted
16+
; CHECK: liveins: $r0
17+
; CHECK-NEXT: {{ $}}
18+
; CHECK-NEXT: [[MVNi:%[0-9]+]]:gpr = MVNi 0, 14 /* CC::al */, $noreg, $noreg
19+
; CHECK-NEXT: $r0 = COPY [[MVNi]]
20+
; CHECK-NEXT: MOVPCLR 14 /* CC::al */, $noreg, implicit $r0
21+
%0:gprb(s32) = G_CONSTANT i32 -1
22+
$r0 = COPY %0(s32)
23+
MOVPCLR 14 /* CC::al */, $noreg, implicit $r0
24+
25+
...

0 commit comments

Comments
 (0)