Skip to content

Commit 0a37163

Browse files
author
Jessica Paquette
committed
[GlobalISel] Add scalar widening for G_MERGE_VALUES destination
This adds support for the case where WideSize = DstSize + K * SrcSize In this case, we can pad the G_MERGE_VALUES instruction with K extra undef values with width SrcSize. Then the destination can be handled via widenScalarDst. Differential Revision: https://reviews.llvm.org/D106814
1 parent 69daca0 commit 0a37163

File tree

3 files changed

+168
-8
lines changed

3 files changed

+168
-8
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,10 @@ class LegalizerHelper {
165165
Register widenWithUnmerge(LLT WideTy, Register OrigReg);
166166

167167
private:
168-
LegalizeResult
169-
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
168+
LegalizeResult widenScalarSrcMergeValues(MachineInstr &MI, LLT WideTy);
169+
LegalizeResult widenScalarDstMergeValues(MachineInstr &MI, LLT WideTy);
170+
LegalizeResult widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
171+
LLT WideTy);
170172
LegalizeResult
171173
widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
172174
LegalizeResult

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,11 +1418,7 @@ void LegalizerHelper::bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx) {
14181418
}
14191419

14201420
LegalizerHelper::LegalizeResult
1421-
LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
1422-
LLT WideTy) {
1423-
if (TypeIdx != 1)
1424-
return UnableToLegalize;
1425-
1421+
LegalizerHelper::widenScalarSrcMergeValues(MachineInstr &MI, LLT WideTy) {
14261422
Register DstReg = MI.getOperand(0).getReg();
14271423
LLT DstTy = MRI.getType(DstReg);
14281424
if (DstTy.isVector())
@@ -1539,6 +1535,44 @@ LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
15391535
return Legalized;
15401536
}
15411537

1538+
LegalizerHelper::LegalizeResult
1539+
LegalizerHelper::widenScalarDstMergeValues(MachineInstr &MI, LLT WideTy) {
1540+
// Disallow for vectors and pointers. Not sure about what to do with pointers.
1541+
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
1542+
if (!DstTy.isScalar())
1543+
return UnableToLegalize;
1544+
LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
1545+
const int DstSize = DstTy.getSizeInBits();
1546+
const int SrcSize = SrcTy.getSizeInBits();
1547+
const int WideSize = WideTy.getSizeInBits();
1548+
// If WideSize = DstSize + K * SrcSize then we can get WideSize by padding
1549+
// with K undef elements.
1550+
//
1551+
// dst = G_MERGE_VALUES elt1, elt2, ..., eltN
1552+
// -> wide_dst = G_MERGE_VALUES elt1, elt2, ... eltN, pad1, pad2, ... padK
1553+
int Difference = WideSize - DstSize;
1554+
if ((Difference) % SrcSize != 0)
1555+
return UnableToLegalize;
1556+
int NumPadEltsToAdd = Difference / SrcSize;
1557+
assert(NumPadEltsToAdd && "Expected to add at least one element?");
1558+
MachineFunction &MF = *MI.getMF();
1559+
for (int I = 0; I < NumPadEltsToAdd; ++I) {
1560+
auto PadElt = MIRBuilder.buildUndef(SrcTy);
1561+
MI.addOperand(
1562+
MF, MachineOperand::CreateReg(PadElt.getReg(0), /*isDef = */ false));
1563+
}
1564+
widenScalarDst(MI, WideTy, 0);
1565+
return Legalized;
1566+
}
1567+
1568+
LegalizerHelper::LegalizeResult
1569+
LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
1570+
LLT WideTy) {
1571+
if (TypeIdx == 0)
1572+
return widenScalarDstMergeValues(MI, WideTy);
1573+
return widenScalarSrcMergeValues(MI, WideTy);
1574+
}
1575+
15421576
Register LegalizerHelper::widenWithUnmerge(LLT WideTy, Register OrigReg) {
15431577
Register WideReg = MRI.createGenericVirtualRegister(WideTy);
15441578
LLT OrigTy = MRI.getType(OrigReg);

llvm/test/CodeGen/AArch64/GlobalISel/legalize-merge-values.mir

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2-
# RUN: llc -march=aarch64 -O0 -run-pass=legalizer %s -o - | FileCheck %s
2+
# RUN: llc -march=aarch64 -O0 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
33

44
---
55
name: test_merge_s4
@@ -26,3 +26,127 @@ body: |
2626
%4:_(s64) = G_ANYEXT %3
2727
$x0 = COPY %4
2828
...
29+
---
30+
name: test_merge_s24_s8
31+
tracksRegLiveness: true
32+
body: |
33+
bb.0:
34+
liveins: $w0
35+
36+
; 24 + 8 = 32 => Add 1 undef element as padding.
37+
38+
; CHECK-LABEL: name: test_merge_s24_s8
39+
; CHECK: liveins: $w0
40+
; CHECK: %x:_(s8) = G_CONSTANT i8 0
41+
; CHECK: [[DEF:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
42+
; CHECK: [[MV:%[0-9]+]]:_(s32) = G_MERGE_VALUES %x(s8), %x(s8), %x(s8), [[DEF]](s8)
43+
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16777215
44+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[MV]](s32)
45+
; CHECK: %zext:_(s32) = G_AND [[COPY]], [[C]]
46+
; CHECK: $w0 = COPY %zext(s32)
47+
; CHECK: RET_ReallyLR implicit $w0
48+
%x:_(s8) = G_CONSTANT i8 0
49+
%merge:_(s24) = G_MERGE_VALUES %x, %x, %x
50+
%zext:_(s32) = G_ZEXT %merge
51+
$w0 = COPY %zext
52+
RET_ReallyLR implicit $w0
53+
...
54+
---
55+
name: test_merge_s40_s8
56+
tracksRegLiveness: true
57+
body: |
58+
bb.0:
59+
liveins: $x0
60+
61+
; 64 - 40 = 24; 24 / 8 = 3 => Add 3 undef elements as padding.
62+
63+
; CHECK-LABEL: name: test_merge_s40_s8
64+
; CHECK: liveins: $x0
65+
; CHECK: %x:_(s8) = G_CONSTANT i8 0
66+
; CHECK: [[DEF:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
67+
; CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES %x(s8), %x(s8), %x(s8), %x(s8), %x(s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8)
68+
; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1099511627775
69+
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY [[MV]](s64)
70+
; CHECK: %zext:_(s64) = G_AND [[COPY]], [[C]]
71+
; CHECK: $x0 = COPY %zext(s64)
72+
; CHECK: RET_ReallyLR implicit $x0
73+
%x:_(s8) = G_CONSTANT i8 0
74+
%merge:_(s40) = G_MERGE_VALUES %x, %x, %x, %x, %x
75+
%zext:_(s64) = G_ZEXT %merge
76+
$x0 = COPY %zext
77+
RET_ReallyLR implicit $x0
78+
...
79+
---
80+
name: test_merge_s7_s1
81+
tracksRegLiveness: true
82+
body: |
83+
bb.0:
84+
liveins: $w0
85+
86+
; 7 + 1 = 8 -> Add one undef.
87+
88+
; CHECK-LABEL: name: test_merge_s7_s1
89+
; CHECK: liveins: $w0
90+
; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
91+
; CHECK: %x:_(s1) = G_TRUNC [[C]](s8)
92+
; CHECK: [[DEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
93+
; CHECK: [[MV:%[0-9]+]]:_(s8) = G_MERGE_VALUES %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), [[DEF]](s1)
94+
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 127
95+
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[MV]](s8)
96+
; CHECK: %zext:_(s32) = G_AND [[ANYEXT]], [[C1]]
97+
; CHECK: $w0 = COPY %zext(s32)
98+
; CHECK: RET_ReallyLR implicit $w0
99+
%x:_(s1) = G_CONSTANT i1 0
100+
%merge:_(s7) = G_MERGE_VALUES %x, %x, %x, %x, %x, %x, %x
101+
%zext:_(s32) = G_ZEXT %merge
102+
$w0 = COPY %zext
103+
RET_ReallyLR implicit $w0
104+
...
105+
---
106+
name: test_merge_s21_s7
107+
tracksRegLiveness: true
108+
body: |
109+
bb.0:
110+
liveins: $w0
111+
112+
; Can't legalize this one yet.
113+
114+
; CHECK-LABEL: name: test_merge_s21_s7
115+
; CHECK: liveins: $w0
116+
; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
117+
; CHECK: %x:_(s7) = G_TRUNC [[C]](s8)
118+
; CHECK: %merge:_(s21) = G_MERGE_VALUES %x(s7), %x(s7), %x(s7)
119+
; CHECK: %zext:_(s32) = G_ZEXT %merge(s21)
120+
; CHECK: $w0 = COPY %zext(s32)
121+
; CHECK: RET_ReallyLR implicit $w0
122+
%x:_(s7) = G_CONSTANT i7 0
123+
%merge:_(s21) = G_MERGE_VALUES %x, %x, %x
124+
%zext:_(s32) = G_ZEXT %merge
125+
$w0 = COPY %zext
126+
RET_ReallyLR implicit $w0
127+
...
128+
---
129+
name: test_merge_s11_s1
130+
tracksRegLiveness: true
131+
body: |
132+
bb.0:
133+
liveins: $w0
134+
135+
; 7 + 1 = 8 -> Add one undef.
136+
137+
; CHECK-LABEL: name: test_merge_s11_s1
138+
; CHECK: liveins: $w0
139+
; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
140+
; CHECK: %x:_(s1) = G_TRUNC [[C]](s8)
141+
; CHECK: [[DEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
142+
; CHECK: [[MV:%[0-9]+]]:_(s16) = G_MERGE_VALUES %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), %x(s1), [[DEF]](s1), [[DEF]](s1), [[DEF]](s1), [[DEF]](s1), [[DEF]](s1)
143+
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2047
144+
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[MV]](s16)
145+
; CHECK: %zext:_(s32) = G_AND [[ANYEXT]], [[C1]]
146+
; CHECK: $w0 = COPY %zext(s32)
147+
; CHECK: RET_ReallyLR implicit $w0
148+
%x:_(s1) = G_CONSTANT i1 0
149+
%merge:_(s11) = G_MERGE_VALUES %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x
150+
%zext:_(s32) = G_ZEXT %merge
151+
$w0 = COPY %zext
152+
RET_ReallyLR implicit $w0

0 commit comments

Comments
 (0)