Skip to content

Commit c08a783

Browse files
author
Igor Breger
committedMay 1, 2017
[GlobalISel][X86] G_SEXT/G_ZEXT support.
Reviewers: zvi, guyblank Reviewed By: zvi Subscribers: rovka, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D32591 llvm-svn: 301790
1 parent 70a6051 commit c08a783

File tree

7 files changed

+596
-0
lines changed

7 files changed

+596
-0
lines changed
 

‎llvm/lib/Target/X86/X86LegalizerInfo.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
7171

7272
setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
7373
setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar);
74+
75+
// Extensions
76+
setAction({G_ZEXT, s32}, Legal);
77+
setAction({G_SEXT, s32}, Legal);
78+
79+
for (auto Ty : {s8, s16}) {
80+
setAction({G_ZEXT, 1, Ty}, Legal);
81+
setAction({G_SEXT, 1, Ty}, Legal);
82+
}
7483
}
7584

7685
void X86LegalizerInfo::setLegalizerInfo64bit() {
@@ -105,6 +114,17 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
105114
setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
106115

107116
setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
117+
118+
// Extensions
119+
for (auto Ty : {s32, s64}) {
120+
setAction({G_ZEXT, Ty}, Legal);
121+
setAction({G_SEXT, Ty}, Legal);
122+
}
123+
124+
for (auto Ty : {s8, s16, s32}) {
125+
setAction({G_ZEXT, 1, Ty}, Legal);
126+
setAction({G_SEXT, 1, Ty}, Legal);
127+
}
108128
}
109129

110130
void X86LegalizerInfo::setLegalizerInfoSSE1() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X64
3+
4+
; TODO merge with ext.ll after i64 sext suported on 32bit platform
5+
6+
define i64 @test_sext_i8(i8 %val) {
7+
; X64-LABEL: test_sext_i8:
8+
; X64: # BB#0:
9+
; X64-NEXT: movsbq %dil, %rax
10+
; X64-NEXT: retq
11+
%r = sext i8 %val to i64
12+
ret i64 %r
13+
}
14+
15+
define i64 @test_sext_i16(i16 %val) {
16+
; X64-LABEL: test_sext_i16:
17+
; X64: # BB#0:
18+
; X64-NEXT: movswq %di, %rax
19+
; X64-NEXT: retq
20+
%r = sext i16 %val to i64
21+
ret i64 %r
22+
}
23+
24+
; TODO enable after selection supported
25+
;define i64 @test_sext_i32(i32 %val) {
26+
; %r = sext i32 %val to i64
27+
; ret i64 %r
28+
;}
29+
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X64
3+
; RUN: llc -mtriple=i386-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X32
4+
5+
define i32 @test_zext_i8(i8 %val) {
6+
; X64-LABEL: test_zext_i8:
7+
; X64: # BB#0:
8+
; X64-NEXT: movzbl %dil, %eax
9+
; X64-NEXT: retq
10+
;
11+
; X32-LABEL: test_zext_i8:
12+
; X32: # BB#0:
13+
; X32-NEXT: leal 4(%esp), %eax
14+
; X32-NEXT: movzbl (%eax), %eax
15+
; X32-NEXT: retl
16+
%r = zext i8 %val to i32
17+
ret i32 %r
18+
}
19+
20+
define i32 @test_zext_i16(i16 %val) {
21+
; X64-LABEL: test_zext_i16:
22+
; X64: # BB#0:
23+
; X64-NEXT: movzwl %di, %eax
24+
; X64-NEXT: retq
25+
;
26+
; X32-LABEL: test_zext_i16:
27+
; X32: # BB#0:
28+
; X32-NEXT: leal 4(%esp), %eax
29+
; X32-NEXT: movzwl (%eax), %eax
30+
; X32-NEXT: retl
31+
%r = zext i16 %val to i32
32+
ret i32 %r
33+
}
34+
35+
define i32 @test_sext_i8(i8 %val) {
36+
; X64-LABEL: test_sext_i8:
37+
; X64: # BB#0:
38+
; X64-NEXT: movsbl %dil, %eax
39+
; X64-NEXT: retq
40+
;
41+
; X32-LABEL: test_sext_i8:
42+
; X32: # BB#0:
43+
; X32-NEXT: leal 4(%esp), %eax
44+
; X32-NEXT: movsbl (%eax), %eax
45+
; X32-NEXT: retl
46+
%r = sext i8 %val to i32
47+
ret i32 %r
48+
}
49+
50+
define i32 @test_sext_i16(i16 %val) {
51+
; X64-LABEL: test_sext_i16:
52+
; X64: # BB#0:
53+
; X64-NEXT: movswl %di, %eax
54+
; X64-NEXT: retq
55+
;
56+
; X32-LABEL: test_sext_i16:
57+
; X32: # BB#0:
58+
; X32-NEXT: leal 4(%esp), %eax
59+
; X32-NEXT: movswl (%eax), %eax
60+
; X32-NEXT: retl
61+
%r = sext i16 %val to i32
62+
ret i32 %r
63+
}
64+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
2+
3+
--- |
4+
define i64 @test_sext_i8(i8 %val) {
5+
%r = sext i8 %val to i64
6+
ret i64 %r
7+
}
8+
9+
define i64 @test_sext_i16(i16 %val) {
10+
%r = sext i16 %val to i64
11+
ret i64 %r
12+
}
13+
14+
define i64 @test_sext_i32(i32 %val) {
15+
%r = sext i32 %val to i64
16+
ret i64 %r
17+
}
18+
19+
define i64 @test_zext_i8(i8 %val) {
20+
%r = zext i8 %val to i64
21+
ret i64 %r
22+
}
23+
24+
define i64 @test_zext_i16(i16 %val) {
25+
%r = zext i16 %val to i64
26+
ret i64 %r
27+
}
28+
29+
define i64 @test_zext_i32(i32 %val) {
30+
%r = zext i32 %val to i64
31+
ret i64 %r
32+
}
33+
34+
...
35+
---
36+
name: test_sext_i8
37+
# CHECK-LABEL: name: test_sext_i8
38+
alignment: 4
39+
legalized: false
40+
regBankSelected: false
41+
registers:
42+
- { id: 0, class: _ }
43+
- { id: 1, class: _ }
44+
# CHECK: %0(s8) = COPY %edi
45+
# CHECK-NEXT: %1(s64) = G_SEXT %0(s8)
46+
# CHECK-NEXT: %rax = COPY %1(s64)
47+
# CHECK-NEXT: RET 0, implicit %rax
48+
body: |
49+
bb.1 (%ir-block.0):
50+
liveins: %edi
51+
52+
%0(s8) = COPY %edi
53+
%1(s64) = G_SEXT %0(s8)
54+
%rax = COPY %1(s64)
55+
RET 0, implicit %rax
56+
57+
...
58+
---
59+
name: test_sext_i16
60+
# CHECK-LABEL: name: test_sext_i16
61+
alignment: 4
62+
legalized: false
63+
regBankSelected: false
64+
registers:
65+
- { id: 0, class: _ }
66+
- { id: 1, class: _ }
67+
# CHECK: %0(s16) = COPY %edi
68+
# CHECK-NEXT: %1(s64) = G_SEXT %0(s16)
69+
# CHECK-NEXT: %rax = COPY %1(s64)
70+
# CHECK-NEXT: RET 0, implicit %rax
71+
body: |
72+
bb.1 (%ir-block.0):
73+
liveins: %edi
74+
75+
%0(s16) = COPY %edi
76+
%1(s64) = G_SEXT %0(s16)
77+
%rax = COPY %1(s64)
78+
RET 0, implicit %rax
79+
80+
...
81+
---
82+
name: test_sext_i32
83+
# CHECK-LABEL: name: test_sext_i32
84+
alignment: 4
85+
legalized: false
86+
regBankSelected: false
87+
registers:
88+
- { id: 0, class: _ }
89+
- { id: 1, class: _ }
90+
# CHECK: %0(s32) = COPY %edi
91+
# CHECK-NEXT: %1(s64) = G_SEXT %0(s32)
92+
# CHECK-NEXT: %rax = COPY %1(s64)
93+
# CHECK-NEXT: RET 0, implicit %rax
94+
body: |
95+
bb.1 (%ir-block.0):
96+
liveins: %edi
97+
98+
%0(s32) = COPY %edi
99+
%1(s64) = G_SEXT %0(s32)
100+
%rax = COPY %1(s64)
101+
RET 0, implicit %rax
102+
103+
...
104+
---
105+
name: test_zext_i8
106+
# CHECK-LABEL: name: test_zext_i8
107+
alignment: 4
108+
legalized: false
109+
regBankSelected: false
110+
registers:
111+
- { id: 0, class: _ }
112+
- { id: 1, class: _ }
113+
# CHECK: %0(s8) = COPY %edi
114+
# CHECK-NEXT: %1(s64) = G_ZEXT %0(s8)
115+
# CHECK-NEXT: %rax = COPY %1(s64)
116+
# CHECK-NEXT: RET 0, implicit %rax
117+
body: |
118+
bb.1 (%ir-block.0):
119+
liveins: %edi
120+
121+
%0(s8) = COPY %edi
122+
%1(s64) = G_ZEXT %0(s8)
123+
%rax = COPY %1(s64)
124+
RET 0, implicit %rax
125+
126+
...
127+
---
128+
name: test_zext_i16
129+
# CHECK-LABEL: name: test_zext_i16
130+
alignment: 4
131+
legalized: false
132+
regBankSelected: false
133+
registers:
134+
- { id: 0, class: _ }
135+
- { id: 1, class: _ }
136+
# CHECK: %0(s16) = COPY %edi
137+
# CHECK-NEXT: %1(s64) = G_ZEXT %0(s16)
138+
# CHECK-NEXT: %rax = COPY %1(s64)
139+
# CHECK-NEXT: RET 0, implicit %rax
140+
body: |
141+
bb.1 (%ir-block.0):
142+
liveins: %edi
143+
144+
%0(s16) = COPY %edi
145+
%1(s64) = G_ZEXT %0(s16)
146+
%rax = COPY %1(s64)
147+
RET 0, implicit %rax
148+
149+
...
150+
---
151+
name: test_zext_i32
152+
# CHECK-LABEL: name: test_zext_i32
153+
alignment: 4
154+
legalized: false
155+
regBankSelected: false
156+
registers:
157+
- { id: 0, class: _ }
158+
- { id: 1, class: _ }
159+
# CHECK: %0(s32) = COPY %edi
160+
# CHECK-NEXT: %1(s64) = G_ZEXT %0(s32)
161+
# CHECK-NEXT: %rax = COPY %1(s64)
162+
# CHECK-NEXT: RET 0, implicit %rax
163+
body: |
164+
bb.1 (%ir-block.0):
165+
liveins: %edi
166+
167+
%0(s32) = COPY %edi
168+
%1(s64) = G_ZEXT %0(s32)
169+
%rax = COPY %1(s64)
170+
RET 0, implicit %rax
171+
172+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
2+
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
3+
--- |
4+
define i32 @test_zext_i8(i8 %val) {
5+
%r = zext i8 %val to i32
6+
ret i32 %r
7+
}
8+
9+
define i32 @test_zext_i16(i16 %val) {
10+
%r = zext i16 %val to i32
11+
ret i32 %r
12+
}
13+
14+
define i32 @test_sext_i8(i8 %val) {
15+
%r = sext i8 %val to i32
16+
ret i32 %r
17+
}
18+
19+
define i32 @test_sext_i16(i16 %val) {
20+
%r = sext i16 %val to i32
21+
ret i32 %r
22+
}
23+
24+
...
25+
---
26+
name: test_zext_i8
27+
# ALL-LABEL: name: test_zext_i8
28+
alignment: 4
29+
legalized: false
30+
regBankSelected: false
31+
registers:
32+
- { id: 0, class: _ }
33+
- { id: 1, class: _ }
34+
# ALL: %0(s8) = COPY %edi
35+
# ALL-NEXT: %1(s32) = G_ZEXT %0(s8)
36+
# ALL-NEXT: %eax = COPY %1(s32)
37+
# ALL-NEXT: RET 0, implicit %eax
38+
body: |
39+
bb.1 (%ir-block.0):
40+
liveins: %edi
41+
42+
%0(s8) = COPY %edi
43+
%1(s32) = G_ZEXT %0(s8)
44+
%eax = COPY %1(s32)
45+
RET 0, implicit %eax
46+
47+
...
48+
---
49+
name: test_zext_i16
50+
# ALL-LABEL: name: test_zext_i16
51+
alignment: 4
52+
legalized: false
53+
regBankSelected: false
54+
registers:
55+
- { id: 0, class: _ }
56+
- { id: 1, class: _ }
57+
# ALL: %0(s16) = COPY %edi
58+
# ALL-NEXT: %1(s32) = G_ZEXT %0(s16)
59+
# ALL-NEXT: %eax = COPY %1(s32)
60+
# ALL-NEXT: RET 0, implicit %eax
61+
body: |
62+
bb.1 (%ir-block.0):
63+
liveins: %edi
64+
65+
%0(s16) = COPY %edi
66+
%1(s32) = G_ZEXT %0(s16)
67+
%eax = COPY %1(s32)
68+
RET 0, implicit %eax
69+
70+
...
71+
---
72+
name: test_sext_i8
73+
# ALL-LABEL: name: test_sext_i8
74+
alignment: 4
75+
legalized: false
76+
regBankSelected: false
77+
registers:
78+
- { id: 0, class: _ }
79+
- { id: 1, class: _ }
80+
# ALL: %0(s8) = COPY %edi
81+
# ALL-NEXT: %1(s32) = G_SEXT %0(s8)
82+
# ALL-NEXT: %eax = COPY %1(s32)
83+
# ALL-NEXT: RET 0, implicit %eax
84+
body: |
85+
bb.1 (%ir-block.0):
86+
liveins: %edi
87+
88+
%0(s8) = COPY %edi
89+
%1(s32) = G_SEXT %0(s8)
90+
%eax = COPY %1(s32)
91+
RET 0, implicit %eax
92+
93+
...
94+
---
95+
name: test_sext_i16
96+
# ALL-LABEL: name: test_sext_i16
97+
alignment: 4
98+
legalized: false
99+
regBankSelected: false
100+
registers:
101+
- { id: 0, class: _ }
102+
- { id: 1, class: _ }
103+
# ALL: %0(s16) = COPY %edi
104+
# ALL-NEXT: %1(s32) = G_SEXT %0(s16)
105+
# ALL-NEXT: %eax = COPY %1(s32)
106+
# ALL-NEXT: RET 0, implicit %eax
107+
body: |
108+
bb.1 (%ir-block.0):
109+
liveins: %edi
110+
111+
%0(s16) = COPY %edi
112+
%1(s32) = G_SEXT %0(s16)
113+
%eax = COPY %1(s32)
114+
RET 0, implicit %eax
115+
116+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
2+
3+
--- |
4+
define i64 @test_sext_i8(i8 %val) {
5+
%r = sext i8 %val to i64
6+
ret i64 %r
7+
}
8+
9+
define i64 @test_sext_i16(i16 %val) {
10+
%r = sext i16 %val to i64
11+
ret i64 %r
12+
}
13+
14+
...
15+
---
16+
name: test_sext_i8
17+
# ALL-LABEL: name: test_sext_i8
18+
alignment: 4
19+
legalized: true
20+
regBankSelected: true
21+
# ALL: registers:
22+
# ALL-NEXT: - { id: 0, class: gr8 }
23+
# ALL-NEXT: - { id: 1, class: gr64 }
24+
registers:
25+
- { id: 0, class: gpr }
26+
- { id: 1, class: gpr }
27+
# ALL: %0 = COPY %dil
28+
# ALL-NEXT: %1 = MOVSX64rr8 %0
29+
# ALL-NEXT: %rax = COPY %1
30+
# ALL-NEXT: RET 0, implicit %rax
31+
body: |
32+
bb.1 (%ir-block.0):
33+
liveins: %edi
34+
35+
%0(s8) = COPY %edi
36+
%1(s64) = G_SEXT %0(s8)
37+
%rax = COPY %1(s64)
38+
RET 0, implicit %rax
39+
40+
...
41+
---
42+
name: test_sext_i16
43+
# ALL-LABEL: name: test_sext_i16
44+
alignment: 4
45+
legalized: true
46+
regBankSelected: true
47+
# ALL: registers:
48+
# ALL-NEXT: - { id: 0, class: gr16 }
49+
# ALL-NEXT: - { id: 1, class: gr64 }
50+
registers:
51+
- { id: 0, class: gpr }
52+
- { id: 1, class: gpr }
53+
# ALL: %0 = COPY %di
54+
# ALL-NEXT: %1 = MOVSX64rr16 %0
55+
# ALL-NEXT: %rax = COPY %1
56+
# ALL-NEXT: RET 0, implicit %rax
57+
body: |
58+
bb.1 (%ir-block.0):
59+
liveins: %edi
60+
61+
%0(s16) = COPY %edi
62+
%1(s64) = G_SEXT %0(s16)
63+
%rax = COPY %1(s64)
64+
RET 0, implicit %rax
65+
66+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
2+
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
3+
4+
--- |
5+
define i32 @test_zext_i8(i8 %val) {
6+
%r = zext i8 %val to i32
7+
ret i32 %r
8+
}
9+
10+
define i32 @test_zext_i16(i16 %val) {
11+
%r = zext i16 %val to i32
12+
ret i32 %r
13+
}
14+
15+
define i32 @test_sext_i8(i8 %val) {
16+
%r = sext i8 %val to i32
17+
ret i32 %r
18+
}
19+
20+
define i32 @test_sext_i16(i16 %val) {
21+
%r = sext i16 %val to i32
22+
ret i32 %r
23+
}
24+
25+
...
26+
---
27+
name: test_zext_i8
28+
# ALL-LABEL: name: test_zext_i8
29+
alignment: 4
30+
legalized: true
31+
regBankSelected: true
32+
# ALL: registers:
33+
# ALL-NEXT: - { id: 0, class: gr8 }
34+
# ALL-NEXT: - { id: 1, class: gr32 }
35+
registers:
36+
- { id: 0, class: gpr }
37+
- { id: 1, class: gpr }
38+
# ALL: %0 = COPY %dil
39+
# ALL-NEXT: %1 = MOVZX32rr8 %0
40+
# ALL-NEXT: %eax = COPY %1
41+
# ALL-NEXT: RET 0, implicit %eax
42+
body: |
43+
bb.1 (%ir-block.0):
44+
liveins: %edi
45+
46+
%0(s8) = COPY %edi
47+
%1(s32) = G_ZEXT %0(s8)
48+
%eax = COPY %1(s32)
49+
RET 0, implicit %eax
50+
51+
...
52+
---
53+
name: test_zext_i16
54+
# ALL-LABEL: name: test_zext_i16
55+
alignment: 4
56+
legalized: true
57+
regBankSelected: true
58+
# ALL: registers:
59+
# ALL-NEXT: - { id: 0, class: gr16 }
60+
# ALL-NEXT: - { id: 1, class: gr32 }
61+
registers:
62+
- { id: 0, class: gpr }
63+
- { id: 1, class: gpr }
64+
# ALL: %0 = COPY %di
65+
# ALL-NEXT: %1 = MOVZX32rr16 %0
66+
# ALL-NEXT: %eax = COPY %1
67+
# ALL-NEXT: RET 0, implicit %eax
68+
body: |
69+
bb.1 (%ir-block.0):
70+
liveins: %edi
71+
72+
%0(s16) = COPY %edi
73+
%1(s32) = G_ZEXT %0(s16)
74+
%eax = COPY %1(s32)
75+
RET 0, implicit %eax
76+
77+
...
78+
---
79+
name: test_sext_i8
80+
# ALL-LABEL: name: test_sext_i8
81+
alignment: 4
82+
legalized: true
83+
regBankSelected: true
84+
# ALL: registers:
85+
# ALL-NEXT: - { id: 0, class: gr8 }
86+
# ALL-NEXT: - { id: 1, class: gr32 }
87+
registers:
88+
- { id: 0, class: gpr }
89+
- { id: 1, class: gpr }
90+
# ALL: %0 = COPY %dil
91+
# ALL-NEXT: %1 = MOVSX32rr8 %0
92+
# ALL-NEXT: %eax = COPY %1
93+
# ALL-NEXT: RET 0, implicit %eax
94+
body: |
95+
bb.1 (%ir-block.0):
96+
liveins: %edi
97+
98+
%0(s8) = COPY %edi
99+
%1(s32) = G_SEXT %0(s8)
100+
%eax = COPY %1(s32)
101+
RET 0, implicit %eax
102+
103+
...
104+
---
105+
name: test_sext_i16
106+
# ALL-LABEL: name: test_sext_i16
107+
alignment: 4
108+
legalized: true
109+
regBankSelected: true
110+
# ALL: registers:
111+
# ALL-NEXT: - { id: 0, class: gr16 }
112+
# ALL-NEXT: - { id: 1, class: gr32 }
113+
registers:
114+
- { id: 0, class: gpr }
115+
- { id: 1, class: gpr }
116+
# ALL: %0 = COPY %di
117+
# ALL-NEXT: %1 = MOVSX32rr16 %0
118+
# ALL-NEXT: %eax = COPY %1
119+
# ALL-NEXT: RET 0, implicit %eax
120+
body: |
121+
bb.1 (%ir-block.0):
122+
liveins: %edi
123+
124+
%0(s16) = COPY %edi
125+
%1(s32) = G_SEXT %0(s16)
126+
%eax = COPY %1(s32)
127+
RET 0, implicit %eax
128+
129+
...

0 commit comments

Comments
 (0)
Please sign in to comment.