[llvm] [GISel] Convert zext nneg to sext if it is cheaper (PR #93856)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri May 31 01:21:59 PDT 2024
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/93856
>From e69add4eb4837e276f9ff877253be670d18d6c0a Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 31 May 2024 02:03:05 +0800
Subject: [PATCH 1/4] [RISCV][GISel] Add pre-commit tests. NFC.
---
.../RISCV/GlobalISel/alu-roundtrip-rv64.ll | 11 ++++++++++
.../test/CodeGen/RISCV/GlobalISel/combine.mir | 20 +++++++++++++++++++
2 files changed, 31 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/combine.mir
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
index d4acca17930d5..df3be2ef1f933 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
@@ -101,3 +101,14 @@ entry:
%0 = urem i64 %a, %b
ret i64 %0
}
+
+define i64 @zext_nneg_i32_i64(i32 %a) {
+; RV64IM-LABEL: zext_nneg_i32_i64:
+; RV64IM: # %bb.0: # %entry
+; RV64IM-NEXT: slli a0, a0, 32
+; RV64IM-NEXT: srli a0, a0, 32
+; RV64IM-NEXT: ret
+entry:
+ %b = zext nneg i32 %a to i64
+ ret i64 %b
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir b/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir
new file mode 100644
index 0000000000000..837b11df643a3
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir
@@ -0,0 +1,20 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -run-pass=riscv-prelegalizer-combiner -mtriple riscv64 %s -o - | FileCheck %s --check-prefix=RV64
+
+---
+name: nneg_zext
+body: |
+ bb.0:
+
+ ; RV64-LABEL: name: nneg_zext
+ ; RV64: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV64-NEXT: %2:_(s64) = nneg G_ZEXT [[TRUNC]](s32)
+ ; RV64-NEXT: $x10 = COPY %2(s64)
+ ; RV64-NEXT: PseudoRET implicit $x10
+ %0:_(s64) = COPY $x10
+ %2:_(s32) = G_TRUNC %0
+ %3:_(s64) = nneg G_ZEXT %2
+ $x10 = COPY %3(s64)
+ PseudoRET implicit $x10
+...
>From 4043821e7557585acbedab2b6232a91be60985a0 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 31 May 2024 02:08:16 +0800
Subject: [PATCH 2/4] [GISel] Convert zext nneg to sext if it is cheaper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Thorsten Schütt <schuett at gmail.com>
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 3 +++
.../include/llvm/Target/GlobalISel/Combine.td | 9 ++++++++-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 20 +++++++++++++++++++
.../RISCV/GlobalISel/alu-roundtrip-rv64.ll | 3 +--
.../test/CodeGen/RISCV/GlobalISel/combine.mir | 4 ++--
5 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 2111e82e1a99d..7c1adc7475785 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -816,6 +816,9 @@ class CombinerHelper {
/// Combine zext of trunc.
bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo);
+ /// Combine zext nneg to sext.
+ bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo);
+
/// Match constant LHS FP ops that should be commuted.
bool matchCommuteFPConstantToRHS(MachineInstr &MI);
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 8012f91922777..d4dd2504d6edf 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -182,6 +182,7 @@ def FmReassoc : MIFlagEnum<"FmReassoc">;
def IsExact : MIFlagEnum<"IsExact">;
def NoSWrap : MIFlagEnum<"NoSWrap">;
def NoUWrap : MIFlagEnum<"NoUWrap">;
+def NonNeg : MIFlagEnum<"NonNeg">;
def MIFlags;
// def not; -> Already defined as a SDNode
@@ -1553,6 +1554,12 @@ def zext_trunc : GICombineRule<
[{ return Helper.matchZextOfTrunc(${root}, ${matchinfo}); }]),
(apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+def nneg_zext : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_ZEXT $root, $x, (MIFlags NonNeg)),
+ [{ return Helper.matchNonNegZext(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
def extract_vector_element_shuffle_vector : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (G_SHUFFLE_VECTOR $src, $src1, $src2, $mask),
@@ -1793,7 +1800,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
combine_concat_vector, double_icmp_zero_and_or_combine, match_addos,
- sext_trunc, zext_trunc, combine_shuffle_concat,
+ sext_trunc, zext_trunc, nneg_zext, combine_shuffle_concat,
push_freeze_to_prevent_poison_from_propagating]>;
// A combine group used to for prelegalizer combiners at -O0. The combines in
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 4cc602b5c8709..e88d0c76836f7 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7400,3 +7400,23 @@ bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO,
return false;
}
+
+bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GZext *Zext = cast<GZext>(getDefIgnoringCopies(MO.getReg(), MRI));
+
+ Register Dst = Zext->getReg(0);
+ Register Src = Zext->getSrcReg();
+
+ LLT DstTy = MRI.getType(Dst);
+ LLT SrcTy = MRI.getType(Src);
+ const auto &TLI = getTargetLowering();
+
+ // Convert zext nneg to sext if sext is the preferred form for the target.
+ if (TLI.isSExtCheaperThanZExt(getMVTForLLT(SrcTy), getMVTForLLT(DstTy))) {
+ MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); };
+ return true;
+ }
+
+ return false;
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
index df3be2ef1f933..fd80afce6510e 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
@@ -105,8 +105,7 @@ entry:
define i64 @zext_nneg_i32_i64(i32 %a) {
; RV64IM-LABEL: zext_nneg_i32_i64:
; RV64IM: # %bb.0: # %entry
-; RV64IM-NEXT: slli a0, a0, 32
-; RV64IM-NEXT: srli a0, a0, 32
+; RV64IM-NEXT: sext.w a0, a0
; RV64IM-NEXT: ret
entry:
%b = zext nneg i32 %a to i64
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir b/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir
index 837b11df643a3..ef3fc4c9d5fae 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/combine.mir
@@ -9,8 +9,8 @@ body: |
; RV64-LABEL: name: nneg_zext
; RV64: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; RV64-NEXT: %2:_(s64) = nneg G_ZEXT [[TRUNC]](s32)
- ; RV64-NEXT: $x10 = COPY %2(s64)
+ ; RV64-NEXT: [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[TRUNC]](s32)
+ ; RV64-NEXT: $x10 = COPY [[SEXT]](s64)
; RV64-NEXT: PseudoRET implicit $x10
%0:_(s64) = COPY $x10
%2:_(s32) = G_TRUNC %0
>From 19908981ff2b528f5ea9ad803584afa7a8323862 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 31 May 2024 02:41:52 +0800
Subject: [PATCH 3/4] [GISel] Address review comments.
---
llvm/include/llvm/Target/GlobalISel/Combine.td | 4 +++-
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 78fcf1a506f90..1ea2652871ab8 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1780,6 +1780,8 @@ def fma_combines : GICombineGroup<[combine_fadd_fmul_to_fmad_or_fma,
def constant_fold_binops : GICombineGroup<[constant_fold_binop,
constant_fold_fp_binop]>;
+def prefer_sign_combines : GICombineGroup<[nneg_zext]>;
+
def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
vector_ops_combines, freeze_combines,
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
@@ -1803,7 +1805,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
combine_concat_vector, double_icmp_zero_and_or_combine, match_addos,
- sext_trunc, zext_trunc, nneg_zext, combine_shuffle_concat]>;
+ sext_trunc, zext_trunc, prefer_sign_combines, combine_shuffle_concat]>;
// 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 1a317271b2be9..e54c810729355 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7410,7 +7410,7 @@ bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO,
bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
BuildFnTy &MatchInfo) {
- GZext *Zext = cast<GZext>(getDefIgnoringCopies(MO.getReg(), MRI));
+ GZext *Zext = cast<GZext>(MRI.getVRegDef(MO.getReg()));
Register Dst = Zext->getReg(0);
Register Src = Zext->getSrcReg();
>From 56e9ce230767ea1221dbb378343bb24e7cccb641 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 31 May 2024 16:21:22 +0800
Subject: [PATCH 4/4] [GISel] Add legality check
---
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index e54c810729355..b516608aa53cd 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7420,7 +7420,8 @@ bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
const auto &TLI = getTargetLowering();
// Convert zext nneg to sext if sext is the preferred form for the target.
- if (TLI.isSExtCheaperThanZExt(getMVTForLLT(SrcTy), getMVTForLLT(DstTy))) {
+ if (isLegalOrBeforeLegalizer({TargetOpcode::G_SEXT, {DstTy, SrcTy}}) &&
+ TLI.isSExtCheaperThanZExt(getMVTForLLT(SrcTy), getMVTForLLT(DstTy))) {
MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); };
return true;
}
More information about the llvm-commits
mailing list