Skip to content

Commit 2906fca

Browse files
author
Thorsten Schütt
authored
[GlobalISel] Combine G_MERGE_VALUES of x and zero (#116283)
into zext x LegalizerHelper has two padding strategies: undef or zero. see LegalizerHelper:273 see LegalizerHelper:315 This PR is about zero sugar and Coke Zero. ; CHECK-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES %a(s32), [[C]](s32) Please continue padding merge values. // %bits_8_15:(s8) = G_CONSTANT i8 0 // %0:(s16) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8) %bits_8_15 is defined by zero. For optimization, we pick zext. // %0:_(s16) = G_ZEXT %bits_0_7:(s8) The upper bits of %0 are zero and the lower bits come from %bits_0_7.
1 parent ec0a27f commit 2906fca

File tree

12 files changed

+421
-401
lines changed

12 files changed

+421
-401
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,9 @@ class CombinerHelper {
936936
// merge_values(_, undef) -> anyext
937937
bool matchMergeXAndUndef(const MachineInstr &MI, BuildFnTy &MatchInfo);
938938

939+
// merge_values(_, zero) -> zext
940+
bool matchMergeXAndZero(const MachineInstr &MI, BuildFnTy &MatchInfo);
941+
939942
private:
940943
/// Checks for legality of an indexed variant of \p LdSt.
941944
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,14 @@ def merge_of_x_and_undef : GICombineRule <
865865
[{ return Helper.matchMergeXAndUndef(*${MI}, ${matchinfo}); }]),
866866
(apply [{ Helper.applyBuildFn(*${MI}, ${matchinfo}); }])>;
867867

868+
/// Transform merge_x_zero -> zext.
869+
def merge_of_x_and_zero : GICombineRule <
870+
(defs root:$root, build_fn_matchinfo:$matchinfo),
871+
(match (G_CONSTANT $zero, 0),
872+
(G_MERGE_VALUES $root, $x, $zero):$MI,
873+
[{ return Helper.matchMergeXAndZero(*${MI}, ${matchinfo}); }]),
874+
(apply [{ Helper.applyBuildFn(*${MI}, ${matchinfo}); }])>;
875+
868876
def merge_combines: GICombineGroup<[
869877
unmerge_anyext_build_vector,
870878
unmerge_merge,
@@ -873,7 +881,8 @@ def merge_combines: GICombineGroup<[
873881
unmerge_undef,
874882
unmerge_dead_to_trunc,
875883
unmerge_zext_to_zext,
876-
merge_of_x_and_undef
884+
merge_of_x_and_undef,
885+
merge_of_x_and_zero
877886
]>;
878887

879888
// Under certain conditions, transform:

llvm/lib/CodeGen/GlobalISel/CombinerHelperArtifacts.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,31 @@ bool CombinerHelper::matchMergeXAndUndef(const MachineInstr &MI,
5656
};
5757
return true;
5858
}
59+
60+
bool CombinerHelper::matchMergeXAndZero(const MachineInstr &MI,
61+
BuildFnTy &MatchInfo) {
62+
const GMerge *Merge = cast<GMerge>(&MI);
63+
64+
Register Dst = Merge->getReg(0);
65+
LLT DstTy = MRI.getType(Dst);
66+
LLT SrcTy = MRI.getType(Merge->getSourceReg(0));
67+
68+
// No multi-use check. It is a constant.
69+
70+
//
71+
// %bits_8_15:_(s8) = G_CONSTANT i8 0
72+
// %0:_(s16) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8)
73+
//
74+
// ->
75+
//
76+
// %0:_(s16) = G_ZEXT %bits_0_7:(s8)
77+
//
78+
79+
if (!isLegalOrBeforeLegalizer({TargetOpcode::G_ZEXT, {DstTy, SrcTy}}))
80+
return false;
81+
82+
MatchInfo = [=](MachineIRBuilder &B) {
83+
B.buildZExt(Dst, Merge->getSourceReg(0));
84+
};
85+
return true;
86+
}

llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,3 +567,49 @@ body: |
567567
$q0 = COPY %me(s128)
568568
$x0 = COPY %def(s64)
569569
...
570+
# Check that we zext the merge
571+
---
572+
name: test_merge_zero
573+
body: |
574+
bb.1:
575+
; CHECK-LABEL: name: test_merge_zero
576+
; CHECK: %opaque:_(s64) = COPY $x0
577+
; CHECK-NEXT: %me:_(s128) = G_ZEXT %opaque(s64)
578+
; CHECK-NEXT: $q0 = COPY %me(s128)
579+
%opaque:_(s64) = COPY $x0
580+
%def:_(s64) = G_CONSTANT i64 0
581+
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
582+
$q0 = COPY %me(s128)
583+
...
584+
# Check that we still zext the merge, multi-use
585+
---
586+
name: test_merge_zero_multi_use
587+
body: |
588+
bb.1:
589+
; CHECK-LABEL: name: test_merge_zero_multi_use
590+
; CHECK: %opaque:_(s64) = COPY $x0
591+
; CHECK-NEXT: %def:_(s64) = G_CONSTANT i64 0
592+
; CHECK-NEXT: %me:_(s128) = G_ZEXT %opaque(s64)
593+
; CHECK-NEXT: $q0 = COPY %me(s128)
594+
; CHECK-NEXT: $x0 = COPY %def(s64)
595+
%opaque:_(s64) = COPY $x0
596+
%def:_(s64) = G_CONSTANT i64 0
597+
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
598+
$q0 = COPY %me(s128)
599+
$x0 = COPY %def(s64)
600+
...
601+
# Check that we don't zext the merge with one
602+
---
603+
name: test_merge_one
604+
body: |
605+
bb.1:
606+
; CHECK-LABEL: name: test_merge_one
607+
; CHECK: %opaque:_(s64) = COPY $x0
608+
; CHECK-NEXT: %def:_(s64) = G_CONSTANT i64 1
609+
; CHECK-NEXT: %me:_(s128) = G_MERGE_VALUES %opaque(s64), %def(s64)
610+
; CHECK-NEXT: $q0 = COPY %me(s128)
611+
%opaque:_(s64) = COPY $x0
612+
%def:_(s64) = G_CONSTANT i64 1
613+
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
614+
$q0 = COPY %me(s128)
615+
...

0 commit comments

Comments
 (0)