Skip to content

Commit 897c18b

Browse files
feat(RISCVCombines): simplify zextw zextb chains
1 parent 890c3f0 commit 897c18b

4 files changed

Lines changed: 324 additions & 21 deletions

File tree

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// RUN: veir-opt %s -p=riscv-combine | filecheck %s
2+
3+
"builtin.module"() ({
4+
"func.func"() <{function_type = (!riscv.reg) -> !riscv.reg, sym_name = "byte_shift"}> ({
5+
^bb0(%x : !riscv.reg):
6+
%zextb = "riscv.zextb"(%x) : (!riscv.reg) -> !riscv.reg
7+
%zextw = "riscv.zextw"(%zextb) : (!riscv.reg) -> !riscv.reg
8+
%slliw = "riscv.slliw"(%zextw) <{"value" = 24 : i64}> : (!riscv.reg) -> !riscv.reg
9+
%out = "riscv.zextw"(%slliw) : (!riscv.reg) -> !riscv.reg
10+
"func.return"(%out) : (!riscv.reg) -> ()
11+
}) : () -> ()
12+
13+
"func.func"() <{function_type = (!riscv.reg) -> !riscv.reg, sym_name = "shift_too_large"}> ({
14+
^bb0(%x : !riscv.reg):
15+
%zextb = "riscv.zextb"(%x) : (!riscv.reg) -> !riscv.reg
16+
%slliw = "riscv.slliw"(%zextb) <{"value" = 25 : i64}> : (!riscv.reg) -> !riscv.reg
17+
%out = "riscv.zextw"(%slliw) : (!riscv.reg) -> !riscv.reg
18+
"func.return"(%out) : (!riscv.reg) -> ()
19+
}) : () -> ()
20+
21+
// Cover every statically instantiated Puddle pattern for the valid shift range.
22+
"func.func"() <{function_type = (!riscv.reg) -> (!riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg), sym_name = "all_byte_shifts"}> ({
23+
^bb0(%x : !riscv.reg):
24+
%zextb = "riscv.zextb"(%x) : (!riscv.reg) -> !riscv.reg
25+
%slliw0 = "riscv.slliw"(%zextb) <{"value" = 0 : i64}> : (!riscv.reg) -> !riscv.reg
26+
%out0 = "riscv.zextw"(%slliw0) : (!riscv.reg) -> !riscv.reg
27+
%slliw1 = "riscv.slliw"(%zextb) <{"value" = 1 : i64}> : (!riscv.reg) -> !riscv.reg
28+
%out1 = "riscv.zextw"(%slliw1) : (!riscv.reg) -> !riscv.reg
29+
%slliw2 = "riscv.slliw"(%zextb) <{"value" = 2 : i64}> : (!riscv.reg) -> !riscv.reg
30+
%out2 = "riscv.zextw"(%slliw2) : (!riscv.reg) -> !riscv.reg
31+
%slliw3 = "riscv.slliw"(%zextb) <{"value" = 3 : i64}> : (!riscv.reg) -> !riscv.reg
32+
%out3 = "riscv.zextw"(%slliw3) : (!riscv.reg) -> !riscv.reg
33+
%slliw4 = "riscv.slliw"(%zextb) <{"value" = 4 : i64}> : (!riscv.reg) -> !riscv.reg
34+
%out4 = "riscv.zextw"(%slliw4) : (!riscv.reg) -> !riscv.reg
35+
%slliw5 = "riscv.slliw"(%zextb) <{"value" = 5 : i64}> : (!riscv.reg) -> !riscv.reg
36+
%out5 = "riscv.zextw"(%slliw5) : (!riscv.reg) -> !riscv.reg
37+
%slliw6 = "riscv.slliw"(%zextb) <{"value" = 6 : i64}> : (!riscv.reg) -> !riscv.reg
38+
%out6 = "riscv.zextw"(%slliw6) : (!riscv.reg) -> !riscv.reg
39+
%slliw7 = "riscv.slliw"(%zextb) <{"value" = 7 : i64}> : (!riscv.reg) -> !riscv.reg
40+
%out7 = "riscv.zextw"(%slliw7) : (!riscv.reg) -> !riscv.reg
41+
%slliw8 = "riscv.slliw"(%zextb) <{"value" = 8 : i64}> : (!riscv.reg) -> !riscv.reg
42+
%out8 = "riscv.zextw"(%slliw8) : (!riscv.reg) -> !riscv.reg
43+
%slliw9 = "riscv.slliw"(%zextb) <{"value" = 9 : i64}> : (!riscv.reg) -> !riscv.reg
44+
%out9 = "riscv.zextw"(%slliw9) : (!riscv.reg) -> !riscv.reg
45+
%slliw10 = "riscv.slliw"(%zextb) <{"value" = 10 : i64}> : (!riscv.reg) -> !riscv.reg
46+
%out10 = "riscv.zextw"(%slliw10) : (!riscv.reg) -> !riscv.reg
47+
%slliw11 = "riscv.slliw"(%zextb) <{"value" = 11 : i64}> : (!riscv.reg) -> !riscv.reg
48+
%out11 = "riscv.zextw"(%slliw11) : (!riscv.reg) -> !riscv.reg
49+
%slliw12 = "riscv.slliw"(%zextb) <{"value" = 12 : i64}> : (!riscv.reg) -> !riscv.reg
50+
%out12 = "riscv.zextw"(%slliw12) : (!riscv.reg) -> !riscv.reg
51+
%slliw13 = "riscv.slliw"(%zextb) <{"value" = 13 : i64}> : (!riscv.reg) -> !riscv.reg
52+
%out13 = "riscv.zextw"(%slliw13) : (!riscv.reg) -> !riscv.reg
53+
%slliw14 = "riscv.slliw"(%zextb) <{"value" = 14 : i64}> : (!riscv.reg) -> !riscv.reg
54+
%out14 = "riscv.zextw"(%slliw14) : (!riscv.reg) -> !riscv.reg
55+
%slliw15 = "riscv.slliw"(%zextb) <{"value" = 15 : i64}> : (!riscv.reg) -> !riscv.reg
56+
%out15 = "riscv.zextw"(%slliw15) : (!riscv.reg) -> !riscv.reg
57+
%slliw16 = "riscv.slliw"(%zextb) <{"value" = 16 : i64}> : (!riscv.reg) -> !riscv.reg
58+
%out16 = "riscv.zextw"(%slliw16) : (!riscv.reg) -> !riscv.reg
59+
%slliw17 = "riscv.slliw"(%zextb) <{"value" = 17 : i64}> : (!riscv.reg) -> !riscv.reg
60+
%out17 = "riscv.zextw"(%slliw17) : (!riscv.reg) -> !riscv.reg
61+
%slliw18 = "riscv.slliw"(%zextb) <{"value" = 18 : i64}> : (!riscv.reg) -> !riscv.reg
62+
%out18 = "riscv.zextw"(%slliw18) : (!riscv.reg) -> !riscv.reg
63+
%slliw19 = "riscv.slliw"(%zextb) <{"value" = 19 : i64}> : (!riscv.reg) -> !riscv.reg
64+
%out19 = "riscv.zextw"(%slliw19) : (!riscv.reg) -> !riscv.reg
65+
%slliw20 = "riscv.slliw"(%zextb) <{"value" = 20 : i64}> : (!riscv.reg) -> !riscv.reg
66+
%out20 = "riscv.zextw"(%slliw20) : (!riscv.reg) -> !riscv.reg
67+
%slliw21 = "riscv.slliw"(%zextb) <{"value" = 21 : i64}> : (!riscv.reg) -> !riscv.reg
68+
%out21 = "riscv.zextw"(%slliw21) : (!riscv.reg) -> !riscv.reg
69+
%slliw22 = "riscv.slliw"(%zextb) <{"value" = 22 : i64}> : (!riscv.reg) -> !riscv.reg
70+
%out22 = "riscv.zextw"(%slliw22) : (!riscv.reg) -> !riscv.reg
71+
%slliw23 = "riscv.slliw"(%zextb) <{"value" = 23 : i64}> : (!riscv.reg) -> !riscv.reg
72+
%out23 = "riscv.zextw"(%slliw23) : (!riscv.reg) -> !riscv.reg
73+
%slliw24 = "riscv.slliw"(%zextb) <{"value" = 24 : i64}> : (!riscv.reg) -> !riscv.reg
74+
%out24 = "riscv.zextw"(%slliw24) : (!riscv.reg) -> !riscv.reg
75+
"func.return"(%out0, %out1, %out2, %out3, %out4, %out5, %out6, %out7, %out8, %out9, %out10, %out11, %out12, %out13, %out14, %out15, %out16, %out17, %out18, %out19, %out20, %out21, %out22, %out23, %out24) : (!riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg, !riscv.reg) -> ()
76+
}) : () -> ()
77+
78+
// The newly created `slli` must take the root's `x4` result type, not become
79+
// an unallocated `!riscv.reg` value.
80+
"func.func"() <{function_type = (!riscv.reg<x1>) -> !riscv.reg<x4>, sym_name = "typed_byte_shift"}> ({
81+
^bb0(%x : !riscv.reg<x1>):
82+
%zextb = "riscv.zextb"(%x) : (!riscv.reg<x1>) -> !riscv.reg<x2>
83+
%slliw = "riscv.slliw"(%zextb) <{"value" = 24 : i64}> : (!riscv.reg<x2>) -> !riscv.reg<x3>
84+
%out = "riscv.zextw"(%slliw) : (!riscv.reg<x3>) -> !riscv.reg<x4>
85+
"func.return"(%out) : (!riscv.reg<x4>) -> ()
86+
}) : () -> ()
87+
}) : () -> ()
88+
89+
// CHECK-LABEL: "sym_name" = "byte_shift"
90+
// CHECK: ^{{.*}}(%[[SHIFT_X:.*]] : !riscv.reg):
91+
// CHECK-NEXT: %[[SHIFT_B:.*]] = "riscv.zextb"(%[[SHIFT_X]]) : (!riscv.reg) -> !riscv.reg
92+
// CHECK-NEXT: %[[SHIFT:.*]] = "riscv.slli"(%[[SHIFT_B]]) <{"value" = 24 : i64}> : (!riscv.reg) -> !riscv.reg
93+
// CHECK-NEXT: "func.return"(%[[SHIFT]]) : (!riscv.reg) -> ()
94+
95+
// CHECK-LABEL: "sym_name" = "shift_too_large"
96+
// CHECK: ^{{.*}}(%[[LARGE_X:.*]] : !riscv.reg):
97+
// CHECK-NEXT: %[[LARGE_B:.*]] = "riscv.zextb"(%[[LARGE_X]]) : (!riscv.reg) -> !riscv.reg
98+
// CHECK-NEXT: %[[LARGE_SHIFT:.*]] = "riscv.slliw"(%[[LARGE_B]]) <{"value" = 25 : i64}> : (!riscv.reg) -> !riscv.reg
99+
// CHECK-NEXT: %[[LARGE_OUT:.*]] = "riscv.zextw"(%[[LARGE_SHIFT]]) : (!riscv.reg) -> !riscv.reg
100+
// CHECK-NEXT: "func.return"(%[[LARGE_OUT]]) : (!riscv.reg) -> ()
101+
102+
// CHECK-LABEL: "sym_name" = "all_byte_shifts"
103+
// CHECK: ^{{.*}}(%[[ALL_X:.*]] : !riscv.reg):
104+
// CHECK-NEXT: %[[ALL_B:.*]] = "riscv.zextb"(%[[ALL_X]]) : (!riscv.reg) -> !riscv.reg
105+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 0 : i64}> : (!riscv.reg) -> !riscv.reg
106+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 1 : i64}> : (!riscv.reg) -> !riscv.reg
107+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 2 : i64}> : (!riscv.reg) -> !riscv.reg
108+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 3 : i64}> : (!riscv.reg) -> !riscv.reg
109+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 4 : i64}> : (!riscv.reg) -> !riscv.reg
110+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 5 : i64}> : (!riscv.reg) -> !riscv.reg
111+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 6 : i64}> : (!riscv.reg) -> !riscv.reg
112+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 7 : i64}> : (!riscv.reg) -> !riscv.reg
113+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 8 : i64}> : (!riscv.reg) -> !riscv.reg
114+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 9 : i64}> : (!riscv.reg) -> !riscv.reg
115+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 10 : i64}> : (!riscv.reg) -> !riscv.reg
116+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 11 : i64}> : (!riscv.reg) -> !riscv.reg
117+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 12 : i64}> : (!riscv.reg) -> !riscv.reg
118+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 13 : i64}> : (!riscv.reg) -> !riscv.reg
119+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 14 : i64}> : (!riscv.reg) -> !riscv.reg
120+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 15 : i64}> : (!riscv.reg) -> !riscv.reg
121+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 16 : i64}> : (!riscv.reg) -> !riscv.reg
122+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 17 : i64}> : (!riscv.reg) -> !riscv.reg
123+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 18 : i64}> : (!riscv.reg) -> !riscv.reg
124+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 19 : i64}> : (!riscv.reg) -> !riscv.reg
125+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 20 : i64}> : (!riscv.reg) -> !riscv.reg
126+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 21 : i64}> : (!riscv.reg) -> !riscv.reg
127+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 22 : i64}> : (!riscv.reg) -> !riscv.reg
128+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 23 : i64}> : (!riscv.reg) -> !riscv.reg
129+
// CHECK-NEXT: %{{.*}} = "riscv.slli"(%[[ALL_B]]) <{"value" = 24 : i64}> : (!riscv.reg) -> !riscv.reg
130+
131+
// CHECK-LABEL: "sym_name" = "typed_byte_shift"
132+
// CHECK: ^{{.*}}(%[[TYPED_SHIFT_X:.*]] : !riscv.reg<x1>):
133+
// CHECK-NEXT: %[[TYPED_SHIFT_B:.*]] = "riscv.zextb"(%[[TYPED_SHIFT_X]]) : (!riscv.reg<x1>) -> !riscv.reg<x2>
134+
// CHECK-NEXT: %[[TYPED_SHIFT:.*]] = "riscv.slli"(%[[TYPED_SHIFT_B]]) <{"value" = 24 : i64}> : (!riscv.reg<x2>) -> !riscv.reg<x4>
135+
// CHECK-NEXT: "func.return"(%[[TYPED_SHIFT]]) : (!riscv.reg<x4>) -> ()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: veir-opt %s -p=riscv-combine | filecheck %s
2+
3+
"builtin.module"() ({
4+
"func.func"() <{function_type = (!riscv.reg) -> !riscv.reg, sym_name = "nested_zext"}> ({
5+
^bb0(%x : !riscv.reg):
6+
%zextb = "riscv.zextb"(%x) : (!riscv.reg) -> !riscv.reg
7+
%zextw = "riscv.zextw"(%zextb) : (!riscv.reg) -> !riscv.reg
8+
"func.return"(%zextw) : (!riscv.reg) -> ()
9+
}) : () -> ()
10+
11+
// The inner result and root use the same fixed register.
12+
"func.func"() <{function_type = (!riscv.reg<x1>) -> !riscv.reg<x3>, sym_name = "typed_nested_zext"}> ({
13+
^bb0(%x : !riscv.reg<x1>):
14+
%zextb = "riscv.zextb"(%x) : (!riscv.reg<x1>) -> !riscv.reg<x3>
15+
%zextw = "riscv.zextw"(%zextb) : (!riscv.reg<x3>) -> !riscv.reg<x3>
16+
"func.return"(%zextw) : (!riscv.reg<x3>) -> ()
17+
}) : () -> ()
18+
19+
// Matching register types use forwarding even when the inner op is shared.
20+
"func.func"() <{function_type = (!riscv.reg<x1>) -> (!riscv.reg<x3>, !riscv.reg<x3>), sym_name = "typed_nested_zext_same_type_shared"}> ({
21+
^bb0(%x : !riscv.reg<x1>):
22+
%zextb = "riscv.zextb"(%x) : (!riscv.reg<x1>) -> !riscv.reg<x3>
23+
%zextw = "riscv.zextw"(%zextb) : (!riscv.reg<x3>) -> !riscv.reg<x3>
24+
"func.return"(%zextb, %zextw) : (!riscv.reg<x3>, !riscv.reg<x3>) -> ()
25+
}) : () -> ()
26+
27+
// A distinct destination register requires a retargeted zextb.
28+
"func.func"() <{function_type = (!riscv.reg<x1>) -> !riscv.reg<x3>, sym_name = "typed_nested_zext_distinct"}> ({
29+
^bb0(%x : !riscv.reg<x1>):
30+
%zextb = "riscv.zextb"(%x) : (!riscv.reg<x1>) -> !riscv.reg<x2>
31+
%zextw = "riscv.zextw"(%zextb) : (!riscv.reg<x2>) -> !riscv.reg<x3>
32+
"func.return"(%zextw) : (!riscv.reg<x3>) -> ()
33+
}) : () -> ()
34+
35+
// Retargeting preserves the original operation when it has another user.
36+
"func.func"() <{function_type = (!riscv.reg<x1>) -> (!riscv.reg<x2>, !riscv.reg<x3>), sym_name = "typed_nested_zext_shared"}> ({
37+
^bb0(%x : !riscv.reg<x1>):
38+
%zextb = "riscv.zextb"(%x) : (!riscv.reg<x1>) -> !riscv.reg<x2>
39+
%zextw = "riscv.zextw"(%zextb) : (!riscv.reg<x2>) -> !riscv.reg<x3>
40+
"func.return"(%zextb, %zextw) : (!riscv.reg<x2>, !riscv.reg<x3>) -> ()
41+
}) : () -> ()
42+
}) : () -> ()
43+
44+
// CHECK-LABEL: "sym_name" = "nested_zext"
45+
// CHECK: ^{{.*}}(%[[NESTED_X:.*]] : !riscv.reg):
46+
// CHECK-NEXT: %[[NESTED_B:.*]] = "riscv.zextb"(%[[NESTED_X]]) : (!riscv.reg) -> !riscv.reg
47+
// CHECK-NEXT: "func.return"(%[[NESTED_B]]) : (!riscv.reg) -> ()
48+
49+
// CHECK-LABEL: "sym_name" = "typed_nested_zext"
50+
// CHECK: ^{{.*}}(%[[TYPED_NESTED_X:.*]] : !riscv.reg<x1>):
51+
// CHECK-NEXT: %[[TYPED_NESTED_B:.*]] = "riscv.zextb"(%[[TYPED_NESTED_X]]) : (!riscv.reg<x1>) -> !riscv.reg<x3>
52+
// CHECK-NEXT: "func.return"(%[[TYPED_NESTED_B]]) : (!riscv.reg<x3>) -> ()
53+
54+
// CHECK-LABEL: "sym_name" = "typed_nested_zext_same_type_shared"
55+
// CHECK: ^{{.*}}(%[[TYPED_SAME_X:.*]] : !riscv.reg<x1>):
56+
// CHECK-NEXT: %[[TYPED_SAME_B:.*]] = "riscv.zextb"(%[[TYPED_SAME_X]]) : (!riscv.reg<x1>) -> !riscv.reg<x3>
57+
// CHECK-NEXT: "func.return"(%[[TYPED_SAME_B]], %[[TYPED_SAME_B]]) : (!riscv.reg<x3>, !riscv.reg<x3>) -> ()
58+
59+
// CHECK-LABEL: "sym_name" = "typed_nested_zext_distinct"
60+
// CHECK: ^{{.*}}(%[[TYPED_DISTINCT_X:.*]] : !riscv.reg<x1>):
61+
// CHECK-NEXT: %[[TYPED_DISTINCT_B:.*]] = "riscv.zextb"(%[[TYPED_DISTINCT_X]]) : (!riscv.reg<x1>) -> !riscv.reg<x3>
62+
// CHECK-NEXT: "func.return"(%[[TYPED_DISTINCT_B]]) : (!riscv.reg<x3>) -> ()
63+
64+
// CHECK-LABEL: "sym_name" = "typed_nested_zext_shared"
65+
// CHECK: ^{{.*}}(%[[TYPED_SHARED_X:.*]] : !riscv.reg<x1>):
66+
// CHECK-NEXT: %[[TYPED_SHARED_ORIGINAL:.*]] = "riscv.zextb"(%[[TYPED_SHARED_X]]) : (!riscv.reg<x1>) -> !riscv.reg<x2>
67+
// CHECK-NEXT: %[[TYPED_SHARED_RETARGETED:.*]] = "riscv.zextb"(%[[TYPED_SHARED_X]]) : (!riscv.reg<x1>) -> !riscv.reg<x3>
68+
// CHECK-NEXT: "func.return"(%[[TYPED_SHARED_ORIGINAL]], %[[TYPED_SHARED_RETARGETED]]) : (!riscv.reg<x2>, !riscv.reg<x3>) -> ()

0 commit comments

Comments
 (0)