[llvm] c999084 - [GlobalISel] Port some basic shufflevector undef combines from the DAGCombiner
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 19 16:48:56 PDT 2020
Author: Jessica Paquette
Date: 2020-03-19T16:46:06-07:00
New Revision: c999084619a61daffac39f0ec9ea3c801e5a8823
URL: https://github.com/llvm/llvm-project/commit/c999084619a61daffac39f0ec9ea3c801e5a8823
DIFF: https://github.com/llvm/llvm-project/commit/c999084619a61daffac39f0ec9ea3c801e5a8823.diff
LOG: [GlobalISel] Port some basic shufflevector undef combines from the DAGCombiner
Port over the following:
- shuffle undef, undef, any_mask -> undef
- shuffle anything, anything, undef_mask -> undef
This sort of thing shows up a lot when you try to bugpoint code containing
shufflevector.
Differential Revision: https://reviews.llvm.org/D76382
Added:
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-undef.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index d47dddf88f51..36b80276ac47 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -194,6 +194,13 @@ class CombinerHelper {
/// G_IMPLICIT_DEF.
bool matchAnyExplicitUseIsUndef(MachineInstr &MI);
+ /// Return true if all register explicit use operands on \p MI are defined by
+ /// a G_IMPLICIT_DEF.
+ bool matchAllExplicitUsesAreUndef(MachineInstr &MI);
+
+ /// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
+ bool matchUndefShuffleVectorMask(MachineInstr &MI);
+
/// 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 baa31d0a09e5..ebe7ea35b548 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -161,14 +161,35 @@ def undef_to_negative_one: GICombineRule<
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithConstant(*${root}, -1); }])>;
-def propagate_undef: GICombineRule<
+// Instructions where if any source operand is undef, the instruction can be
+// replaced with undef.
+def propagate_undef_any_op: GICombineRule<
(defs root:$root),
(match (wip_match_opcode G_ADD, G_FPTOSI, G_FPTOUI, G_SUB, G_XOR):$root,
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+// Instructions where if all source operands are undef, the instruction can be
+// replaced with undef.
+def propagate_undef_all_ops: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+ [{ return Helper.matchAllExplicitUsesAreUndef(*${root}); }]),
+ (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+
+// Replace a G_SHUFFLE_VECTOR with an undef mask with a G_IMPLICIT_DEF.
+def propagate_undef_shuffle_mask: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+ [{ return Helper.matchUndefShuffleVectorMask(*${root}); }]),
+ (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+
+// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
- undef_to_negative_one, propagate_undef]>;
+ undef_to_negative_one,
+ propagate_undef_any_op,
+ propagate_undef_all_ops,
+ propagate_undef_shuffle_mask]>;
def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl]>;
def all_combines : GICombineGroup<[trivial_combines, ptr_add_immed_chain,
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index ecb46f401fb4..195698245fd9 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -1490,6 +1490,19 @@ bool CombinerHelper::matchAnyExplicitUseIsUndef(MachineInstr &MI) {
});
}
+bool CombinerHelper::matchAllExplicitUsesAreUndef(MachineInstr &MI) {
+ return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
+ return !MO.isReg() ||
+ getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
+ });
+}
+
+bool CombinerHelper::matchUndefShuffleVectorMask(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
+ ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
+ return all_of(Mask, [](int Elt) { return Elt < 0; });
+}
+
bool CombinerHelper::replaceInstWithFConstant(MachineInstr &MI, double C) {
assert(MI.getNumDefs() == 1 && "Expected only one def?");
Builder.setInstr(MI);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-undef.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-undef.mir
index 2c5f12ac9d8d..f1e14a32ee22 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-undef.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-undef.mir
@@ -166,3 +166,61 @@ body: |
RET_ReallyLR implicit $w0
...
+---
+name: shufflevector_undef_ops_to_undef
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: shufflevector_undef_ops_to_undef
+ ; CHECK: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+ ; CHECK: $d0 = COPY [[DEF]](<2 x s32>)
+ ; CHECK: RET_ReallyLR implicit $d0
+ %1:_(<2 x s32>) = G_IMPLICIT_DEF
+ %2:_(<2 x s32>) = G_IMPLICIT_DEF
+ %0:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2(<2 x s32>), shufflemask(0, 1)
+ $d0 = COPY %0(<2 x s32>)
+ RET_ReallyLR implicit $d0
+
+...
+---
+name: shufflevector_undef_mask_to_undef
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $d0, $d1
+ ; CHECK-LABEL: name: shufflevector_undef_mask_to_undef
+ ; CHECK: liveins: $d0, $d1
+ ; CHECK: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+ ; CHECK: $d0 = COPY [[DEF]](<2 x s32>)
+ ; CHECK: RET_ReallyLR implicit $d0
+ %0:_(<2 x s32>) = COPY $d0
+ %1:_(<2 x s32>) = COPY $d1
+ %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(undef, undef)
+ $d0 = COPY %2(<2 x s32>)
+ RET_ReallyLR implicit $d0
+
+...
+---
+name: shufflevector_not_all_ops_undef
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $d0
+ ; Show that we don't do the combine when one of the vectors is not a
+ ; G_IMPLICIT_DEF.
+ ;
+ ; CHECK-LABEL: name: shufflevector_not_all_ops_undef
+ ; CHECK: liveins: $d0
+ ; CHECK: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+ ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
+ ; CHECK: [[SHUF:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[DEF]](<2 x s32>), [[COPY]], shufflemask(0, 1)
+ ; CHECK: $d0 = COPY [[SHUF]](<2 x s32>)
+ ; CHECK: RET_ReallyLR implicit $d0
+ %1:_(<2 x s32>) = G_IMPLICIT_DEF
+ %2:_(<2 x s32>) = COPY $d0
+ %0:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2(<2 x s32>), shufflemask(0, 1)
+ $d0 = COPY %0(<2 x s32>)
+ RET_ReallyLR implicit $d0
More information about the llvm-commits
mailing list