Skip to content

Commit 0864501

Browse files
dtcxzywThorsten Schütt
andauthored
[GISel] Convert zext nneg to sext if it is cheaper (#93856)
This patch converts `zext nneg` to `sext` on RISCV to use free sext. --------- Co-authored-by: Thorsten Schütt <[email protected]>
1 parent bfa8b64 commit 0864501

File tree

5 files changed

+64
-1
lines changed

5 files changed

+64
-1
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,9 @@ class CombinerHelper {
816816
/// Combine zext of trunc.
817817
bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo);
818818

819+
/// Combine zext nneg to sext.
820+
bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo);
821+
819822
/// Match constant LHS FP ops that should be commuted.
820823
bool matchCommuteFPConstantToRHS(MachineInstr &MI);
821824

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ def FmReassoc : MIFlagEnum<"FmReassoc">;
182182
def IsExact : MIFlagEnum<"IsExact">;
183183
def NoSWrap : MIFlagEnum<"NoSWrap">;
184184
def NoUWrap : MIFlagEnum<"NoUWrap">;
185+
def NonNeg : MIFlagEnum<"NonNeg">;
185186

186187
def MIFlags;
187188
// def not; -> Already defined as a SDNode
@@ -1546,6 +1547,12 @@ def zext_trunc : GICombineRule<
15461547
[{ return Helper.matchZextOfTrunc(${root}, ${matchinfo}); }]),
15471548
(apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
15481549

1550+
def nneg_zext : GICombineRule<
1551+
(defs root:$root, build_fn_matchinfo:$matchinfo),
1552+
(match (G_ZEXT $root, $x, (MIFlags NonNeg)),
1553+
[{ return Helper.matchNonNegZext(${root}, ${matchinfo}); }]),
1554+
(apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
1555+
15491556
def extract_vector_element_shuffle_vector : GICombineRule<
15501557
(defs root:$root, build_fn_matchinfo:$matchinfo),
15511558
(match (G_SHUFFLE_VECTOR $src, $src1, $src2, $mask),
@@ -1773,6 +1780,8 @@ def fma_combines : GICombineGroup<[combine_fadd_fmul_to_fmad_or_fma,
17731780
def constant_fold_binops : GICombineGroup<[constant_fold_binop,
17741781
constant_fold_fp_binop]>;
17751782

1783+
def prefer_sign_combines : GICombineGroup<[nneg_zext]>;
1784+
17761785
def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
17771786
vector_ops_combines, freeze_combines,
17781787
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
@@ -1796,7 +1805,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
17961805
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
17971806
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
17981807
combine_concat_vector, double_icmp_zero_and_or_combine, match_addos,
1799-
sext_trunc, zext_trunc, combine_shuffle_concat]>;
1808+
sext_trunc, zext_trunc, prefer_sign_combines, combine_shuffle_concat]>;
18001809

18011810
// A combine group used to for prelegalizer combiners at -O0. The combines in
18021811
// this group have been selected based on experiments to balance code size and

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7407,3 +7407,24 @@ bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO,
74077407

74087408
return false;
74097409
}
7410+
7411+
bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
7412+
BuildFnTy &MatchInfo) {
7413+
GZext *Zext = cast<GZext>(MRI.getVRegDef(MO.getReg()));
7414+
7415+
Register Dst = Zext->getReg(0);
7416+
Register Src = Zext->getSrcReg();
7417+
7418+
LLT DstTy = MRI.getType(Dst);
7419+
LLT SrcTy = MRI.getType(Src);
7420+
const auto &TLI = getTargetLowering();
7421+
7422+
// Convert zext nneg to sext if sext is the preferred form for the target.
7423+
if (isLegalOrBeforeLegalizer({TargetOpcode::G_SEXT, {DstTy, SrcTy}}) &&
7424+
TLI.isSExtCheaperThanZExt(getMVTForLLT(SrcTy), getMVTForLLT(DstTy))) {
7425+
MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); };
7426+
return true;
7427+
}
7428+
7429+
return false;
7430+
}

llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,13 @@ entry:
101101
%0 = urem i64 %a, %b
102102
ret i64 %0
103103
}
104+
105+
define i64 @zext_nneg_i32_i64(i32 %a) {
106+
; RV64IM-LABEL: zext_nneg_i32_i64:
107+
; RV64IM: # %bb.0: # %entry
108+
; RV64IM-NEXT: sext.w a0, a0
109+
; RV64IM-NEXT: ret
110+
entry:
111+
%b = zext nneg i32 %a to i64
112+
ret i64 %b
113+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -run-pass=riscv-prelegalizer-combiner -mtriple riscv64 %s -o - | FileCheck %s --check-prefix=RV64
3+
4+
---
5+
name: nneg_zext
6+
body: |
7+
bb.0:
8+
9+
; RV64-LABEL: name: nneg_zext
10+
; RV64: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
11+
; RV64-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
12+
; RV64-NEXT: [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[TRUNC]](s32)
13+
; RV64-NEXT: $x10 = COPY [[SEXT]](s64)
14+
; RV64-NEXT: PseudoRET implicit $x10
15+
%0:_(s64) = COPY $x10
16+
%2:_(s32) = G_TRUNC %0
17+
%3:_(s64) = nneg G_ZEXT %2
18+
$x10 = COPY %3(s64)
19+
PseudoRET implicit $x10
20+
...

0 commit comments

Comments
 (0)