diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index 987d19e2f6ce1..a39994ca8f33d 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -608,6 +608,16 @@ NaN-propagating maximum that also treat -0.0 as less than 0.0. While FMAXNUM_IEEE follow IEEE 754-2008 semantics, FMAXIMUM follows IEEE 754-2019 semantics. +G_FMINIMUMNUM +^^^^^^^^^^^^^ + +IEEE-754 2019 minimumNumber + +G_FMAXIMUMNUM +^^^^^^^^^^^^^ + +IEEE-754 2019 maximumNumber + G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FREM ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 771c318da817d..92fd60e03112a 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -724,6 +724,8 @@ 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) +HANDLE_TARGET_OPCODE(G_FMINIMUMNUM) +HANDLE_TARGET_OPCODE(G_FMAXIMUMNUM) /// Access to FP environment. HANDLE_TARGET_OPCODE(G_GET_FPENV) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index c041c3cdfca5b..a462b07461b41 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -885,6 +885,21 @@ def G_FMAXIMUM : GenericInstruction { let isCommutable = true; } +/// G_FMINIMUMNUM/G_FMAXIMUMNUM - IEEE-754 2019 minimumNumber/maximumNumber +def G_FMINIMUMNUM : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1, type0:$src2); + let hasSideEffects = false; + let isCommutable = true; +} + +def G_FMAXIMUMNUM : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1, type0:$src2); + let hasSideEffects = false; + let isCommutable = true; +} + //------------------------------------------------------------------------------ // Floating Point Binary ops. //------------------------------------------------------------------------------ diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index dd418696c0aac..8ab2533afc15f 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1929,6 +1929,10 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { return TargetOpcode::G_FMINIMUM; case Intrinsic::maximum: return TargetOpcode::G_FMAXIMUM; + case Intrinsic::minimumnum: + return TargetOpcode::G_FMINIMUMNUM; + case Intrinsic::maximumnum: + return TargetOpcode::G_FMAXIMUMNUM; case Intrinsic::canonicalize: return TargetOpcode::G_FCANONICALIZE; case Intrinsic::floor: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll index ff92d4c43fa40..4e639974b66e0 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-fp-min-max-intrinsics.ll @@ -79,6 +79,62 @@ define float @test_maximum(float %x, float %y) { ret float %val } +define float @test_minimumnum(float %x, float %y) { + ; CHECK-LABEL: name: test_minimumnum + ; CHECK: bb.1 (%ir-block.0): + ; CHECK-NEXT: liveins: $s0, $s1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s1 + ; CHECK-NEXT: [[FMINIMUMNUM:%[0-9]+]]:_(s32) = G_FMINIMUMNUM [[COPY]], [[COPY1]] + ; CHECK-NEXT: $s0 = COPY [[FMINIMUMNUM]](s32) + ; CHECK-NEXT: RET_ReallyLR implicit $s0 + %val = call float @llvm.minimumnum.f32(float %x, float %y) + ret float %val +} + +define float @test_minimumnum_nnan(float %x, float %y) { + ; CHECK-LABEL: name: test_minimumnum_nnan + ; CHECK: bb.1 (%ir-block.0): + ; CHECK-NEXT: liveins: $s0, $s1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s1 + ; CHECK-NEXT: [[FMINIMUMNUM:%[0-9]+]]:_(s32) = nnan G_FMINIMUMNUM [[COPY]], [[COPY1]] + ; CHECK-NEXT: $s0 = COPY [[FMINIMUMNUM]](s32) + ; CHECK-NEXT: RET_ReallyLR implicit $s0 + %val = call nnan float @llvm.minimumnum.f32(float %x, float %y) + ret float %val +} + +define float @test_maximumnum(float %x, float %y) { + ; CHECK-LABEL: name: test_maximumnum + ; CHECK: bb.1 (%ir-block.0): + ; CHECK-NEXT: liveins: $s0, $s1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s1 + ; CHECK-NEXT: [[FMAXIMUMNUM:%[0-9]+]]:_(s32) = G_FMAXIMUMNUM [[COPY]], [[COPY1]] + ; CHECK-NEXT: $s0 = COPY [[FMAXIMUMNUM]](s32) + ; CHECK-NEXT: RET_ReallyLR implicit $s0 + %val = call float @llvm.maximumnum.f32(float %x, float %y) + ret float %val +} + +define float @test_maximumnum_nnan(float %x, float %y) { + ; CHECK-LABEL: name: test_maximumnum_nnan + ; CHECK: bb.1 (%ir-block.0): + ; CHECK-NEXT: liveins: $s0, $s1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s1 + ; CHECK-NEXT: [[FMAXIMUMNUM:%[0-9]+]]:_(s32) = nnan G_FMAXIMUMNUM [[COPY]], [[COPY1]] + ; CHECK-NEXT: $s0 = COPY [[FMAXIMUMNUM]](s32) + ; CHECK-NEXT: RET_ReallyLR implicit $s0 + %val = call nnan float @llvm.maximumnum.f32(float %x, float %y) + ret float %val +} + declare float @llvm.minnum.f32(float, float) #0 declare float @llvm.maxnum.f32(float, float) #0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 7c5af4b7baa36..612e44714752f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -598,6 +598,12 @@ # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK +# DEBUG-NEXT: G_FMINIMUMNUM (opcode {{[0-9]+}}): 1 type index +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FMAXIMUMNUM (opcode {{[0-9]+}}): 1 type index +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_GET_FPENV (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir index dd05eacef2408..0501e90c958da 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir @@ -591,6 +591,12 @@ # DEBUG-NEXT: G_FMAXIMUM (opcode {{[0-9]+}}): 1 type index # DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FMINIMUMNUM (opcode {{[0-9]+}}): 1 type index +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FMAXIMUMNUM (opcode {{[0-9]+}}): 1 type index +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_GET_FPENV (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined diff --git a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td index 22ec34026768c..570adbb632616 100644 --- a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td +++ b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td @@ -513,7 +513,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3), // R00O-NEXT: GIM_Reject, // R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] // R00O-NEXT: GIM_Reject, -// R00O-NEXT: }; // Size: 1848 bytes +// R00O-NEXT: }; // Size: 1856 bytes def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4), [(set GPR32:$dst,