[llvm] 29bebb0 - [GISel] Add new combines for G_FMINNUM/MAXNUM and G_FMINIMUM/MAXIMUM
Michael Kitzan via llvm-commits
llvm-commits at lists.llvm.org
Wed May 18 12:22:19 PDT 2022
Author: Michael Kitzan
Date: 2022-05-18T12:08:53-07:00
New Revision: 29bebb0237965618b6c91fe32f63d13cf9ecabc5
URL: https://github.com/llvm/llvm-project/commit/29bebb0237965618b6c91fe32f63d13cf9ecabc5
DIFF: https://github.com/llvm/llvm-project/commit/29bebb0237965618b6c91fe32f63d13cf9ecabc5.diff
LOG: [GISel] Add new combines for G_FMINNUM/MAXNUM and G_FMINIMUM/MAXIMUM
I noticed https://reviews.llvm.org/D87415 added SDAG combines to fold
FMIN/MAX instrs with NaNs.
The patch implements the same NaN combines for GISel GMIR FMIN/MAX opcodes:
G_FMINNUM(X, NaN) -> X
G_FMAXNUM(X, NaN) -> X
G_FMINIMUM(X, NaN) -> NaN
G_FMAXIMUM(X, NaN) -> NaN
The patch adds AArch64 tests for these combines as well.
Reviewed by: arsenm
Differential revision: https://reviews.llvm.org/D125819
Added:
llvm/test/CodeGen/AArch64/GlobalISel/combine-fminimum-fmaximum.mir
llvm/test/CodeGen/AArch64/GlobalISel/combine-fminnum-fmaxnum.mir
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 9819d42427a8f..e2c503a94e00b 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -734,6 +734,8 @@ class CombinerHelper {
/// Fold boolean selects to logical operations.
bool matchSelectToLogical(MachineInstr &MI, BuildFnTy &MatchInfo);
+ bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info);
+
private:
/// Given a non-indexed load or store instruction \p MI, find an offset that
/// can be usefully and legally folded into it as a post-indexing operation.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 16580a432d638..38c5abb074cc2 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -891,6 +891,13 @@ def combine_fsub_fpext_fneg_fmul_to_fmad_or_fma: GICombineRule<
*${root}, ${info}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
+def combine_minmax_nan_matchinfo: GIDefMatchData<"unsigned">;
+def combine_minmax_nan: GICombineRule<
+ (defs root:$root, combine_minmax_nan_matchinfo:$info),
+ (match (wip_match_opcode G_FMINNUM, G_FMAXNUM, G_FMINIMUM, G_FMAXIMUM):$root,
+ [{ return Helper.matchCombineFMinMaxNaN(*${root}, ${info}); }]),
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${info}); }])>;
+
// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
undef_to_negative_one,
@@ -910,7 +917,7 @@ def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
def const_combines : GICombineGroup<[constant_fp_op, const_ptradd_to_i2p,
overlapping_and, mulo_by_2, mulo_by_0,
- addo_by_0]>;
+ addo_by_0, combine_minmax_nan]>;
def known_bits_simplifications : GICombineGroup<[
redundant_and, redundant_sext_inreg, redundant_or, urem_pow2_to_mask,
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 80f556cbaad79..f974fe9859ad3 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -5600,6 +5600,33 @@ bool CombinerHelper::matchSelectToLogical(MachineInstr &MI,
return false;
}
+bool CombinerHelper::matchCombineFMinMaxNaN(MachineInstr &MI,
+ unsigned &IdxToPropagate) {
+ bool PropagateNaN;
+ switch (MI.getOpcode()) {
+ default:
+ return false;
+ case TargetOpcode::G_FMINNUM:
+ case TargetOpcode::G_FMAXNUM:
+ PropagateNaN = false;
+ break;
+ case TargetOpcode::G_FMINIMUM:
+ case TargetOpcode::G_FMAXIMUM:
+ PropagateNaN = true;
+ break;
+ }
+
+ auto MatchNaN = [&](unsigned Idx) {
+ Register MaybeNaNReg = MI.getOperand(Idx).getReg();
+ const ConstantFP *MaybeCst = getConstantFPVRegVal(MaybeNaNReg, MRI);
+ if (!MaybeCst || !MaybeCst->getValueAPF().isNaN())
+ return false;
+ IdxToPropagate = PropagateNaN ? Idx : (Idx == 1 ? 2 : 1);
+ return true;
+ };
+
+ return MatchNaN(1) || MatchNaN(2);
+}
bool CombinerHelper::tryCombine(MachineInstr &MI) {
if (tryCombineCopy(MI))
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-fminimum-fmaximum.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-fminimum-fmaximum.mir
new file mode 100644
index 0000000000000..6e675c00d846b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-fminimum-fmaximum.mir
@@ -0,0 +1,159 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+
+---
+name: test_combine_nan_rhs_fminimum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fminimum_half
+ ; CHECK: [[C:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH7C01
+ ; CHECK-NEXT: $h0 = COPY [[C]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMINIMUM %0, %1
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fminimum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fminimum_float
+ ; CHECK: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMINIMUM %0, %1
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fminimum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fminimum_double
+ ; CHECK: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMINIMUM %0, %1
+ $x0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fminimum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fminimum_half
+ ; CHECK: [[C:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH7C01
+ ; CHECK-NEXT: $h0 = COPY [[C]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMINIMUM %1, %0
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fminimum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fminimum_float
+ ; CHECK: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMINIMUM %1, %0
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fminimum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fminimum_double
+ ; CHECK: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMINIMUM %1, %0
+ $x0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fmaximum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fmaximum_half
+ ; CHECK: [[C:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH7C01
+ ; CHECK-NEXT: $h0 = COPY [[C]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMAXIMUM %0, %1
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fmaximum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fmaximum_float
+ ; CHECK: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMAXIMUM %0, %1
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fmaximum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fmaximum_double
+ ; CHECK: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMAXIMUM %0, %1
+ $x0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fmaximum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fmaximum_half
+ ; CHECK: [[C:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH7C01
+ ; CHECK-NEXT: $h0 = COPY [[C]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMAXIMUM %1, %0
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fmaximum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fmaximum_float
+ ; CHECK: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMAXIMUM %1, %0
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fmaximum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fmaximum_double
+ ; CHECK: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMAXIMUM %1, %0
+ $x0 = COPY %2
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-fminnum-fmaxnum.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-fminnum-fmaxnum.mir
new file mode 100644
index 0000000000000..9f93205a38a5b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-fminnum-fmaxnum.mir
@@ -0,0 +1,159 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+
+---
+name: test_combine_nan_rhs_fminnum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fminnum_half
+ ; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: $h0 = COPY [[COPY]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMINNUM %0, %1
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fminnum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fminnum_float
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMINNUM %0, %1
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fminnum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fminnum_double
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMINNUM %0, %1
+ $x0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fminnum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fminnum_half
+ ; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: $h0 = COPY [[COPY]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMINNUM %1, %0
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fminnum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fminnum_float
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMINNUM %1, %0
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fminnum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fminnum_double
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMINNUM %1, %0
+ $x0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fmaxnum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fmaxnum_half
+ ; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: $h0 = COPY [[COPY]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMAXNUM %0, %1
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fmaxnum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fmaxnum_float
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMAXNUM %0, %1
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_rhs_fmaxnum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_rhs_fmaxnum_double
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMAXNUM %0, %1
+ $x0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fmaxnum_half
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fmaxnum_half
+ ; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: $h0 = COPY [[COPY]](s16)
+ %0:_(s16) = COPY $h0
+ %1:_(s16) = G_FCONSTANT half 0xH7C01
+ %2:_(s16) = G_FMAXNUM %1, %0
+ $h0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fmaxnum_float
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fmaxnum_float
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_FCONSTANT float 0x7FF8000000000000
+ %2:_(s32) = G_FMAXNUM %1, %0
+ $w0 = COPY %2
+...
+---
+name: test_combine_nan_lhs_fmaxnum_double
+body: |
+ bb.1:
+ liveins:
+ ; CHECK-LABEL: name: test_combine_nan_lhs_fmaxnum_double
+ ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 0x7FF8000000000000
+ %2:_(s64) = G_FMAXNUM %1, %0
+ $x0 = COPY %2
+...
More information about the llvm-commits
mailing list