Skip to content

Commit dd2fea9

Browse files
author
Thorsten Schütt
committed
[GlobalIsel][X86] Legalize G_CTLZ and G_CTPOP for 32-bit
Note that 32-bit support is very limited Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D151459
1 parent 344e91a commit dd2fea9

File tree

3 files changed

+181
-16
lines changed

3 files changed

+181
-16
lines changed

llvm/lib/Target/X86/X86LegalizerInfo.cpp

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
7272
setLegalizerInfoAVX512DQ();
7373
setLegalizerInfoAVX512BW();
7474

75+
const LLT s16 = LLT::scalar(16);
76+
const LLT s32 = LLT::scalar(32);
77+
const LLT s64 = LLT::scalar(64);
78+
7579
getActionDefinitionsBuilder(G_INTRINSIC_ROUNDEVEN)
7680
.scalarize(0)
7781
.minScalar(0, LLT::scalar(32))
@@ -93,6 +97,41 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
9397

9498
getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
9599

100+
101+
if (Subtarget.is64Bit()) {
102+
if (Subtarget.hasPOPCNT()) {
103+
// popcount
104+
getActionDefinitionsBuilder(G_CTPOP)
105+
.legalFor({{s16, s16}, {s32, s32}, {s64, s64}})
106+
.widenScalarToNextPow2(1, /*Min=*/16)
107+
.clampScalar(1, s16, s64);
108+
}
109+
110+
if (Subtarget.hasLZCNT()) {
111+
// count leading zeros (LZCNT)
112+
getActionDefinitionsBuilder(G_CTLZ)
113+
.legalFor({{s16, s16}, {s32, s32}, {s64, s64}})
114+
.widenScalarToNextPow2(1, /*Min=*/16)
115+
.clampScalar(1, s16, s64);
116+
}
117+
} else { // 32-bit
118+
if (Subtarget.hasPOPCNT()) {
119+
// popcount
120+
getActionDefinitionsBuilder(G_CTPOP)
121+
.legalFor({{s16, s16}, {s32, s32}})
122+
.widenScalarToNextPow2(1, /*Min=*/16)
123+
.clampScalar(1, s16, s32);
124+
}
125+
126+
if (Subtarget.hasLZCNT()) {
127+
// count leading zeros (LZCNT)
128+
getActionDefinitionsBuilder(G_CTLZ)
129+
.legalFor({{s16, s16}, {s32, s32}})
130+
.widenScalarToNextPow2(1, /*Min=*/16)
131+
.clampScalar(1, s16, s32);
132+
}
133+
}
134+
96135
LegacyInfo.computeTables();
97136
verify(*STI.getInstrInfo());
98137
}
@@ -288,22 +327,6 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
288327
LegacyInfo.setAction({G_MERGE_VALUES, 1, s128}, LegacyLegalizeActions::Legal);
289328
LegacyInfo.setAction({G_UNMERGE_VALUES, s128}, LegacyLegalizeActions::Legal);
290329

291-
if (Subtarget.hasPOPCNT()) {
292-
// popcount
293-
getActionDefinitionsBuilder(G_CTPOP)
294-
.legalFor({{s16, s16}, {s32, s32}, {s64, s64}})
295-
.widenScalarToNextPow2(1, /*Min=*/16)
296-
.clampScalar(1, s16, s64);
297-
}
298-
299-
if (Subtarget.hasLZCNT()) {
300-
// count leading zeros (LZCNT)
301-
getActionDefinitionsBuilder(G_CTLZ)
302-
.legalFor({{s16, s16}, {s32, s32}, {s64, s64}})
303-
.widenScalarToNextPow2(1, /*Min=*/16)
304-
.clampScalar(1, s16, s64);
305-
}
306-
307330
}
308331

309332
void X86LegalizerInfo::setLegalizerInfoSSE1() {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
2+
# RUN: llc -mtriple=i386-linux-gnu -mattr=+popcnt -run-pass=legalizer %s -o - | FileCheck %s
3+
4+
# test popcount for s8, s16, and s32
5+
6+
---
7+
name: test_ctpop8
8+
alignment: 16
9+
legalized: false
10+
regBankSelected: false
11+
registers:
12+
- { id: 0, class: _, preferred-register: '' }
13+
- { id: 1, class: _, preferred-register: '' }
14+
body: |
15+
bb.1:
16+
; CHECK-LABEL: name: test_ctpop8
17+
; CHECK: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
18+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[DEF]](s8)
19+
; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]](s16)
20+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[CTPOP]](s16)
21+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[TRUNC]](s8)
22+
; CHECK-NEXT: RET 0, implicit [[COPY]](s8)
23+
%0:_(s8) = IMPLICIT_DEF
24+
%1:_(s8) = G_CTPOP %0
25+
%2:_(s8) = COPY %1(s8)
26+
RET 0, implicit %2
27+
28+
...
29+
---
30+
name: test_ctpop32
31+
alignment: 16
32+
legalized: false
33+
regBankSelected: false
34+
registers:
35+
- { id: 0, class: _, preferred-register: '' }
36+
- { id: 1, class: _, preferred-register: '' }
37+
body: |
38+
bb.1:
39+
; CHECK-LABEL: name: test_ctpop32
40+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF
41+
; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[DEF]](s32)
42+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY [[CTPOP]](s32)
43+
; CHECK-NEXT: RET 0, implicit [[COPY]](s32)
44+
%0:_(s32) = IMPLICIT_DEF
45+
%1:_(s32) = G_CTPOP %0
46+
%2:_(s32) = COPY %1(s32)
47+
RET 0, implicit %2
48+
49+
...
50+
---
51+
name: test_ctpop16
52+
alignment: 16
53+
legalized: false
54+
regBankSelected: false
55+
registers:
56+
- { id: 0, class: _, preferred-register: '' }
57+
- { id: 1, class: _, preferred-register: '' }
58+
body: |
59+
bb.1:
60+
; CHECK-LABEL: name: test_ctpop16
61+
; CHECK: [[DEF:%[0-9]+]]:_(s16) = IMPLICIT_DEF
62+
; CHECK-NEXT: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[DEF]](s16)
63+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]](s16)
64+
; CHECK-NEXT: RET 0, implicit [[COPY]](s16)
65+
%0:_(s16) = IMPLICIT_DEF
66+
%1:_(s16) = G_CTPOP %0
67+
%2:_(s16) = COPY %1(s16)
68+
RET 0, implicit %2
69+
70+
...
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
2+
# RUN: llc -mtriple=i386-linux-gnu -mattr=+lzcnt -run-pass=legalizer %s -o - | FileCheck %s
3+
4+
# test count leading zeros for s8, s16, and s32
5+
6+
---
7+
name: test_ctlz8
8+
alignment: 16
9+
legalized: false
10+
regBankSelected: false
11+
registers:
12+
- { id: 0, class: _, preferred-register: '' }
13+
- { id: 1, class: _, preferred-register: '' }
14+
body: |
15+
bb.1:
16+
; CHECK-LABEL: name: test_ctlz8
17+
; CHECK: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
18+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[DEF]](s8)
19+
; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s16) = G_CTLZ [[ZEXT]](s16)
20+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
21+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[CTLZ]], [[C]]
22+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]](s16)
23+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[TRUNC]](s8)
24+
; CHECK-NEXT: RET 0, implicit [[COPY]](s8)
25+
%0:_(s8) = IMPLICIT_DEF
26+
%1:_(s8) = G_CTLZ %0
27+
%2:_(s8) = COPY %1(s8)
28+
RET 0, implicit %2
29+
30+
...
31+
---
32+
name: test_ctlz32
33+
alignment: 16
34+
legalized: false
35+
regBankSelected: false
36+
registers:
37+
- { id: 0, class: _, preferred-register: '' }
38+
- { id: 1, class: _, preferred-register: '' }
39+
body: |
40+
bb.1:
41+
; CHECK-LABEL: name: test_ctlz32
42+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = IMPLICIT_DEF
43+
; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s32) = G_CTLZ [[DEF]](s32)
44+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY [[CTLZ]](s32)
45+
; CHECK-NEXT: RET 0, implicit [[COPY]](s32)
46+
%0:_(s32) = IMPLICIT_DEF
47+
%1:_(s32) = G_CTLZ %0
48+
%2:_(s32) = COPY %1(s32)
49+
RET 0, implicit %2
50+
51+
...
52+
---
53+
name: test_ctlz16
54+
alignment: 16
55+
legalized: false
56+
regBankSelected: false
57+
registers:
58+
- { id: 0, class: _, preferred-register: '' }
59+
- { id: 1, class: _, preferred-register: '' }
60+
body: |
61+
bb.1:
62+
; CHECK-LABEL: name: test_ctlz16
63+
; CHECK: [[DEF:%[0-9]+]]:_(s16) = IMPLICIT_DEF
64+
; CHECK-NEXT: [[CTLZ:%[0-9]+]]:_(s16) = G_CTLZ [[DEF]](s16)
65+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTLZ]](s16)
66+
; CHECK-NEXT: RET 0, implicit [[COPY]](s16)
67+
%0:_(s16) = IMPLICIT_DEF
68+
%1:_(s16) = G_CTLZ %0
69+
%2:_(s16) = COPY %1(s16)
70+
RET 0, implicit %2
71+
72+
...

0 commit comments

Comments
 (0)