mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-05 11:46:42 +00:00
[SelectionDAG] Do minnum->minimum at legalization time instead of building time
The SDAGBuilder behavior stems from the days when we didn't have fast math flags available in SDAG. We do now and doing the transformation in the legalizer has the advantage that it also works for vector types. llvm-svn: 364743
This commit is contained in:
parent
5c70cae542
commit
919564baf2
@ -6016,28 +6016,18 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
|
||||
getValue(I.getArgOperand(0))));
|
||||
return;
|
||||
}
|
||||
case Intrinsic::minnum: {
|
||||
auto VT = getValue(I.getArgOperand(0)).getValueType();
|
||||
unsigned Opc =
|
||||
I.hasNoNaNs() && TLI.isOperationLegalOrCustom(ISD::FMINIMUM, VT)
|
||||
? ISD::FMINIMUM
|
||||
: ISD::FMINNUM;
|
||||
setValue(&I, DAG.getNode(Opc, sdl, VT,
|
||||
case Intrinsic::minnum:
|
||||
setValue(&I, DAG.getNode(ISD::FMINNUM, sdl,
|
||||
getValue(I.getArgOperand(0)).getValueType(),
|
||||
getValue(I.getArgOperand(0)),
|
||||
getValue(I.getArgOperand(1))));
|
||||
return;
|
||||
}
|
||||
case Intrinsic::maxnum: {
|
||||
auto VT = getValue(I.getArgOperand(0)).getValueType();
|
||||
unsigned Opc =
|
||||
I.hasNoNaNs() && TLI.isOperationLegalOrCustom(ISD::FMAXIMUM, VT)
|
||||
? ISD::FMAXIMUM
|
||||
: ISD::FMAXNUM;
|
||||
setValue(&I, DAG.getNode(Opc, sdl, VT,
|
||||
case Intrinsic::maxnum:
|
||||
setValue(&I, DAG.getNode(ISD::FMAXNUM, sdl,
|
||||
getValue(I.getArgOperand(0)).getValueType(),
|
||||
getValue(I.getArgOperand(0)),
|
||||
getValue(I.getArgOperand(1))));
|
||||
return;
|
||||
}
|
||||
case Intrinsic::minimum:
|
||||
setValue(&I, DAG.getNode(ISD::FMINIMUM, sdl,
|
||||
getValue(I.getArgOperand(0)).getValueType(),
|
||||
|
@ -5098,6 +5098,17 @@ SDValue TargetLowering::expandFMINNUM_FMAXNUM(SDNode *Node,
|
||||
return DAG.getNode(NewOp, dl, VT, Quiet0, Quiet1, Node->getFlags());
|
||||
}
|
||||
|
||||
// If the target has FMINIMUM/FMAXIMUM but not FMINNUM/FMAXNUM use that
|
||||
// instead if there are no NaNs.
|
||||
if (Node->getFlags().hasNoNaNs()) {
|
||||
unsigned IEEE2018Op =
|
||||
Node->getOpcode() == ISD::FMINNUM ? ISD::FMINIMUM : ISD::FMAXIMUM;
|
||||
if (isOperationLegalOrCustom(IEEE2018Op, VT)) {
|
||||
return DAG.getNode(IEEE2018Op, dl, VT, Node->getOperand(0),
|
||||
Node->getOperand(1), Node->getFlags());
|
||||
}
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,15 @@ define float @fmin32_intrinsic(float %x, float %y) {
|
||||
ret float %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: fminnum32_intrinsic:
|
||||
; CHECK: f32.min $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
|
||||
; CHECK-NEXT: return $pop0{{$}}
|
||||
declare float @llvm.minnum.f32(float, float)
|
||||
define float @fminnum32_intrinsic(float %x, float %y) {
|
||||
%a = call nnan float @llvm.minnum.f32(float %x, float %y)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: fmax32_intrinsic:
|
||||
; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
|
||||
; CHECK-NEXT: return $pop0{{$}}
|
||||
@ -158,6 +167,15 @@ define float @fmax32_intrinsic(float %x, float %y) {
|
||||
ret float %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: fmaxnum32_intrinsic:
|
||||
; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
|
||||
; CHECK-NEXT: return $pop0{{$}}
|
||||
declare float @llvm.maxnum.f32(float, float)
|
||||
define float @fmaxnum32_intrinsic(float %x, float %y) {
|
||||
%a = call nnan float @llvm.maxnum.f32(float %x, float %y)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: fma32:
|
||||
; CHECK: {{^}} f32.call $push[[LR:[0-9]+]]=, fmaf, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
|
||||
; CHECK-NEXT: return $pop[[LR]]{{$}}
|
||||
|
@ -1073,6 +1073,17 @@ define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
|
||||
ret <4 x float> %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: minnum_intrinsic_v4f32:
|
||||
; NO-SIMD128-NOT: f32x4
|
||||
; SIMD128-NEXT: .functype minnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
|
||||
; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
|
||||
define <4 x float> @minnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
|
||||
%a = call nnan <4 x float> @llvm.minnum.v4f32(<4 x float> %x, <4 x float> %y)
|
||||
ret <4 x float> %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: max_intrinsic_v4f32:
|
||||
; NO-SIMD128-NOT: f32x4
|
||||
; SIMD128-NEXT: .functype max_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
|
||||
@ -1084,6 +1095,17 @@ define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
|
||||
ret <4 x float> %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: maxnum_intrinsic_v4f32:
|
||||
; NO-SIMD128-NOT: f32x4
|
||||
; SIMD128-NEXT: .functype maxnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
|
||||
; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
|
||||
define <4 x float> @maxnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
|
||||
%a = call nnan <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y)
|
||||
ret <4 x float> %a
|
||||
}
|
||||
|
||||
; CHECK-LABEL: min_const_intrinsic_v4f32:
|
||||
; NO-SIMD128-NOT: f32x4
|
||||
; SIMD128-NEXT: .functype min_const_intrinsic_v4f32 () -> (v128){{$}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user