Skip to content

Commit e4af9de

Browse files
Petar AvramovicPetar Avramovic
authored andcommitted
[MIPS GlobalISel] Select MSA vector generic and builtin add
Select vector G_ADD for MIPS32 with MSA. We have to set bank for vector operands to fprb and selectImpl will do the rest. __builtin_msa_addv_<format> will be transformed into G_ADD in legalizeIntrinsic and selected in the same way. __builtin_msa_addvi_<format> will be directly selected into ADDVI_<format> in legalizeIntrinsic. MIR tests for it have unnecessary additional copies. Capture current state of tests with run-pass=legalizer with a test in test/CodeGen/MIR/Mips. Differential Revision: https://reviews.llvm.org/D68984 llvm-svn: 375501
1 parent e5dd30f commit e4af9de

File tree

10 files changed

+963
-2
lines changed

10 files changed

+963
-2
lines changed

llvm/lib/Target/Mips/MipsLegalizerInfo.cpp

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ CheckTy0Ty1MemSizeAlign(const LegalityQuery &Query,
4141
return false;
4242
}
4343

44+
static bool CheckTyN(unsigned N, const LegalityQuery &Query,
45+
std::initializer_list<LLT> SupportedValues) {
46+
for (auto &Val : SupportedValues)
47+
if (Val == Query.Types[N])
48+
return true;
49+
return false;
50+
}
51+
4452
MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
4553
using namespace TargetOpcode;
4654

@@ -53,10 +61,20 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
5361
const LLT v2s64 = LLT::vector(2, 64);
5462
const LLT p0 = LLT::pointer(0, 32);
5563

56-
getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL})
64+
getActionDefinitionsBuilder({G_SUB, G_MUL})
5765
.legalFor({s32})
5866
.clampScalar(0, s32, s32);
5967

68+
getActionDefinitionsBuilder(G_ADD)
69+
.legalIf([=, &ST](const LegalityQuery &Query) {
70+
if (CheckTyN(0, Query, {s32}))
71+
return true;
72+
if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
73+
return true;
74+
return false;
75+
})
76+
.clampScalar(0, s32, s32);
77+
6078
getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE, G_UMULO})
6179
.lowerFor({{s32, s1}});
6280

@@ -270,6 +288,33 @@ bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI,
270288
return true;
271289
}
272290

291+
static bool SelectMSA3OpIntrinsic(MachineInstr &MI, unsigned Opcode,
292+
MachineIRBuilder &MIRBuilder,
293+
const MipsSubtarget &ST) {
294+
assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
295+
if (!MIRBuilder.buildInstr(Opcode)
296+
.add(MI.getOperand(0))
297+
.add(MI.getOperand(2))
298+
.add(MI.getOperand(3))
299+
.constrainAllUses(MIRBuilder.getTII(), *ST.getRegisterInfo(),
300+
*ST.getRegBankInfo()))
301+
return false;
302+
MI.eraseFromParent();
303+
return true;
304+
}
305+
306+
static bool MSA3OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
307+
MachineIRBuilder &MIRBuilder,
308+
const MipsSubtarget &ST) {
309+
assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
310+
MIRBuilder.buildInstr(Opcode)
311+
.add(MI.getOperand(0))
312+
.add(MI.getOperand(2))
313+
.add(MI.getOperand(3));
314+
MI.eraseFromParent();
315+
return true;
316+
}
317+
273318
bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
274319
MachineRegisterInfo &MRI,
275320
MachineIRBuilder &MIRBuilder) const {
@@ -306,6 +351,19 @@ bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
306351
MI.eraseFromParent();
307352
return true;
308353
}
354+
case Intrinsic::mips_addv_b:
355+
case Intrinsic::mips_addv_h:
356+
case Intrinsic::mips_addv_w:
357+
case Intrinsic::mips_addv_d:
358+
return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_ADD, MIRBuilder, ST);
359+
case Intrinsic::mips_addvi_b:
360+
return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_B, MIRBuilder, ST);
361+
case Intrinsic::mips_addvi_h:
362+
return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_H, MIRBuilder, ST);
363+
case Intrinsic::mips_addvi_w:
364+
return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_W, MIRBuilder, ST);
365+
case Intrinsic::mips_addvi_d:
366+
return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_D, MIRBuilder, ST);
309367
default:
310368
break;
311369
}

llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,6 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
437437

438438
switch (Opc) {
439439
case G_TRUNC:
440-
case G_ADD:
441440
case G_SUB:
442441
case G_MUL:
443442
case G_UMULH:
@@ -460,6 +459,11 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
460459
case G_VASTART:
461460
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
462461
break;
462+
case G_ADD:
463+
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
464+
if (Op0Size == 128)
465+
OperandsMapping = getMSAMapping(MF);
466+
break;
463467
case G_STORE:
464468
case G_LOAD:
465469
if (Op0Size == 128) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -mcpu=mips32r5 -mattr=+msa,+fp64,+nan2008 -stop-after=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=P5600
3+
4+
; Check there are no COPY instructions surrounding ADDVI_W instruction.
5+
; All virtual registers were created with createGenericVirtualRegister
6+
; which sets RegClassOrRegBank in VRegInfo.
7+
; Constraining register classes when G_INTRINSIC intrinsic(@llvm.mips.addvi.w)
8+
; gets selected into ADDVI_W works as expected.
9+
; Check that setRegClassOrRegBank.mir has same output.
10+
11+
declare <4 x i32> @llvm.mips.addvi.w(<4 x i32>, i32 immarg)
12+
define void @add_v4i32_builtin_imm(<4 x i32>* %a, <4 x i32>* %c) {
13+
; P5600-LABEL: name: add_v4i32_builtin_imm
14+
; P5600: bb.1.entry:
15+
; P5600: liveins: $a0, $a1
16+
; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
17+
; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
18+
; P5600: [[LOAD:%[0-9]+]]:msa128w(<4 x s32>) = G_LOAD [[COPY]](p0) :: (load 16 from %ir.a)
19+
; P5600: [[ADDVI_W:%[0-9]+]]:msa128w(<4 x s32>) = ADDVI_W [[LOAD]](<4 x s32>), 25
20+
; P5600: G_STORE [[ADDVI_W]](<4 x s32>), [[COPY1]](p0) :: (store 16 into %ir.c)
21+
; P5600: RetRA
22+
entry:
23+
%0 = load <4 x i32>, <4 x i32>* %a, align 16
24+
%1 = tail call <4 x i32> @llvm.mips.addvi.w(<4 x i32> %0, i32 25)
25+
store <4 x i32> %1, <4 x i32>* %c, align 16
26+
ret void
27+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r5 -mattr=+msa,+fp64,+nan2008 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=P5600
3+
4+
# Check there are COPY instructions surrounding ADDVI_W instruction.
5+
# MIParser does not set RegClassOrRegBank for parsed virtual registers.
6+
# Constraining register classes when G_INTRINSIC intrinsic(@llvm.mips.addvi.w)
7+
# gets selected into ADDVI_W creates additional copies.
8+
# FixMe: Make sure this test has same output as setRegClassOrRegBank.ll.
9+
10+
--- |
11+
12+
declare <4 x i32> @llvm.mips.addvi.w(<4 x i32>, i32 immarg)
13+
define void @add_v4i32_builtin_imm(<4 x i32>* %a, <4 x i32>* %c) { entry: ret void }
14+
15+
...
16+
---
17+
name: add_v4i32_builtin_imm
18+
alignment: 4
19+
tracksRegLiveness: true
20+
body: |
21+
bb.1.entry:
22+
liveins: $a0, $a1
23+
24+
; P5600-LABEL: name: add_v4i32_builtin_imm
25+
; P5600: liveins: $a0, $a1
26+
; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
27+
; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
28+
; P5600: [[LOAD:%[0-9]+]]:_(<4 x s32>) = G_LOAD [[COPY]](p0) :: (load 16 from %ir.a)
29+
; P5600: [[COPY2:%[0-9]+]]:msa128w = COPY [[LOAD]](<4 x s32>)
30+
; P5600: [[ADDVI_W:%[0-9]+]]:msa128w = ADDVI_W [[COPY2]], 25
31+
; P5600: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY [[ADDVI_W]]
32+
; P5600: G_STORE [[COPY3]](<4 x s32>), [[COPY1]](p0) :: (store 16 into %ir.c)
33+
; P5600: RetRA
34+
%0:_(p0) = COPY $a0
35+
%1:_(p0) = COPY $a1
36+
%2:_(<4 x s32>) = G_LOAD %0(p0) :: (load 16 from %ir.a)
37+
%3:_(<4 x s32>) = G_INTRINSIC intrinsic(@llvm.mips.addvi.w), %2(<4 x s32>), 25
38+
G_STORE %3(<4 x s32>), %1(p0) :: (store 16 into %ir.c)
39+
RetRA
40+
41+
...
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r5 -mattr=+msa,+fp64,+nan2008 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=P5600
3+
--- |
4+
5+
define void @add_v16i8(<16 x i8>* %a, <16 x i8>* %b, <16 x i8>* %c) { entry: ret void }
6+
define void @add_v8i16(<8 x i16>* %a, <8 x i16>* %b, <8 x i16>* %c) { entry: ret void }
7+
define void @add_v4i32(<4 x i32>* %a, <4 x i32>* %b, <4 x i32>* %c) { entry: ret void }
8+
define void @add_v2i64(<2 x i64>* %a, <2 x i64>* %b, <2 x i64>* %c) { entry: ret void }
9+
10+
...
11+
---
12+
name: add_v16i8
13+
alignment: 4
14+
legalized: true
15+
regBankSelected: true
16+
tracksRegLiveness: true
17+
body: |
18+
bb.1.entry:
19+
liveins: $a0, $a1, $a2
20+
21+
; P5600-LABEL: name: add_v16i8
22+
; P5600: liveins: $a0, $a1, $a2
23+
; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
24+
; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
25+
; P5600: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
26+
; P5600: [[LD_B:%[0-9]+]]:msa128b = LD_B [[COPY]], 0 :: (load 16 from %ir.a)
27+
; P5600: [[LD_B1:%[0-9]+]]:msa128b = LD_B [[COPY1]], 0 :: (load 16 from %ir.b)
28+
; P5600: [[ADDV_B:%[0-9]+]]:msa128b = ADDV_B [[LD_B1]], [[LD_B]]
29+
; P5600: ST_B [[ADDV_B]], [[COPY2]], 0 :: (store 16 into %ir.c)
30+
; P5600: RetRA
31+
%0:gprb(p0) = COPY $a0
32+
%1:gprb(p0) = COPY $a1
33+
%2:gprb(p0) = COPY $a2
34+
%3:fprb(<16 x s8>) = G_LOAD %0(p0) :: (load 16 from %ir.a)
35+
%4:fprb(<16 x s8>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
36+
%5:fprb(<16 x s8>) = G_ADD %4, %3
37+
G_STORE %5(<16 x s8>), %2(p0) :: (store 16 into %ir.c)
38+
RetRA
39+
40+
...
41+
---
42+
name: add_v8i16
43+
alignment: 4
44+
legalized: true
45+
regBankSelected: true
46+
tracksRegLiveness: true
47+
body: |
48+
bb.1.entry:
49+
liveins: $a0, $a1, $a2
50+
51+
; P5600-LABEL: name: add_v8i16
52+
; P5600: liveins: $a0, $a1, $a2
53+
; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
54+
; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
55+
; P5600: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
56+
; P5600: [[LD_H:%[0-9]+]]:msa128h = LD_H [[COPY]], 0 :: (load 16 from %ir.a)
57+
; P5600: [[LD_H1:%[0-9]+]]:msa128h = LD_H [[COPY1]], 0 :: (load 16 from %ir.b)
58+
; P5600: [[ADDV_H:%[0-9]+]]:msa128h = ADDV_H [[LD_H1]], [[LD_H]]
59+
; P5600: ST_H [[ADDV_H]], [[COPY2]], 0 :: (store 16 into %ir.c)
60+
; P5600: RetRA
61+
%0:gprb(p0) = COPY $a0
62+
%1:gprb(p0) = COPY $a1
63+
%2:gprb(p0) = COPY $a2
64+
%3:fprb(<8 x s16>) = G_LOAD %0(p0) :: (load 16 from %ir.a)
65+
%4:fprb(<8 x s16>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
66+
%5:fprb(<8 x s16>) = G_ADD %4, %3
67+
G_STORE %5(<8 x s16>), %2(p0) :: (store 16 into %ir.c)
68+
RetRA
69+
70+
...
71+
---
72+
name: add_v4i32
73+
alignment: 4
74+
legalized: true
75+
regBankSelected: true
76+
tracksRegLiveness: true
77+
body: |
78+
bb.1.entry:
79+
liveins: $a0, $a1, $a2
80+
81+
; P5600-LABEL: name: add_v4i32
82+
; P5600: liveins: $a0, $a1, $a2
83+
; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
84+
; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
85+
; P5600: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
86+
; P5600: [[LD_W:%[0-9]+]]:msa128w = LD_W [[COPY]], 0 :: (load 16 from %ir.a)
87+
; P5600: [[LD_W1:%[0-9]+]]:msa128w = LD_W [[COPY1]], 0 :: (load 16 from %ir.b)
88+
; P5600: [[ADDV_W:%[0-9]+]]:msa128w = ADDV_W [[LD_W1]], [[LD_W]]
89+
; P5600: ST_W [[ADDV_W]], [[COPY2]], 0 :: (store 16 into %ir.c)
90+
; P5600: RetRA
91+
%0:gprb(p0) = COPY $a0
92+
%1:gprb(p0) = COPY $a1
93+
%2:gprb(p0) = COPY $a2
94+
%3:fprb(<4 x s32>) = G_LOAD %0(p0) :: (load 16 from %ir.a)
95+
%4:fprb(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
96+
%5:fprb(<4 x s32>) = G_ADD %4, %3
97+
G_STORE %5(<4 x s32>), %2(p0) :: (store 16 into %ir.c)
98+
RetRA
99+
100+
...
101+
---
102+
name: add_v2i64
103+
alignment: 4
104+
legalized: true
105+
regBankSelected: true
106+
tracksRegLiveness: true
107+
body: |
108+
bb.1.entry:
109+
liveins: $a0, $a1, $a2
110+
111+
; P5600-LABEL: name: add_v2i64
112+
; P5600: liveins: $a0, $a1, $a2
113+
; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
114+
; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
115+
; P5600: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
116+
; P5600: [[LD_D:%[0-9]+]]:msa128d = LD_D [[COPY]], 0 :: (load 16 from %ir.a)
117+
; P5600: [[LD_D1:%[0-9]+]]:msa128d = LD_D [[COPY1]], 0 :: (load 16 from %ir.b)
118+
; P5600: [[ADDV_D:%[0-9]+]]:msa128d = ADDV_D [[LD_D1]], [[LD_D]]
119+
; P5600: ST_D [[ADDV_D]], [[COPY2]], 0 :: (store 16 into %ir.c)
120+
; P5600: RetRA
121+
%0:gprb(p0) = COPY $a0
122+
%1:gprb(p0) = COPY $a1
123+
%2:gprb(p0) = COPY $a2
124+
%3:fprb(<2 x s64>) = G_LOAD %0(p0) :: (load 16 from %ir.a)
125+
%4:fprb(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
126+
%5:fprb(<2 x s64>) = G_ADD %4, %3
127+
G_STORE %5(<2 x s64>), %2(p0) :: (store 16 into %ir.c)
128+
RetRA
129+
130+
...

0 commit comments

Comments
 (0)