Skip to content

Commit 7152194

Browse files
authored
[MIPS] match llvm.{min,max}num with {min,max}.fmt for R6 (#89021)
- The behavior is similar to UCOMISD on x86, which is also used to compare two fp values, specifically on handling of NaNs. - Update related tests regarding this change. - The further goal is to implement `llvm.minimum` and `llvm.maximum` intrinsics for MIPS R6 and Pre-R6. Part of #64207
1 parent 8400324 commit 7152194

File tree

4 files changed

+395
-186
lines changed

4 files changed

+395
-186
lines changed

llvm/lib/Target/Mips/Mips32r6InstrInfo.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,22 @@ def : MipsPat<(select i32:$cond, immz, i32:$f),
11171117
ISA_MIPS32R6;
11181118
}
11191119

1120+
// llvm.fmin/fmax operations.
1121+
let AdditionalPredicates = [NotInMicroMips] in {
1122+
def : MipsPat<(fmaxnum f32:$lhs, f32:$rhs),
1123+
(MAX_S f32:$lhs, f32:$rhs)>,
1124+
ISA_MIPS32R6;
1125+
def : MipsPat<(fmaxnum f64:$lhs, f64:$rhs),
1126+
(MAX_D f64:$lhs, f64:$rhs)>,
1127+
ISA_MIPS32R6;
1128+
def : MipsPat<(fminnum f32:$lhs, f32:$rhs),
1129+
(MIN_S f32:$lhs, f32:$rhs)>,
1130+
ISA_MIPS32R6;
1131+
def : MipsPat<(fminnum f64:$lhs, f64:$rhs),
1132+
(MIN_D f64:$lhs, f64:$rhs)>,
1133+
ISA_MIPS32R6;
1134+
}
1135+
11201136
// Pseudo instructions
11211137
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
11221138
hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT], hasPostISelHook = 1 in {

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
358358
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
359359
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
360360

361+
// Lower fmin and fmax operations for MIPS R6.
362+
// Instructions are defined but never used.
363+
if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {
364+
setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
365+
setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
366+
setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
367+
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
368+
}
369+
361370
if (Subtarget.isGP64bit()) {
362371
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
363372
setOperationAction(ISD::BlockAddress, MVT::i64, Custom);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; RUN: llc %s -mtriple=mipsisa32r6el-linux-gnu -o - | \
2+
; RUN: FileCheck %s --check-prefix=MIPS32R6EL
3+
; RUN: llc %s -mtriple=mipsisa64r6el-linux-gnuabi64 -o - | \
4+
; RUN: FileCheck %s --check-prefix=MIPS64R6EL
5+
6+
define float @mins(float %x, float %y) {
7+
; MIPS32R6EL-LABEL: mins
8+
; MIPS32R6EL: # %bb.0:
9+
; MIPS32R6EL-NEXT: jr $ra
10+
; MIPS32R6EL-NEXT: min.s $f0, $f12, $f14
11+
;
12+
; MIPS64R6EL-LABEL: mins
13+
; MIPS64R6EL: # %bb.0:
14+
; MIPS64R6EL-NEXT: jr $ra
15+
; MIPS64R6EL-NEXT: min.s $f0, $f12, $f13
16+
17+
%r = tail call float @llvm.minnum.f32(float %x, float %y)
18+
ret float %r
19+
}
20+
21+
define float @maxs(float %x, float %y) {
22+
; MIPS32R6EL-LABEL: maxs
23+
; MIPS32R6EL: # %bb.0:
24+
; MIPS32R6EL-NEXT: jr $ra
25+
; MIPS32R6EL-NEXT: max.s $f0, $f12, $f14
26+
;
27+
; MIPS64R6EL-LABEL: maxs
28+
; MIPS64R6EL: # %bb.0:
29+
; MIPS64R6EL-NEXT: jr $ra
30+
; MIPS64R6EL-NEXT: max.s $f0, $f12, $f13
31+
32+
%r = tail call float @llvm.maxnum.f32(float %x, float %y)
33+
ret float %r
34+
}
35+
36+
define double @mind(double %x, double %y) {
37+
; MIPS32R6EL-LABEL: mind
38+
; MIPS32R6EL: # %bb.0:
39+
; MIPS32R6EL-NEXT: jr $ra
40+
; MIPS32R6EL-NEXT: min.d $f0, $f12, $f14
41+
;
42+
; MIPS64R6EL-LABEL: mind
43+
; MIPS64R6EL: # %bb.0:
44+
; MIPS64R6EL-NEXT: jr $ra
45+
; MIPS64R6EL-NEXT: min.d $f0, $f12, $f13
46+
47+
%r = tail call double @llvm.minnum.f64(double %x, double %y)
48+
ret double %r
49+
}
50+
51+
define double @maxd(double %x, double %y) {
52+
; MIPS32R6EL-LABEL: maxd
53+
; MIPS32R6EL: # %bb.0:
54+
; MIPS32R6EL-NEXT: jr $ra
55+
; MIPS32R6EL-NEXT: max.d $f0, $f12, $f14
56+
;
57+
; MIPS64R6EL-LABEL: maxd
58+
; MIPS64R6EL: # %bb.0:
59+
; MIPS64R6EL-NEXT: jr $ra
60+
; MIPS64R6EL-NEXT: max.d $f0, $f12, $f13
61+
62+
%r = tail call double @llvm.maxnum.f64(double %x, double %y)
63+
ret double %r
64+
}
65+
66+
declare float @llvm.minnum.f32(float, float)
67+
declare float @llvm.maxnum.f32(float, float)
68+
declare double @llvm.minnum.f64(double, double)
69+
declare double @llvm.maxnum.f64(double, double)

0 commit comments

Comments
 (0)