Skip to content

Commit 0e97b4d

Browse files
author
Thorsten Schütt
authored
[GlobalISel] Combine G_MERGE_VALUES of x and undef (#113616)
into anyext x ; CHECK-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[TRUNC]](s32), [[DEF]](s32) Please continue padding merge values. // %bits_8_15:_(s8) = G_IMPLICIT_DEF // %0:_(s16) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8) %bits_8_15 is defined by undef. Its value is undefined and we can pick an arbitrary value. For optimization, we pick anyext, which plays well with the undefinedness. // %0:_(s16) = G_ANYEXT %bits_0_7:(s8) The upper bits of %0 are undefined and the lower bits come from %bits_0_7.
1 parent 9d85ba5 commit 0e97b4d

File tree

6 files changed

+112
-14
lines changed

6 files changed

+112
-14
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,9 @@ class CombinerHelper {
929929
bool matchUnmergeValuesAnyExtBuildVector(const MachineInstr &MI,
930930
BuildFnTy &MatchInfo);
931931

932+
// merge_values(_, undef) -> anyext
933+
bool matchMergeXAndUndef(const MachineInstr &MI, BuildFnTy &MatchInfo);
934+
932935
private:
933936
/// Checks for legality of an indexed variant of \p LdSt.
934937
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
@@ -857,14 +857,23 @@ def unmerge_zext_to_zext : GICombineRule<
857857
(apply [{ Helper.applyCombineUnmergeZExtToZExt(*${d}); }])
858858
>;
859859

860+
/// Transform merge_x_undef -> anyext.
861+
def merge_of_x_and_undef : GICombineRule <
862+
(defs root:$root, build_fn_matchinfo:$matchinfo),
863+
(match (G_IMPLICIT_DEF $undef),
864+
(G_MERGE_VALUES $root, $x, $undef):$MI,
865+
[{ return Helper.matchMergeXAndUndef(*${MI}, ${matchinfo}); }]),
866+
(apply [{ Helper.applyBuildFn(*${MI}, ${matchinfo}); }])>;
867+
860868
def merge_combines: GICombineGroup<[
861869
unmerge_anyext_build_vector,
862870
unmerge_merge,
863871
merge_unmerge,
864872
unmerge_cst,
865873
unmerge_undef,
866874
unmerge_dead_to_trunc,
867-
unmerge_zext_to_zext
875+
unmerge_zext_to_zext,
876+
merge_of_x_and_undef
868877
]>;
869878

870879
// Under certain conditions, transform:

llvm/lib/CodeGen/GlobalISel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMGlobalISel
66
GlobalISel.cpp
77
Combiner.cpp
88
CombinerHelper.cpp
9+
CombinerHelperArtifacts.cpp
910
CombinerHelperCasts.cpp
1011
CombinerHelperCompares.cpp
1112
CombinerHelperVectorOps.cpp
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===- CombinerHelperArtifacts.cpp-----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements CombinerHelper for legalization artifacts.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// G_MERGE_VALUES
14+
//
15+
//===----------------------------------------------------------------------===//
16+
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
17+
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
18+
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
19+
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
20+
#include "llvm/CodeGen/GlobalISel/Utils.h"
21+
#include "llvm/CodeGen/LowLevelTypeUtils.h"
22+
#include "llvm/CodeGen/MachineOperand.h"
23+
#include "llvm/CodeGen/MachineRegisterInfo.h"
24+
#include "llvm/CodeGen/TargetOpcodes.h"
25+
#include "llvm/Support/Casting.h"
26+
27+
#define DEBUG_TYPE "gi-combiner"
28+
29+
using namespace llvm;
30+
31+
bool CombinerHelper::matchMergeXAndUndef(const MachineInstr &MI,
32+
BuildFnTy &MatchInfo) {
33+
const GMerge *Merge = cast<GMerge>(&MI);
34+
35+
Register Dst = Merge->getReg(0);
36+
LLT DstTy = MRI.getType(Dst);
37+
LLT SrcTy = MRI.getType(Merge->getSourceReg(0));
38+
39+
// Otherwise, we would miscompile.
40+
assert(Merge->getNumSources() == 2 && "Unexpected number of operands");
41+
42+
//
43+
// %bits_8_15:_(s8) = G_IMPLICIT_DEF
44+
// %0:_(s16) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8)
45+
//
46+
// ->
47+
//
48+
// %0:_(s16) = G_ANYEXT %bits_0_7:(s8)
49+
//
50+
51+
if (!isLegalOrBeforeLegalizer({TargetOpcode::G_ANYEXT, {DstTy, SrcTy}}))
52+
return false;
53+
54+
MatchInfo = [=](MachineIRBuilder &B) {
55+
B.buildAnyExt(Dst, Merge->getSourceReg(0));
56+
};
57+
return true;
58+
}

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

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ body: |
1010
bb.1:
1111
; CHECK-LABEL: name: test_combine_unmerge_merge
1212
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
13-
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1413
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
15-
; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
14+
; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
1615
%0:_(s32) = G_IMPLICIT_DEF
1716
%1:_(s32) = G_IMPLICIT_DEF
1817
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
@@ -115,9 +114,8 @@ body: |
115114
bb.1:
116115
; CHECK-LABEL: name: test_combine_unmerge_bitcast_merge
117116
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
118-
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
119117
; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
120-
; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
118+
; CHECK-NEXT: $w1 = COPY [[DEF]](s32)
121119
%0:_(s32) = G_IMPLICIT_DEF
122120
%1:_(s32) = G_IMPLICIT_DEF
123121
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
@@ -135,14 +133,11 @@ name: test_combine_unmerge_merge_incompatible_types
135133
body: |
136134
bb.1:
137135
; CHECK-LABEL: name: test_combine_unmerge_merge_incompatible_types
138-
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
139-
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
140-
; CHECK-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]](s32), [[DEF1]](s32)
141-
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[MV]](s64)
142-
; CHECK-NEXT: $h0 = COPY [[UV]](s16)
143-
; CHECK-NEXT: $h1 = COPY [[UV1]](s16)
144-
; CHECK-NEXT: $h2 = COPY [[UV2]](s16)
145-
; CHECK-NEXT: $h3 = COPY [[UV3]](s16)
136+
; CHECK: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
137+
; CHECK-NEXT: $h0 = COPY [[DEF]](s16)
138+
; CHECK-NEXT: $h1 = COPY [[DEF]](s16)
139+
; CHECK-NEXT: $h2 = COPY [[DEF]](s16)
140+
; CHECK-NEXT: $h3 = COPY [[DEF]](s16)
146141
%0:_(s32) = G_IMPLICIT_DEF
147142
%1:_(s32) = G_IMPLICIT_DEF
148143
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
@@ -539,3 +534,36 @@ body: |
539534
$q0 = COPY %un1(s128)
540535
$q1 = COPY %un2(s128)
541536
...
537+
538+
# Check that we anyext the merge
539+
---
540+
name: test_merge_undef
541+
body: |
542+
bb.1:
543+
; CHECK-LABEL: name: test_merge_undef
544+
; CHECK: %opaque:_(s64) = COPY $x0
545+
; CHECK-NEXT: %me:_(s128) = G_ANYEXT %opaque(s64)
546+
; CHECK-NEXT: $q0 = COPY %me(s128)
547+
%opaque:_(s64) = COPY $x0
548+
%def:_(s64) = G_IMPLICIT_DEF
549+
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
550+
$q0 = COPY %me(s128)
551+
...
552+
553+
# Check that we don't anyext the merge, multi-use
554+
---
555+
name: test_merge_undef_multi_use
556+
body: |
557+
bb.1:
558+
; CHECK-LABEL: name: test_merge_undef_multi_use
559+
; CHECK: %opaque:_(s64) = COPY $x0
560+
; CHECK-NEXT: %def:_(s64) = G_IMPLICIT_DEF
561+
; CHECK-NEXT: %me:_(s128) = G_ANYEXT %opaque(s64)
562+
; CHECK-NEXT: $q0 = COPY %me(s128)
563+
; CHECK-NEXT: $x0 = COPY %def(s64)
564+
%opaque:_(s64) = COPY $x0
565+
%def:_(s64) = G_IMPLICIT_DEF
566+
%me:_(s128) = G_MERGE_VALUES %opaque(s64), %def
567+
$q0 = COPY %me(s128)
568+
$x0 = COPY %def(s64)
569+
...

llvm/test/CodeGen/AArch64/bswap.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ define i128 @bswap_i16_to_i128_anyext(i16 %a) {
6060
; CHECK-GI-NEXT: mov x0, xzr
6161
; CHECK-GI-NEXT: rev w8, w8
6262
; CHECK-GI-NEXT: lsr w8, w8, #16
63-
; CHECK-GI-NEXT: bfi x8, x8, #32, #32
6463
; CHECK-GI-NEXT: and x8, x8, #0xffff
6564
; CHECK-GI-NEXT: lsl x1, x8, #48
6665
; CHECK-GI-NEXT: ret

0 commit comments

Comments
 (0)