[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