[llvm] 036a130 - [GlobalISel] Combine (X op Y) == X --> Y == 0
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 11 09:53:10 PDT 2022
Author: Jessica Paquette
Date: 2022-10-11T09:52:48-07:00
New Revision: 036a13065b7a744efcc48cdc0bca3b878ed906fd
URL: https://github.com/llvm/llvm-project/commit/036a13065b7a744efcc48cdc0bca3b878ed906fd
DIFF: https://github.com/llvm/llvm-project/commit/036a13065b7a744efcc48cdc0bca3b878ed906fd.diff
LOG: [GlobalISel] Combine (X op Y) == X --> Y == 0
This matches patterns of the form
```
(X op Y) == X
```
And transforms them to
```
Y == 0
```
where appropriate.
Example: https://godbolt.org/z/hfW811c7W
Differential Revision: https://reviews.llvm.org/D135380
Added:
llvm/test/CodeGen/AArch64/GlobalISel/combine-icmp-of-binop-to-icmp-of-0.mir
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 12b6124bde5e9..515382a8e869e 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -768,6 +768,15 @@ class CombinerHelper {
/// to a min/max instruction of some sort.
bool matchSimplifySelectToMinMax(MachineInstr &MI, BuildFnTy &MatchInfo);
+ /// Transform:
+ /// (X + Y) == X -> Y == 0
+ /// (X - Y) == X -> Y == 0
+ /// (X ^ Y) == X -> Y == 0
+ /// (X + Y) != X -> Y != 0
+ /// (X - Y) != X -> Y != 0
+ /// (X ^ Y) != X -> Y != 0
+ bool matchRedundantBinOpInEquality(MachineInstr &MI, BuildFnTy &MatchInfo);
+
private:
/// Given a non-indexed load or store instruction \p MI, find an offset that
/// can be usefully and legally folded into it as a post-indexing operation.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 2d61315924006..d2fad89dd0a3b 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -736,6 +736,12 @@ def icmp_to_lhs_known_bits : GICombineRule<
[{ return Helper.matchICmpToLHSKnownBits(*${root}, ${info}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
+def redundant_binop_in_equality : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$info),
+ (match (wip_match_opcode G_ICMP):$root,
+ [{ return Helper.matchRedundantBinOpInEquality(*${root}, ${info}); }]),
+ (apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
+
def and_or_disjoint_mask : GICombineRule<
(defs root:$root, build_fn_matchinfo:$info),
(match (wip_match_opcode G_AND):$root,
@@ -1045,7 +1051,7 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
form_bitfield_extract, constant_fold, fabs_fneg_fold,
intdiv_combines, mulh_combines, redundant_neg_operands,
and_or_disjoint_mask, fma_combines, fold_binop_into_select,
- sub_add_reg, select_to_minmax]>;
+ sub_add_reg, select_to_minmax, redundant_binop_in_equality]>;
// A combine group used to for prelegalizer combiners at -O0. The combines in
// this group have been selected based on experiments to balance code size and
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 32d4b53e079f9..f3a58cc65fe19 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DivisionByConstantInfo.h"
#include "llvm/Support/MathExtras.h"
@@ -6060,6 +6061,38 @@ bool CombinerHelper::matchSimplifySelectToMinMax(MachineInstr &MI,
return matchFPSelectToMinMax(Dst, Cond, TrueVal, FalseVal, MatchInfo);
}
+bool CombinerHelper::matchRedundantBinOpInEquality(MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_ICMP);
+ // (X + Y) == X --> Y == 0
+ // (X + Y) != X --> Y != 0
+ // (X - Y) == X --> Y == 0
+ // (X - Y) != X --> Y != 0
+ // (X ^ Y) == X --> Y == 0
+ // (X ^ Y) != X --> Y != 0
+ Register Dst = MI.getOperand(0).getReg();
+ CmpInst::Predicate Pred;
+ Register X, Y, OpLHS, OpRHS;
+ bool MatchedSub = mi_match(
+ Dst, MRI,
+ m_c_GICmp(m_Pred(Pred), m_Reg(X), m_GSub(m_Reg(OpLHS), m_Reg(Y))));
+ if (MatchedSub && X != OpLHS)
+ return false;
+ if (!MatchedSub) {
+ if (!mi_match(Dst, MRI,
+ m_c_GICmp(m_Pred(Pred), m_Reg(X),
+ m_any_of(m_GAdd(m_Reg(OpLHS), m_Reg(OpRHS)),
+ m_GXor(m_Reg(OpLHS), m_Reg(OpRHS))))))
+ return false;
+ Y = X == OpLHS ? OpRHS : X == OpRHS ? OpLHS : Register();
+ }
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Zero = B.buildConstant(MRI.getType(Y), 0);
+ B.buildICmp(Pred, Dst, Y, Zero);
+ };
+ return CmpInst::isEquality(Pred) && Y.isValid();
+}
+
bool CombinerHelper::tryCombine(MachineInstr &MI) {
if (tryCombineCopy(MI))
return true;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-icmp-of-binop-to-icmp-of-0.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-icmp-of-binop-to-icmp-of-0.mir
new file mode 100644
index 0000000000000..966b781463fd0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-icmp-of-binop-to-icmp-of-0.mir
@@ -0,0 +1,863 @@
+# 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
+
+# Test:
+# (X + Y) == X --> Y == 0
+# (X - Y) == X --> Y == 0
+# (X ^ Y) == X --> Y == 0
+# (X + Y) != X --> Y != 0
+# (X - Y) != X --> Y != 0
+# (X ^ Y) != X --> Y != 0
+#
+# And all commuted cases.
+
+...
+---
+name: add_scalar_eq
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_scalar_eq
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: add_vector_eq
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_vector_eq
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_ADD %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: add_scalar_eq_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_scalar_eq_commuted_in_op
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %y, %x
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: add_vector_eq_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_vector_eq_commuted_in_op
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_ADD %y, %x
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: add_scalar_eq_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_scalar_eq_commuted_in_cmp
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %x(s32), %op
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: add_vector_eq_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_vector_eq_commuted_in_cmp
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_ADD %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %x(<4 x s32>), %op
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: xor_scalar_eq
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: xor_scalar_eq
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_XOR %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: xor_vector_eq
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: xor_vector_eq
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_XOR %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: xor_scalar_eq_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: xor_scalar_eq_commuted_in_op
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_XOR %y, %x
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: xor_vector_eq_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: xor_vector_eq_commuted_in_op
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_XOR %y, %x
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: xor_scalar_eq_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: xor_scalar_eq_commuted_in_cmp
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_XOR %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %x(s32), %op
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: xor_vector_eq_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: xor_vector_eq_commuted_in_cmp
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_XOR %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %x(<4 x s32>), %op
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: sub_scalar_eq
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: sub_scalar_eq
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_SUB %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: sub_vector_eq
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: sub_vector_eq
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_SUB %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: sub_scalar_eq_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: sub_scalar_eq_commuted_in_cmp
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_SUB %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %x(s32), %op
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: sub_vector_eq_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: sub_vector_eq_commuted_in_cmp
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_SUB %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %x(<4 x s32>), %op
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: add_scalar_ne
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_scalar_ne
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %x, %y
+ %cmp:_(s1) = G_ICMP intpred(ne), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: add_vector_ne
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_vector_ne
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_ADD %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: add_scalar_ne_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_scalar_ne_commuted_in_op
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %y, %x
+ %cmp:_(s1) = G_ICMP intpred(ne), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: add_vector_ne_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_vector_ne_commuted_in_op
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_ADD %y, %x
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: add_scalar_ne_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: add_scalar_ne_commuted_in_cmp
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %x, %y
+ %cmp:_(s1) = G_ICMP intpred(ne), %x(s32), %op
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: add_vector_ne_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: add_vector_ne_commuted_in_cmp
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_ADD %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %x(<4 x s32>), %op
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: xor_scalar_ne
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: xor_scalar_ne
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_XOR %x, %y
+ %cmp:_(s1) = G_ICMP intpred(ne), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: xor_vector_ne
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: xor_vector_ne
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_XOR %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: xor_scalar_ne_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: xor_scalar_ne_commuted_in_op
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_XOR %y, %x
+ %cmp:_(s1) = G_ICMP intpred(ne), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: xor_vector_ne_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: xor_vector_ne_commuted_in_op
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_XOR %y, %x
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: xor_scalar_ne_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: xor_scalar_ne_commuted_in_cmp
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_XOR %x, %y
+ %cmp:_(s1) = G_ICMP intpred(ne), %x(s32), %op
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: xor_vector_ne_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: xor_vector_ne_commuted_in_cmp
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_XOR %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %x(<4 x s32>), %op
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: sub_scalar_ne
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: sub_scalar_ne
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_SUB %x, %y
+ %cmp:_(s1) = G_ICMP intpred(ne), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: sub_vector_ne
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: sub_vector_ne
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_SUB %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: sub_scalar_ne_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: sub_scalar_ne_commuted_in_cmp
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(ne), %y(s32), [[C]]
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_SUB %x, %y
+ %cmp:_(s1) = G_ICMP intpred(ne), %x(s32), %op
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: sub_vector_ne_commuted_in_cmp
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: sub_vector_ne_commuted_in_cmp
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %y(<4 x s32>), [[BUILD_VECTOR]]
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_SUB %x, %y
+ %cmp:_(<4 x s1>) = G_ICMP intpred(ne), %x(<4 x s32>), %op
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: dont_combine_sub_scalar_eq_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: dont_combine_sub_scalar_eq_commuted_in_op
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $w0
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: %op:_(s32) = G_SUB %y, %x
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_SUB %y, %x
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: dont_combine_sub_vector_eq_commuted_in_op
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: dont_combine_sub_vector_eq_commuted_in_op
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(<4 x s32>) = COPY $q0
+ ; CHECK-NEXT: %y:_(<4 x s32>) = COPY $q1
+ ; CHECK-NEXT: %op:_(<4 x s32>) = G_SUB %y, %x
+ ; CHECK-NEXT: %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ ; CHECK-NEXT: %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ ; CHECK-NEXT: $d0 = COPY %ext(<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %x:_(<4 x s32>) = COPY $q0
+ %y:_(<4 x s32>) = COPY $q1
+ %op:_(<4 x s32>) = G_SUB %y, %x
+ %cmp:_(<4 x s1>) = G_ICMP intpred(eq), %op(<4 x s32>), %x
+ %ext:_(<4 x s16>) = G_ANYEXT %cmp(<4 x s1>)
+ $d0 = COPY %ext(<4 x s16>)
+ RET_ReallyLR implicit $d0
+...
+---
+name: dont_combine_not_equality
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: dont_combine_not_equality
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $w0
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: %op:_(s32) = G_ADD %x, %y
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(slt), %op(s32), %x
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %op:_(s32) = G_ADD %x, %y
+ %cmp:_(s1) = G_ICMP intpred(slt), %op(s32), %x
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
+...
+---
+name: dont_combine_unique_operands
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $w0, $w1, $w2
+ ; CHECK-LABEL: name: dont_combine_unique_operands
+ ; CHECK: liveins: $w0, $w1, $w2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $w0
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: %z:_(s32) = COPY $w2
+ ; CHECK-NEXT: %op:_(s32) = G_ADD %x, %y
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %z
+ ; CHECK-NEXT: %ext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %z:_(s32) = COPY $w2
+ %op:_(s32) = G_ADD %x, %y
+ %cmp:_(s1) = G_ICMP intpred(eq), %op(s32), %z
+ %ext:_(s32) = G_ZEXT %cmp(s1)
+ $w0 = COPY %ext(s32)
+ RET_ReallyLR implicit $w0
More information about the llvm-commits
mailing list