[llvm] r365657 - GlobalISel: Define the full family of FP min/max instructions

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 10 09:31:15 PDT 2019


Author: arsenm
Date: Wed Jul 10 09:31:15 2019
New Revision: 365657

URL: http://llvm.org/viewvc/llvm-project?rev=365657&view=rev
Log:
GlobalISel: Define the full family of FP min/max instructions

Added:
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll
Modified:
    llvm/trunk/include/llvm/Support/TargetOpcodes.def
    llvm/trunk/include/llvm/Target/GenericOpcodes.td
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Modified: llvm/trunk/include/llvm/Support/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TargetOpcodes.def?rev=365657&r1=365656&r2=365657&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Support/TargetOpcodes.def Wed Jul 10 09:31:15 2019
@@ -493,6 +493,18 @@ HANDLE_TARGET_OPCODE(G_FCOPYSIGN)
 /// Generic FP canonicalize value.
 HANDLE_TARGET_OPCODE(G_FCANONICALIZE)
 
+/// FP min/max matching libm's fmin/fmax
+HANDLE_TARGET_OPCODE(G_FMINNUM)
+HANDLE_TARGET_OPCODE(G_FMAXNUM)
+
+/// FP min/max matching IEEE-754 2008's minnum/maxnum semantics.
+HANDLE_TARGET_OPCODE(G_FMINNUM_IEEE)
+HANDLE_TARGET_OPCODE(G_FMAXNUM_IEEE)
+
+/// FP min/max matching IEEE-754 2018 draft semantics.
+HANDLE_TARGET_OPCODE(G_FMINIMUM)
+HANDLE_TARGET_OPCODE(G_FMAXIMUM)
+
 /// Generic pointer offset
 HANDLE_TARGET_OPCODE(G_GEP)
 

Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=365657&r1=365656&r2=365657&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
+++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Wed Jul 10 09:31:15 2019
@@ -505,6 +505,62 @@ def G_FCANONICALIZE : GenericInstruction
   let hasSideEffects = 0;
 }
 
+// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
+// values.
+//
+// In the case where a single input is a NaN (either signaling or quiet),
+// the non-NaN input is returned.
+//
+// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
+def G_FMINNUM : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+  let isCommutable = 1;
+}
+
+def G_FMAXNUM : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+  let isCommutable = 1;
+}
+
+// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
+// two values, following the IEEE-754 2008 definition. This differs from
+// FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
+// signaling NaN, returns a quiet NaN.
+def G_FMINNUM_IEEE : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+  let isCommutable = 1;
+}
+
+def G_FMAXNUM_IEEE : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+  let isCommutable = 1;
+}
+
+// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
+// as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
+// semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
+def G_FMINIMUM : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+  let isCommutable = 1;
+}
+
+def G_FMAXIMUM : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = 0;
+  let isCommutable = 1;
+}
+
 //------------------------------------------------------------------------------
 // Floating Point Binary ops.
 //------------------------------------------------------------------------------

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=365657&r1=365656&r2=365657&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Wed Jul 10 09:31:15 2019
@@ -1222,6 +1222,14 @@ unsigned IRTranslator::getSimpleIntrinsi
       return TargetOpcode::G_FABS;
     case Intrinsic::copysign:
       return TargetOpcode::G_FCOPYSIGN;
+    case Intrinsic::minnum:
+      return TargetOpcode::G_FMINNUM;
+    case Intrinsic::maxnum:
+      return TargetOpcode::G_FMAXNUM;
+    case Intrinsic::minimum:
+      return TargetOpcode::G_FMINIMUM;
+    case Intrinsic::maximum:
+      return TargetOpcode::G_FMAXIMUM;
     case Intrinsic::canonicalize:
       return TargetOpcode::G_FCANONICALIZE;
     case Intrinsic::floor:

Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll?rev=365657&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll Wed Jul 10 09:31:15 2019
@@ -0,0 +1,88 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -mtriple=aarch64-- -verify-machineinstrs -global-isel -stop-after=irtranslator -o - %s | FileCheck %s
+
+define float @test_minnum(float %x, float %y) {
+  ; CHECK-LABEL: name: test_minnum
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $s0, $s1
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
+  ; CHECK:   [[FMINNUM:%[0-9]+]]:_(s32) = G_FMINNUM [[COPY]], [[COPY1]]
+  ; CHECK:   $s0 = COPY [[FMINNUM]](s32)
+  ; CHECK:   RET_ReallyLR implicit $s0
+  %val = call float @llvm.minnum.f32(float %x, float %y)
+  ret float %val
+}
+
+define float @test_minnum_nnan(float %x, float %y) {
+  ; CHECK-LABEL: name: test_minnum_nnan
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $s0, $s1
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
+  ; CHECK:   %2:_(s32) = nnan G_FMINNUM [[COPY]], [[COPY1]]
+  ; CHECK:   $s0 = COPY %2(s32)
+  ; CHECK:   RET_ReallyLR implicit $s0
+  %val = call nnan float @llvm.minnum.f32(float %x, float %y)
+  ret float %val
+}
+
+define float @test_maxnum(float %x, float %y) {
+  ; CHECK-LABEL: name: test_maxnum
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $s0, $s1
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
+  ; CHECK:   [[FMAXNUM:%[0-9]+]]:_(s32) = G_FMAXNUM [[COPY]], [[COPY1]]
+  ; CHECK:   $s0 = COPY [[FMAXNUM]](s32)
+  ; CHECK:   RET_ReallyLR implicit $s0
+  %val = call float @llvm.maxnum.f32(float %x, float %y)
+  ret float %val
+}
+
+define float @test_minimum(float %x, float %y) {
+  ; CHECK-LABEL: name: test_minimum
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $s0, $s1
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
+  ; CHECK:   [[FMINIMUM:%[0-9]+]]:_(s32) = G_FMINIMUM [[COPY]], [[COPY1]]
+  ; CHECK:   $s0 = COPY [[FMINIMUM]](s32)
+  ; CHECK:   RET_ReallyLR implicit $s0
+  %val = call float @llvm.minimum.f32(float %x, float %y)
+  ret float %val
+}
+
+define float @test_minimum_nnan(float %x, float %y) {
+  ; CHECK-LABEL: name: test_minimum_nnan
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $s0, $s1
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
+  ; CHECK:   %2:_(s32) = nnan G_FMINIMUM [[COPY]], [[COPY1]]
+  ; CHECK:   $s0 = COPY %2(s32)
+  ; CHECK:   RET_ReallyLR implicit $s0
+  %val = call nnan float @llvm.minimum.f32(float %x, float %y)
+  ret float %val
+}
+
+define float @test_maximum(float %x, float %y) {
+  ; CHECK-LABEL: name: test_maximum
+  ; CHECK: bb.1 (%ir-block.0):
+  ; CHECK:   liveins: $s0, $s1
+  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
+  ; CHECK:   [[FMAXIMUM:%[0-9]+]]:_(s32) = G_FMAXIMUM [[COPY]], [[COPY1]]
+  ; CHECK:   $s0 = COPY [[FMAXIMUM]](s32)
+  ; CHECK:   RET_ReallyLR implicit $s0
+  %val = call float @llvm.maximum.f32(float %x, float %y)
+  ret float %val
+}
+
+declare float @llvm.minnum.f32(float, float) #0
+declare float @llvm.maxnum.f32(float, float) #0
+
+declare float @llvm.minimum.f32(float, float) #0
+declare float @llvm.maximum.f32(float, float) #0
+
+attributes #0 = { nounwind readnone speculatable }

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir?rev=365657&r1=365656&r2=365657&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir Wed Jul 10 09:31:15 2019
@@ -303,6 +303,24 @@
 # DEBUG-NEXT: G_FCANONICALIZE (opcode {{[0-9]+}}): 1 type index
 # DEBUG: .. type index coverage check SKIPPED: no rules defined
 #
+# DEBUG-NEXT: G_FMINNUM (opcode 131): 1 type index
+# DEBUG: .. type index coverage check SKIPPED: no rules defined
+#
+# DEBUG-NEXT: G_FMAXNUM (opcode 132): 1 type index
+# DEBUG: .. type index coverage check SKIPPED: no rules defined
+#
+# DEBUG-NEXT: G_FMINNUM_IEEE (opcode 133): 1 type index
+# DEBUG: .. type index coverage check SKIPPED: no rules defined
+#
+# DEBUG-NEXT: G_FMAXNUM_IEEE (opcode 134): 1 type index
+# DEBUG: .. type index coverage check SKIPPED: no rules defined
+#
+# DEBUG-NEXT: G_FMINIMUM (opcode 135): 1 type index
+# DEBUG: .. type index coverage check SKIPPED: no rules defined
+#
+# DEBUG-NEXT: G_FMAXIMUM (opcode 136): 1 type index
+# DEBUG: .. type index coverage check SKIPPED: no rules defined
+#
 # DEBUG-NEXT: G_GEP (opcode {{[0-9]+}}): 2 type indices
 # DEBUG:      .. the first uncovered type index: 2, OK
 #




More information about the llvm-commits mailing list