[llvm] db464a3 - [GISel] Add new GISel combiners for G_SELECT
Aditya Nandakumar via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 09:47:34 PDT 2020
Author: Aditya Nandakumar
Date: 2020-08-27T09:40:15-07:00
New Revision: db464a3dbf0e8fed363a7b2b9a5b320514ca60f8
URL: https://github.com/llvm/llvm-project/commit/db464a3dbf0e8fed363a7b2b9a5b320514ca60f8
DIFF: https://github.com/llvm/llvm-project/commit/db464a3dbf0e8fed363a7b2b9a5b320514ca60f8.diff
LOG: [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
Added:
llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 0017fa14c10a..77b55928d586 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -272,6 +272,13 @@ class CombinerHelper {
/// Return true if a G_STORE instruction \p MI is storing an undef value.
bool matchUndefStore(MachineInstr &MI);
+ /// Return true if a G_SELECT instruction \p MI has an undef comparison.
+ bool matchUndefSelectCmp(MachineInstr &MI);
+
+ /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
+ /// true, \p OpIdx will store the operand index of the known selected value.
+ bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
+
/// Replace an instruction with a G_FCONSTANT with value \p C.
bool replaceInstWithFConstant(MachineInstr &MI, double C);
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index c2d721854af0..eb2810844637 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -225,6 +225,24 @@ def select_same_val: GICombineRule<
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
>;
+// Fold (undef ? x : y) -> y
+def select_undef_cmp: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SELECT):$root,
+ [{ return Helper.matchUndefSelectCmp(*${root}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+>;
+
+// Fold (true ? x : y) -> x
+// Fold (false ? x : y) -> y
+def select_constant_cmp_matchdata : GIDefMatchData<"unsigned">;
+def select_constant_cmp: GICombineRule<
+ (defs root:$root, select_constant_cmp_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SELECT):$root,
+ [{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
+>;
+
// Fold x op 0 -> x
def right_identity_zero: GICombineRule<
(defs root:$root),
@@ -341,10 +359,12 @@ def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend]>;
+def select_combines : GICombineGroup<[select_undef_cmp, select_constant_cmp]>;
+
def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl, add_p2i_to_ptradd]>;
def all_combines : GICombineGroup<[trivial_combines, ptr_add_immed_chain,
combines_for_extload, combine_indexed_load_store, undef_combines,
identity_combines, simplify_add_to_sub,
hoist_logic_op_with_same_opcode_hands,
shl_ashr_to_sext_inreg, sext_inreg_of_load,
- width_reduction_combines]>;
+ width_reduction_combines, select_combines]>;
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 232f6d672c48..0486be1dabb6 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -1770,6 +1770,22 @@ bool CombinerHelper::matchUndefStore(MachineInstr &MI) {
MRI);
}
+bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SELECT);
+ return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(),
+ MRI);
+}
+
+bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
+ assert(MI.getOpcode() == TargetOpcode::G_SELECT);
+ if (auto MaybeCstCmp =
+ getConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) {
+ OpIdx = MaybeCstCmp->Value ? 2 : 3;
+ return true;
+ }
+ return false;
+}
+
bool CombinerHelper::eraseInst(MachineInstr &MI) {
MI.eraseFromParent();
return true;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
new file mode 100644
index 000000000000..83e5abdd736d
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
@@ -0,0 +1,62 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+# RUN: llc -debugify-and-strip-all-safe -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+---
+# select (c, x, x) -> x
+name: test_combine_select_same_res
+body: |
+ bb.1:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: test_combine_select_same_res
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s1) = G_TRUNC %0
+ %2:_(s64) = G_SELECT %1, %0, %0
+ $x0 = COPY %2(s64)
+...
+---
+# select (undef, x, y) -> y
+name: test_combine_select_undef_res0_res1
+body: |
+ bb.1:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: test_combine_select_undef_res0_res1
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s1) = G_IMPLICIT_DEF
+ %3:_(s64) = G_SELECT %2, %0, %1
+ $x0 = COPY %3(s64)
+...
+---
+# select (false, x, y) -> y
+name: test_combine_select_false_res0_res1
+body: |
+ bb.1:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: test_combine_select_false_res0_res1
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s1) = G_CONSTANT i1 false
+ %3:_(s64) = G_SELECT %2, %0, %1
+ $x0 = COPY %3(s64)
+...
+---
+# select (true, x, y) -> x
+name: test_combine_select_true_res0_res1
+body: |
+ bb.1:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: test_combine_select_true_res0_res1
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s1) = G_CONSTANT i1 true
+ %3:_(s64) = G_SELECT %2, %0, %1
+ $x0 = COPY %3(s64)
+...
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
index 89f58e1e7687..b8109fe6c87c 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-select.mir
@@ -6,19 +6,23 @@ name: select_from_
diff erent_results_of_unmerge_values
tracksRegLiveness: true
body: |
bb.0:
+ liveins: $vgpr0
; GCN-LABEL: name: select_from_
diff erent_results_of_unmerge_values
+ ; GCN: liveins: $vgpr0
; GCN: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
- ; GCN: [[DEF1:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+ ; GCN: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0
+ ; GCN: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s32)
; GCN: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](<2 x s32>)
- ; GCN: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[DEF1]](s1), [[UV]], [[UV1]]
+ ; GCN: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[TRUNC]](s1), [[UV]], [[UV1]]
; GCN: $vgpr0 = COPY [[SELECT]](s32)
; GCN: SI_RETURN_TO_EPILOG $vgpr0
- %2:_(<2 x s32>) = G_IMPLICIT_DEF
- %4:_(s1) = G_IMPLICIT_DEF
- %0:_(s32), %1:_(s32) = G_UNMERGE_VALUES %2:_(<2 x s32>)
- %3:_(s32) = G_SELECT %4:_(s1), %0:_, %1:_
- $vgpr0 = COPY %3
+ %0:_(<2 x s32>) = G_IMPLICIT_DEF
+ %1:_(s32) = COPY $vgpr0
+ %2:_(s1) = G_TRUNC %1:_(s32)
+ %3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %0:_(<2 x s32>)
+ %5:_(s32) = G_SELECT %2:_(s1), %3:_, %4:_
+ $vgpr0 = COPY %5
SI_RETURN_TO_EPILOG $vgpr0
...
@@ -28,17 +32,20 @@ name: select_from_same_results_of_unmerge_values
tracksRegLiveness: true
body: |
bb.0:
+ liveins: $vgpr0
; GCN-LABEL: name: select_from_same_results_of_unmerge_values
+ ; GCN: liveins: $vgpr0
; GCN: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; GCN: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[DEF]](<2 x s32>)
; GCN: $vgpr0 = COPY [[UV]](s32)
; GCN: SI_RETURN_TO_EPILOG $vgpr0
- %2:_(<2 x s32>) = G_IMPLICIT_DEF
- %4:_(s1) = G_IMPLICIT_DEF
- %0:_(s32), %1:_(s32) = G_UNMERGE_VALUES %2:_(<2 x s32>)
- %3:_(s32) = G_SELECT %4:_(s1), %0:_, %0:_
- $vgpr0 = COPY %3
+ %0:_(<2 x s32>) = G_IMPLICIT_DEF
+ %1:_(s32) = COPY $vgpr0
+ %2:_(s1) = G_TRUNC %1:_(s32)
+ %3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %0:_(<2 x s32>)
+ %5:_(s32) = G_SELECT %2:_(s1), %3:_, %3:_
+ $vgpr0 = COPY %5
SI_RETURN_TO_EPILOG $vgpr0
...
More information about the llvm-commits
mailing list