[llvm] ae98939 - GlobalISel: Fold G_MUL x, 0, and G_*DIV 0, x
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon May 18 15:08:33 PDT 2020
Author: Matt Arsenault
Date: 2020-05-18T18:08:26-04:00
New Revision: ae989391723478c6e8c61b68dd4c575798f340db
URL: https://github.com/llvm/llvm-project/commit/ae989391723478c6e8c61b68dd4c575798f340db
DIFF: https://github.com/llvm/llvm-project/commit/ae989391723478c6e8c61b68dd4c575798f340db.diff
LOG: GlobalISel: Fold G_MUL x, 0, and G_*DIV 0, x
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-trivial-arith.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index ccea66853af3..c8d7ad358ef7 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -231,6 +231,9 @@ class CombinerHelper {
/// Optimize (x op x) -> x
bool matchBinOpSameVal(MachineInstr &MI);
+ /// Check if operand \p OpIdx is zero.
+ bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx);
+
/// Try to transform \p MI by using all of the above
/// combine functions. Returns true if changed.
bool tryCombine(MachineInstr &MI);
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index e9fe821a6f22..af4590707c3f 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -208,6 +208,22 @@ def binop_same_val: GICombineRule<
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
+// Fold (0 op x) - > 0
+def binop_left_to_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SDIV, G_UDIV, G_SREM, G_UREM):$root,
+ [{ return Helper.matchOperandIsZero(*${root}, 1); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
+// Fold (x op 0) - > 0
+def binop_right_to_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_MUL):$root,
+ [{ return Helper.matchOperandIsZero(*${root}, 2); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+>;
+
// 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,
@@ -216,7 +232,8 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
propagate_undef_shuffle_mask]>;
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
- binop_same_val]>;
+ binop_same_val, binop_left_to_zero,
+ binop_right_to_zero]>;
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 1627f7678f50..54824a3a4eb2 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -1587,6 +1587,12 @@ bool CombinerHelper::matchBinOpSameVal(MachineInstr &MI) {
MRI);
}
+bool CombinerHelper::matchOperandIsZero(MachineInstr &MI, unsigned OpIdx) {
+ return matchConstantOp(MI.getOperand(OpIdx), 0) &&
+ canReplaceReg(MI.getOperand(0).getReg(), MI.getOperand(OpIdx).getReg(),
+ MRI);
+}
+
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-trivial-arith.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
index ec9157f190a7..1252917fdb3e 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir
@@ -40,6 +40,132 @@ body: |
RET_ReallyLR implicit $w0
...
+---
+name: mul_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0
+ ; Fold (x * 0) -> 0
+ ;
+ ; CHECK-LABEL: name: mul_0
+ ; CHECK: liveins: $w0
+ ; CHECK: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK: $w0 = COPY %cst(s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_MUL %x(s32), %cst
+ $w0 = COPY %op(s32)
+ RET_ReallyLR implicit $w0
+
+...
+
+# FIXME: Probably should be able to replace this.
+---
+name: mul_0_cant_replace
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0
+ ; Fold (x * 0) -> 0
+ ;
+ ; CHECK-LABEL: name: mul_0_cant_replace
+ ; CHECK: liveins: $w0
+ ; CHECK: %x:_(s32) = COPY $w0
+ ; CHECK: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK: %op:gpr(s32) = G_MUL %x, %cst
+ ; CHECK: $w0 = COPY %op(s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:gpr(s32) = G_MUL %x(s32), %cst
+ $w0 = COPY %op(s32)
+ RET_ReallyLR implicit $w0
+
+...
+
+---
+name: sdiv_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0
+ ; Fold (0 / x) -> 0
+ ;
+ ; CHECK-LABEL: name: sdiv_0
+ ; CHECK: liveins: $w0
+ ; CHECK: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK: $w0 = COPY %cst(s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_SDIV %cst, %x
+ $w0 = COPY %op(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: udiv_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0
+ ; Fold (0 / x) -> 0
+ ;
+ ; CHECK-LABEL: name: udiv_0
+ ; CHECK: liveins: $w0
+ ; CHECK: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK: $w0 = COPY %cst(s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_UDIV %cst, %x
+ $w0 = COPY %op(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: srem_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0
+ ; Fold (0 % x) -> 0
+ ;
+ ; CHECK-LABEL: name: srem_0
+ ; CHECK: liveins: $w0
+ ; CHECK: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK: $w0 = COPY %cst(s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_SREM %cst, %x
+ $w0 = COPY %op(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: urem_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0
+ ; Fold (0 % x) -> 0
+ ;
+ ; CHECK-LABEL: name: urem_0
+ ; CHECK: liveins: $w0
+ ; CHECK: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK: $w0 = COPY %cst(s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_UREM %cst, %x
+ $w0 = COPY %op(s32)
+ RET_ReallyLR implicit $w0
+
+...
+
---
name: right_ident_or
tracksRegLiveness: true
More information about the llvm-commits
mailing list