Skip to content

Commit db464a3

Browse files
author
Aditya Nandakumar
committed
[GISel] Add new GISel combiners for G_SELECT
https://reviews.llvm.org/D83833 Patch adds two new GICombinerRules for G_SELECT. The rules include: combining selects with undef comparisons into their first selectee value, and to combine away selects with constant comparisons. Patch additionally adds a new combiner test for the AArch64 target to test these new G_SELECT combiner rules and the existing select_same_val combiner rule. Patch by mkitzan
1 parent a7e4a17 commit db464a3

File tree

5 files changed

+125
-13
lines changed

5 files changed

+125
-13
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ class CombinerHelper {
272272
/// Return true if a G_STORE instruction \p MI is storing an undef value.
273273
bool matchUndefStore(MachineInstr &MI);
274274

275+
/// Return true if a G_SELECT instruction \p MI has an undef comparison.
276+
bool matchUndefSelectCmp(MachineInstr &MI);
277+
278+
/// Return true if a G_SELECT instruction \p MI has a constant comparison. If
279+
/// true, \p OpIdx will store the operand index of the known selected value.
280+
bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
281+
275282
/// Replace an instruction with a G_FCONSTANT with value \p C.
276283
bool replaceInstWithFConstant(MachineInstr &MI, double C);
277284

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,24 @@ def select_same_val: GICombineRule<
225225
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
226226
>;
227227

228+
// Fold (undef ? x : y) -> y
229+
def select_undef_cmp: GICombineRule<
230+
(defs root:$root),
231+
(match (wip_match_opcode G_SELECT):$root,
232+
[{ return Helper.matchUndefSelectCmp(*${root}); }]),
233+
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
234+
>;
235+
236+
// Fold (true ? x : y) -> x
237+
// Fold (false ? x : y) -> y
238+
def select_constant_cmp_matchdata : GIDefMatchData<"unsigned">;
239+
def select_constant_cmp: GICombineRule<
240+
(defs root:$root, select_constant_cmp_matchdata:$matchinfo),
241+
(match (wip_match_opcode G_SELECT):$root,
242+
[{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
243+
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
244+
>;
245+
228246
// Fold x op 0 -> x
229247
def right_identity_zero: GICombineRule<
230248
(defs root:$root),
@@ -341,10 +359,12 @@ def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
341359

342360
def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend]>;
343361

362+
def select_combines : GICombineGroup<[select_undef_cmp, select_constant_cmp]>;
363+
344364
def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl, add_p2i_to_ptradd]>;
345365
def all_combines : GICombineGroup<[trivial_combines, ptr_add_immed_chain,
346366
combines_for_extload, combine_indexed_load_store, undef_combines,
347367
identity_combines, simplify_add_to_sub,
348368
hoist_logic_op_with_same_opcode_hands,
349369
shl_ashr_to_sext_inreg, sext_inreg_of_load,
350-
width_reduction_combines]>;
370+
width_reduction_combines, select_combines]>;

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,22 @@ bool CombinerHelper::matchUndefStore(MachineInstr &MI) {
17701770
MRI);
17711771
}
17721772

1773+
bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
1774+
assert(MI.getOpcode() == TargetOpcode::G_SELECT);
1775+
return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(),
1776+
MRI);
1777+
}
1778+
1779+
bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
1780+
assert(MI.getOpcode() == TargetOpcode::G_SELECT);
1781+
if (auto MaybeCstCmp =
1782+
getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) {
1783+
OpIdx = MaybeCstCmp->Value ? 2 : 3;
1784+
return true;
1785+
}
1786+
return false;
1787+
}
1788+
17731789
bool CombinerHelper::eraseInst(MachineInstr &MI) {
17741790
MI.eraseFromParent();
17751791
return true;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
3+
# RUN: llc -debugify-and-strip-all-safe -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
4+
---
5+
# select (c, x, x) -> x
6+
name: test_combine_select_same_res
7+
body: |
8+
bb.1:
9+
liveins: $x0, $x1
10+
; CHECK-LABEL: name: test_combine_select_same_res
11+
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
12+
; CHECK: $x0 = COPY [[COPY]](s64)
13+
%0:_(s64) = COPY $x0
14+
%1:_(s1) = G_TRUNC %0
15+
%2:_(s64) = G_SELECT %1, %0, %0
16+
$x0 = COPY %2(s64)
17+
...
18+
---
19+
# select (undef, x, y) -> y
20+
name: test_combine_select_undef_res0_res1
21+
body: |
22+
bb.1:
23+
liveins: $x0, $x1
24+
; CHECK-LABEL: name: test_combine_select_undef_res0_res1
25+
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
26+
; CHECK: $x0 = COPY [[COPY]](s64)
27+
%0:_(s64) = COPY $x0
28+
%1:_(s64) = COPY $x1
29+
%2:_(s1) = G_IMPLICIT_DEF
30+
%3:_(s64) = G_SELECT %2, %0, %1
31+
$x0 = COPY %3(s64)
32+
...
33+
---
34+
# select (false, x, y) -> y
35+
name: test_combine_select_false_res0_res1
36+
body: |
37+
bb.1:
38+
liveins: $x0, $x1
39+
; CHECK-LABEL: name: test_combine_select_false_res0_res1
40+
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x1
41+
; CHECK: $x0 = COPY [[COPY]](s64)
42+
%0:_(s64) = COPY $x0
43+
%1:_(s64) = COPY $x1
44+
%2:_(s1) = G_CONSTANT i1 false
45+
%3:_(s64) = G_SELECT %2, %0, %1
46+
$x0 = COPY %3(s64)
47+
...
48+
---
49+
# select (true, x, y) -> x
50+
name: test_combine_select_true_res0_res1
51+
body: |
52+
bb.1:
53+
liveins: $x0, $x1
54+
; CHECK-LABEL: name: test_combine_select_true_res0_res1
55+
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
56+
; CHECK: $x0 = COPY [[COPY]](s64)
57+
%0:_(s64) = COPY $x0
58+
%1:_(s64) = COPY $x1
59+
%2:_(s1) = G_CONSTANT i1 true
60+
%3:_(s64) = G_SELECT %2, %0, %1
61+
$x0 = COPY %3(s64)
62+
...

llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@ name: select_from_different_results_of_unmerge_values
66
tracksRegLiveness: true
77
body: |
88
bb.0:
9+
liveins: $vgpr0
910
1011
; GCN-LABEL: name: select_from_different_results_of_unmerge_values
12+
; GCN: liveins: $vgpr0
1113
; GCN: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
12-
; GCN: [[DEF1:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
14+
; GCN: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0
15+
; GCN: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32)
1316
; GCN: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](<2 x s32>)
14-
; GCN: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[DEF1]](s1), [[UV]], [[UV1]]
17+
; GCN: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[TRUNC]](s1), [[UV]], [[UV1]]
1518
; GCN: $vgpr0 = COPY [[SELECT]](s32)
1619
; GCN: SI_RETURN_TO_EPILOG $vgpr0
17-
%2:_(<2 x s32>) = G_IMPLICIT_DEF
18-
%4:_(s1) = G_IMPLICIT_DEF
19-
%0:_(s32), %1:_(s32) = G_UNMERGE_VALUES %2:_(<2 x s32>)
20-
%3:_(s32) = G_SELECT %4:_(s1), %0:_, %1:_
21-
$vgpr0 = COPY %3
20+
%0:_(<2 x s32>) = G_IMPLICIT_DEF
21+
%1:_(s32) = COPY $vgpr0
22+
%2:_(s1) = G_TRUNC %1:_(s32)
23+
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %0:_(<2 x s32>)
24+
%5:_(s32) = G_SELECT %2:_(s1), %3:_, %4:_
25+
$vgpr0 = COPY %5
2226
SI_RETURN_TO_EPILOG $vgpr0
2327
2428
...
@@ -28,17 +32,20 @@ name: select_from_same_results_of_unmerge_values
2832
tracksRegLiveness: true
2933
body: |
3034
bb.0:
35+
liveins: $vgpr0
3136
3237
; GCN-LABEL: name: select_from_same_results_of_unmerge_values
38+
; GCN: liveins: $vgpr0
3339
; GCN: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
3440
; GCN: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](<2 x s32>)
3541
; GCN: $vgpr0 = COPY [[UV]](s32)
3642
; GCN: SI_RETURN_TO_EPILOG $vgpr0
37-
%2:_(<2 x s32>) = G_IMPLICIT_DEF
38-
%4:_(s1) = G_IMPLICIT_DEF
39-
%0:_(s32), %1:_(s32) = G_UNMERGE_VALUES %2:_(<2 x s32>)
40-
%3:_(s32) = G_SELECT %4:_(s1), %0:_, %0:_
41-
$vgpr0 = COPY %3
43+
%0:_(<2 x s32>) = G_IMPLICIT_DEF
44+
%1:_(s32) = COPY $vgpr0
45+
%2:_(s1) = G_TRUNC %1:_(s32)
46+
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %0:_(<2 x s32>)
47+
%5:_(s32) = G_SELECT %2:_(s1), %3:_, %3:_
48+
$vgpr0 = COPY %5
4249
SI_RETURN_TO_EPILOG $vgpr0
4350
4451
...

0 commit comments

Comments
 (0)