[llvm] d5ee720 - [GlobalISel] Implement identity transforms for x op x -> x
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 18:26:08 PDT 2020
Author: Jessica Paquette
Date: 2020-03-30T18:22:37-07:00
New Revision: d5ee72065b9e5d28f89b1200133e80ce60cb99a0
URL: https://github.com/llvm/llvm-project/commit/d5ee72065b9e5d28f89b1200133e80ce60cb99a0
DIFF: https://github.com/llvm/llvm-project/commit/d5ee72065b9e5d28f89b1200133e80ce60cb99a0.diff
LOG: [GlobalISel] Implement identity transforms for x op x -> x
When we have
```
a = G_OR x, x
```
or
```
b = G_AND y, y
```
We can drop the G_OR/G_AND and just use x/y respectively.
Also update arm64-fallback.ll because there was an or in there which hits this
transformation.
Differential Revision: https://reviews.llvm.org/D77105
Added:
llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-binop-same-val.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/AArch64/GlobalISel/arm64-fallback.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 1e7d38315203..f01cd36751af 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -228,6 +228,9 @@ class CombinerHelper {
/// Optimize (cond ? x : x) -> x
bool matchSelectSameVal(MachineInstr &MI);
+ /// Optimize (x op x) -> x
+ bool matchBinOpSameVal(MachineInstr &MI);
+
/// 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 0d6b6c6f7629..e9fe821a6f22 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -200,6 +200,14 @@ def right_identity_zero: GICombineRule<
(apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
+// Fold (x op x) - > x
+def binop_same_val: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_AND, G_OR):$root,
+ [{ return Helper.matchBinOpSameVal(*${root}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
// 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,
@@ -207,7 +215,8 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
propagate_undef_all_ops,
propagate_undef_shuffle_mask]>;
-def identity_combines : GICombineGroup<[select_same_val, right_identity_zero]>;
+def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
+ binop_same_val]>;
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 6aaf5cdf88c5..1e4824e85757 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -1574,6 +1574,12 @@ bool CombinerHelper::matchSelectSameVal(MachineInstr &MI) {
MRI);
}
+bool CombinerHelper::matchBinOpSameVal(MachineInstr &MI) {
+ return matchEqualDefs(MI.getOperand(1), MI.getOperand(2)) &&
+ canReplaceReg(MI.getOperand(0).getReg(), MI.getOperand(1).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/arm64-fallback.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
index d36b23864937..2b498d2ab9a4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
@@ -153,7 +153,9 @@ define void @nonpow2_add_narrowing() {
define void @nonpow2_or_narrowing() {
%a = add i128 undef, undef
%b = trunc i128 %a to i96
- %dummy = or i96 %b, %b
+ %a2 = add i128 undef, undef
+ %b2 = trunc i128 %a2 to i96
+ %dummy = or i96 %b, %b2
store i96 %dummy, i96* undef
ret void
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-binop-same-val.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-binop-same-val.mir
new file mode 100644
index 000000000000..3c70c4171983
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-binop-same-val.mir
@@ -0,0 +1,96 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+name: or_same
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x0
+
+ ; Fold: x or x -> x
+ ; CHECK-LABEL: name: or_same
+ ; CHECK: liveins: $x0
+ ; CHECK: %copy:_(s64) = COPY $x0
+ ; CHECK: $x0 = COPY %copy(s64)
+ ; CHECK: RET_ReallyLR implicit $x0
+ %copy:_(s64) = COPY $x0
+ %or:_(s64) = G_OR %copy, %copy
+ $x0 = COPY %or(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: and_same
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x0
+
+ ; Fold: x and x -> x
+
+ ; CHECK-LABEL: name: and_same
+ ; CHECK: liveins: $x0
+ ; CHECK: %copy:_(s64) = COPY $x0
+ ; CHECK: $x0 = COPY %copy(s64)
+ ; CHECK: RET_ReallyLR implicit $x0
+ %copy:_(s64) = COPY $x0
+ %and:_(s64) = G_AND %copy, %copy
+ $x0 = COPY %and(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: and_same2
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x0, $x1
+
+ ; We can fold when the LHS and RHS are guaranteed to be identical.
+
+ ; CHECK-LABEL: name: and_same2
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK: %copy1:_(s64) = COPY $x0
+ ; CHECK: %copy2:_(s64) = COPY $x1
+ ; CHECK: %or:_(s64) = G_OR %copy1, %copy2
+ ; CHECK: $x0 = COPY %or(s64)
+ ; CHECK: RET_ReallyLR implicit $x0
+ %copy1:_(s64) = COPY $x0
+ %copy2:_(s64) = COPY $x1
+ %or:_(s64) = G_OR %copy1, %copy2
+ %same_as_or:_(s64) = COPY %or(s64)
+ %and:_(s64) = G_AND %or, %same_as_or
+ $x0 = COPY %and(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: or_and_not_same
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+ ; None of the G_ORs or G_ANDs should be eliminated here, because their LHS
+ ; and RHS values are
diff erent.
+
+ ; CHECK-LABEL: name: or_and_not_same
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK: %copy1:_(s64) = COPY $x0
+ ; CHECK: %copy2:_(s64) = COPY $x1
+ ; CHECK: %copy3:_(s64) = COPY $x2
+ ; CHECK: %or1:_(s64) = G_OR %copy1, %copy2
+ ; CHECK: %or2:_(s64) = G_OR %copy1, %copy3
+ ; CHECK: %and:_(s64) = G_AND %or1, %or2
+ ; CHECK: $x0 = COPY %and(s64)
+ ; CHECK: RET_ReallyLR implicit $x0
+ %copy1:_(s64) = COPY $x0
+ %copy2:_(s64) = COPY $x1
+ %copy3:_(s64) = COPY $x2
+ %or1:_(s64) = G_OR %copy1, %copy2
+ %or2:_(s64) = G_OR %copy1, %copy3
+ %and:_(s64) = G_AND %or1, %or2
+ $x0 = COPY %and(s64)
+ RET_ReallyLR implicit $x0
+
+...
More information about the llvm-commits
mailing list