[llvm] [GlobalISel] Combine G_UNMERGE_VALUES with anyext and build vector (PR #112370)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 15 07:47:09 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
@llvm/pr-subscribers-backend-amdgpu
Author: Thorsten Schütt (tschuett)
<details>
<summary>Changes</summary>
G_UNMERGE_VALUES (G_ANYEXT (G_BUILD_VECTOR))
ag G_UNMERGE_VALUES llvm/test/CodeGen/AArch64/GlobalISel | grep ANYEXT [ANYEXT] is build vector or shuffle vector
Prior art:
https://reviews.llvm.org/D87117
https://reviews.llvm.org/D87166
https://reviews.llvm.org/D87174
https://reviews.llvm.org/D87427
; CHECK-NEXT: [[BUILD_VECTOR2:%[0-9]+]]:_(<8 x s8>) = G_BUILD_VECTOR
[[C2]](s8), [[C2]](s8), [[C2]](s8), [[C2]](s8), [[DEF1]](s8), [[DEF1]](s8), [[DEF1]](s8), [[DEF1]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(<8 x s16>) = G_ANYEXT [[BUILD_VECTOR2]](<8 x s8>)
; CHECK-NEXT: [[UV10:%[0-9]+]]:_(<4 x s16>), [[UV11:%[0-9]+]]:_(<4 x s16>) = G_UNMERGE_VALUES
[[ANYEXT1]](<8 x s16>)
Test:
llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir
---
Patch is 128.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/112370.diff
33 Files Affected:
- (modified) llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h (+4)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h (+8)
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+22-7)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+63)
- (modified) llvm/lib/Target/AArch64/AArch64Combine.td (+2-2)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir (+25-18)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-shifts-undef.mir (+6-9)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir (+8-17)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir (+111-6)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector-widen-crash.ll (+10-9)
- (modified) llvm/test/CodeGen/AArch64/add.ll (+23-23)
- (modified) llvm/test/CodeGen/AArch64/andorxor.ll (+69-69)
- (modified) llvm/test/CodeGen/AArch64/arm64-extract-insert-varidx.ll (+19-15)
- (modified) llvm/test/CodeGen/AArch64/bitcast.ll (+23-18)
- (modified) llvm/test/CodeGen/AArch64/concat-vector.ll (+3-4)
- (modified) llvm/test/CodeGen/AArch64/fptoi.ll (+4-6)
- (modified) llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll (+23-28)
- (modified) llvm/test/CodeGen/AArch64/fptosi-sat-vector.ll (+191-247)
- (modified) llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll (+22-27)
- (modified) llvm/test/CodeGen/AArch64/fptoui-sat-vector.ll (+155-208)
- (modified) llvm/test/CodeGen/AArch64/load.ll (+3-4)
- (modified) llvm/test/CodeGen/AArch64/mul.ll (+23-23)
- (modified) llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll (+14-22)
- (modified) llvm/test/CodeGen/AArch64/neon-compare-instructions.ll (+7-16)
- (modified) llvm/test/CodeGen/AArch64/setcc_knownbits.ll (+6-12)
- (modified) llvm/test/CodeGen/AArch64/sext.ll (+41-49)
- (modified) llvm/test/CodeGen/AArch64/shift-logic.ll (+2-1)
- (modified) llvm/test/CodeGen/AArch64/sub.ll (+23-23)
- (modified) llvm/test/CodeGen/AArch64/xtn.ll (+2-3)
- (modified) llvm/test/CodeGen/AArch64/zext.ll (+36-44)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-trunc-shift.mir (+12-9)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/sext_inreg.ll (+19)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/shl.ll (+34-8)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 76d51ab819f441..ecca7396b90196 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -918,6 +918,10 @@ class CombinerHelper {
bool matchCanonicalizeICmp(const MachineInstr &MI, BuildFnTy &MatchInfo);
bool matchCanonicalizeFCmp(const MachineInstr &MI, BuildFnTy &MatchInfo);
+ // unmerge_values anyext build vector
+ bool matchUnmergeValuesAnyExtBuildVector(const MachineInstr &MI,
+ BuildFnTy &MatchInfo);
+
private:
/// Checks for legality of an indexed variant of \p LdSt.
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index d9f3f4ab3935d3..92d37753791c6e 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -868,6 +868,14 @@ class GZext : public GCastOp {
};
};
+/// Represents an any ext.
+class GAnyExt : public GCastOp {
+public:
+ static bool classof(const MachineInstr *MI) {
+ return MI->getOpcode() == TargetOpcode::G_ANYEXT;
+ };
+};
+
/// Represents a trunc.
class GTrunc : public GCastOp {
public:
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 77cb4370b54664..a5559116d60837 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -420,7 +420,7 @@ def unary_undef_to_zero: GICombineRule<
// 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, G_TRUNC, G_BITCAST):$root,
+ (match (wip_match_opcode G_ADD, G_FPTOSI, G_FPTOUI, G_SUB, G_XOR, G_TRUNC, G_BITCAST, G_ANYEXT):$root,
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
@@ -428,7 +428,7 @@ def propagate_undef_any_op: GICombineRule<
// replaced with undef.
def propagate_undef_all_ops: GICombineRule<
(defs root:$root),
- (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+ (match (wip_match_opcode G_SHUFFLE_VECTOR, G_BUILD_VECTOR):$root,
[{ return Helper.matchAllExplicitUsesAreUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
@@ -832,6 +832,14 @@ def unmerge_dead_to_trunc : GICombineRule<
(apply [{ Helper.applyCombineUnmergeWithDeadLanesToTrunc(*${d}); }])
>;
+// Transform unmerge any build vector -> build vector anyext
+def unmerge_anyext_build_vector : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_UNMERGE_VALUES): $root,
+ [{ return Helper.matchUnmergeValuesAnyExtBuildVector(*${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])
+>;
+
// Transform x,y = unmerge(zext(z)) -> x = zext z; y = 0.
def unmerge_zext_to_zext : GICombineRule<
(defs root:$d),
@@ -840,6 +848,16 @@ def unmerge_zext_to_zext : GICombineRule<
(apply [{ Helper.applyCombineUnmergeZExtToZExt(*${d}); }])
>;
+def merge_combines: GICombineGroup<[
+ unmerge_anyext_build_vector,
+ unmerge_merge,
+ merge_unmerge,
+ unmerge_cst,
+ unmerge_undef,
+ unmerge_dead_to_trunc,
+ unmerge_zext_to_zext
+]>;
+
// Under certain conditions, transform:
// trunc (shl x, K) -> shl (trunc x), K//
// trunc ([al]shr x, K) -> (trunc ([al]shr (trunc x), K))
@@ -1847,7 +1865,6 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
propagate_undef_all_ops,
propagate_undef_shuffle_mask,
erase_undef_store,
- unmerge_undef,
insert_extract_vec_elt_out_of_bounds]>;
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
@@ -1907,8 +1924,6 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
width_reduction_combines, select_combines,
known_bits_simplifications,
not_cmp_fold, opt_brcond_by_inverting_cond,
- unmerge_merge, unmerge_cst, unmerge_dead_to_trunc,
- unmerge_zext_to_zext, merge_unmerge, trunc_shift,
const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine,
div_rem_to_divrem, funnel_shift_combines, bitreverse_shift, commute_shift,
@@ -1916,11 +1931,11 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
constant_fold_cast_op, 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,
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
combine_concat_vector, match_addos,
sext_trunc, zext_trunc, prefer_sign_combines, combine_shuffle_concat,
- combine_use_vector_truncate]>;
+ combine_use_vector_truncate, merge_combines]>;
// 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 14e94d48bf8362..bb37199d77f34f 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7611,3 +7611,66 @@ bool CombinerHelper::matchFoldAMinusC1PlusC2(const MachineInstr &MI,
return true;
}
+
+bool CombinerHelper::matchUnmergeValuesAnyExtBuildVector(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ const GUnmerge *Unmerge = cast<GUnmerge>(&MI);
+
+ if (!MRI.hasOneNonDBGUse(Unmerge->getSourceReg()))
+ return false;
+
+ const MachineInstr *Source = MRI.getVRegDef(Unmerge->getSourceReg());
+
+ LLT DstTy = MRI.getType(Unmerge->getReg(0));
+
+ // We want to unmerge into vectors.
+ if (!DstTy.isFixedVector())
+ return false;
+
+ if (const GAnyExt *Any = dyn_cast<GAnyExt>(Source)) {
+ const MachineInstr *NextSource = MRI.getVRegDef(Any->getSrcReg());
+
+ if (const GBuildVector *BV = dyn_cast<GBuildVector>(NextSource)) {
+ // G_UNMERGE_VALUES G_ANYEXT G_BUILD_VECTOR
+
+ if (!MRI.hasOneNonDBGUse(BV->getReg(0)))
+ return false;
+
+ // FIXME: check element types?
+ if (BV->getNumSources() % Unmerge->getNumDefs() != 0)
+ return false;
+
+ LLT BigBvTy = MRI.getType(BV->getReg(0));
+ LLT SmallBvTy = DstTy;
+ LLT SmallBvElemenTy = SmallBvTy.getElementType();
+
+ if (!isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_BUILD_VECTOR, {SmallBvTy, SmallBvElemenTy}}))
+ return false;
+
+ // check scalar anyext
+ if (!isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_ANYEXT,
+ {SmallBvElemenTy, BigBvTy.getElementType()}}))
+ return false;
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ // build into each G_UNMERGE_VALUES def
+ // a small build vector with anyext from the source build vector
+ for (unsigned I = 0; I < Unmerge->getNumDefs(); ++I) {
+ SmallVector<Register> Ops;
+ for (unsigned J = 0; J < SmallBvTy.getNumElements(); ++J) {
+ auto AnyExt = B.buildAnyExt(
+ SmallBvElemenTy,
+ BV->getSourceReg(I * SmallBvTy.getNumElements() + J));
+ Ops.push_back(AnyExt.getReg(0));
+ }
+ B.buildBuildVector(Unmerge->getOperand(I).getReg(), Ops);
+ };
+ };
+ return true;
+ };
+ };
+
+ return false;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index ead6455ddd5278..029724050a0045 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -322,13 +322,13 @@ def AArch64PostLegalizerCombiner
extractvecelt_pairwise_add, redundant_or,
mul_const, redundant_sext_inreg,
form_bitfield_extract, rotate_out_of_range,
- icmp_to_true_false_known_bits, merge_unmerge,
+ icmp_to_true_false_known_bits,
select_combines, fold_merge_to_zext,
constant_fold_binops, identity_combines,
ptr_add_immed_chain, overlapping_and,
split_store_zero_128, undef_combines,
select_to_minmax, or_to_bsp, combine_concat_vector,
- commute_constant_to_rhs,
+ commute_constant_to_rhs, merge_combines,
push_freeze_to_prevent_poison_from_propagating,
combine_mul_cmlt, combine_use_vector_truncate]> {
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir
index 96a6f18b1d4108..0f6dd23b5bb5ea 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir
@@ -9,24 +9,31 @@ liveins:
body: |
; CHECK-LABEL: name: shift_immed_chain_mismatch_size_crash
; CHECK: bb.0:
- ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
- ; CHECK: liveins: $x0
- ; CHECK: [[DEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
- ; CHECK: [[DEF1:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
- ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 9
- ; CHECK: G_BRCOND [[DEF]](s1), %bb.2
- ; CHECK: G_BR %bb.1
- ; CHECK: bb.1:
- ; CHECK: successors:
- ; CHECK: bb.2:
- ; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[DEF1]](p0) :: (load (s32) from `ptr undef`, align 8)
- ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; CHECK: [[SHL:%[0-9]+]]:_(s32) = nsw G_SHL [[LOAD]], [[C1]](s32)
- ; CHECK: [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[SHL]], [[C]]
- ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; CHECK: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[MUL]], [[C2]](s64)
- ; CHECK: $w0 = COPY [[SHL1]](s32)
- ; CHECK: RET_ReallyLR implicit $w0
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 9
+ ; CHECK-NEXT: G_BRCOND [[DEF]](s1), %bb.2
+ ; CHECK-NEXT: G_BR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors:
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[DEF1]](p0) :: (load (s32) from `ptr undef`, align 8)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = nsw G_SHL [[LOAD]], [[C1]](s32)
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[SHL]], [[C]]
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = nsw G_SHL [[MUL]], [[C2]](s32)
+ ; CHECK-NEXT: [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[SHL1]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[SEXT]], [[C3]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[SHL2]](s64)
+ ; CHECK-NEXT: $w0 = COPY [[TRUNC]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
bb.1:
liveins: $x0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shifts-undef.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shifts-undef.mir
index d4dc24741527b6..236d49fc99c629 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shifts-undef.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shifts-undef.mir
@@ -13,9 +13,8 @@ body: |
; CHECK-LABEL: name: shl_by_ge_bw
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[DEF]](s16)
- ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(s32) = COPY $w0
%0:_(s16) = G_TRUNC %1(s32)
@@ -39,9 +38,8 @@ body: |
; CHECK-LABEL: name: lshr_by_ge_bw
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[DEF]](s16)
- ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(s32) = COPY $w0
%0:_(s16) = G_TRUNC %1(s32)
@@ -65,9 +63,8 @@ body: |
; CHECK-LABEL: name: ashr_by_ge_bw
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[DEF]](s16)
- ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(s32) = COPY $w0
%0:_(s16) = G_TRUNC %1(s32)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
index 4a38b5d4c63dd9..74a4e0464dd0dc 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
@@ -181,23 +181,14 @@ legalized: true
body: |
bb.1:
liveins: $w0
- ; CHECK-PRE-LABEL: name: test_combine_trunc_shl_s32_by_2
- ; CHECK-PRE: liveins: $w0
- ; CHECK-PRE-NEXT: {{ $}}
- ; CHECK-PRE-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
- ; CHECK-PRE-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
- ; CHECK-PRE-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
- ; CHECK-PRE-NEXT: [[SHL:%[0-9]+]]:_(s16) = G_SHL [[TRUNC]], [[C]](s32)
- ; CHECK-PRE-NEXT: $h0 = COPY [[SHL]](s16)
- ;
- ; CHECK-POST-LABEL: name: test_combine_trunc_shl_s32_by_2
- ; CHECK-POST: liveins: $w0
- ; CHECK-POST-NEXT: {{ $}}
- ; CHECK-POST-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
- ; CHECK-POST-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
- ; CHECK-POST-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
- ; CHECK-POST-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[SHL]](s32)
- ; CHECK-POST-NEXT: $h0 = COPY [[TRUNC]](s16)
+ ; CHECK-LABEL: name: test_combine_trunc_shl_s32_by_2
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[SHL]](s32)
+ ; CHECK-NEXT: $h0 = COPY [[TRUNC]](s16)
%0:_(s32) = COPY $w0
%1:_(s32) = G_CONSTANT i32 2
%2:_(s32) = G_SHL %0(s32), %1(s32)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir
index c2c6e04d2d0ce5..7566d38e6c6cfa 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir
@@ -54,9 +54,8 @@ body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_build_vector
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
- ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
+ ; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%2:_(<2 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32)
@@ -74,11 +73,9 @@ body: |
bb.1:
; CHECK-LABEL: name: test_combine_unmerge_buildvector_3ops
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
- ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
- ; CHECK-NEXT: $w2 = COPY [[DEF2]](s32)
+ ; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
+ ; CHECK-NEXT: $w2 = COPY [[DEF]](s32)
%0:_(s32) = G_IMPLICIT_DEF
%1:_(s32) = G_IMPLICIT_DEF
%5:_(s32) = G_IMPLICIT_DEF
@@ -434,3 +431,111 @@ body: |
$w0 = COPY %1(s32)
$w1 = COPY %2(s32)
...
+
+# Check that we unmerge the build vector on the anyext
+---
+name: test_anyext_buildvector
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: test_anyext_buildvector
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY]](s32)
+ ; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY1]](s32)
+ ; CHECK-NEXT: %un1:_(<2 x s64>) = G_BUILD_VECTOR [[ANYEXT]](s64), [[ANYEXT1]](s64)
+ ; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY2]](s32)
+ ; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY3]](s32)
+ ; CHECK-NEXT: %un2:_(<2 x s64>) = G_BUILD_VECTOR [[ANYEXT2]](s64), [[ANYEXT3]](s64)
+ ; CHECK-NEXT: $q0 = COPY %un1(<2 x s64>)
+ ; CHECK-NEXT: $q1 = COPY %un2(<2 x s64>)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w0
+ %2:_(s32) = COPY $w0
+ %3:_(s32) = COPY $w0
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
+ %any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
+ %un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
+ $q0 = COPY %un1(<2 x s64>)
+ $q1 = COPY %un2(<2 x s64>)
+...
+
+# Check that we unmerge the build vector on the anyext and undef
+---
+name: test_anyext_buildvector_undef
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: test_anyext_buildvector_undef
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY]](s32)
+ ; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY1]](s32)
+ ; CHECK-NEXT: %un1:_(<2 x s64>) = G_BUILD_VECTOR [[ANYEXT]](s64), [[ANYEXT1]](s64)
+ ; CHECK-NEXT: %un2:_(<2 x s64>) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: $q0 = COPY %un1(<2 x s64>)
+ ; CHECK-NEXT: $q1 = COPY %un2(<2 x s64>)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w0
+ %2:_(s32) = G_IMPLICIT_DEF
+ %3:_(s32) = G_IMPLICIT_DEF
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
+ %any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
+ %un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
+ $q0 = COPY %un1(<2 x s64>)
+ $q1 = COPY %un2(<2 x s64>)
+...
+
+# Check that we don't unmerge the build vector on the anyext, multi-use
+---
+name: test_anyext_buildvector_multi
+body: |
+ bb.1:
+ ; CHECK-LABEL: name: test_anyext_buildvector_multi
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: %bv:_(<4 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY1]](s32), [[DEF]](s32), [[DEF1]](s32)
+ ; CHECK-NEXT: %any:_(<4 x s64>) = G_ANYEXT %bv(<4 x s32>)
+ ; CHECK-NEXT: %un1:_(<2 x s64>), %un2:_(<2 x s64>) = G_UNMERGE_VALUES %any(<4 x s64>)
+ ; CHECK-NEXT: $q0 = COPY %un1(<2 x s64>)
+ ; CHECK-NEXT: $q1 = COPY %un2(<2 x s64>)
+ ; CHECK-NEXT: $q2 = COPY %bv(<4 x s32>)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w0
+ %2:_(s32) = G_IMPLICIT_DEF
+ %3:_(s32) = G_IMPLICIT_DEF
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32)
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/112370
More information about the llvm-commits
mailing list