mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[InstSimplify] allow folds for fmin/fmax with 'ninf'
maxnum(ninf X, +FLT_MAX) --> +FLT_MAX minnum(ninf X, -FLT_MAX) --> -FLT_MAX This is based on the similar codegen transform proposed in: D87571
This commit is contained in:
parent
200286e570
commit
b11cd5329a
@ -5455,23 +5455,30 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
|
||||
if (Q.isUndefValue(Op1))
|
||||
return Op0;
|
||||
|
||||
// If an argument is NaN, return other or NaN appropriately.
|
||||
bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
|
||||
bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
|
||||
|
||||
// minnum(X, nan) -> X
|
||||
// maxnum(X, nan) -> X
|
||||
// minimum(X, nan) -> nan
|
||||
// maximum(X, nan) -> nan
|
||||
if (match(Op1, m_NaN()))
|
||||
return PropagateNaN ? Op1 : Op0;
|
||||
|
||||
// min(X, -Inf) --> -Inf
|
||||
// max(X, +Inf) --> +Inf
|
||||
bool UseNegInf = IID == Intrinsic::minnum || IID == Intrinsic::minimum;
|
||||
// In the following folds, inf can be replaced with the largest finite
|
||||
// float, if the ninf flag is set.
|
||||
const APFloat *C;
|
||||
if (match(Op1, m_APFloat(C)) && C->isInfinity() &&
|
||||
C->isNegative() == UseNegInf && !PropagateNaN)
|
||||
return ConstantFP::getInfinity(ReturnType, UseNegInf);
|
||||
|
||||
// TODO: minimum(nnan x, inf) -> x
|
||||
// TODO: minnum(nnan ninf x, flt_max) -> x
|
||||
// TODO: maximum(nnan x, -inf) -> x
|
||||
// TODO: maxnum(nnan ninf x, -flt_max) -> x
|
||||
if (match(Op1, m_APFloat(C)) &&
|
||||
(C->isInfinity() || (Q.CxtI->hasNoInfs() && C->isLargest()))) {
|
||||
// min(X, -Inf) --> -Inf
|
||||
// max(X, +Inf) --> +Inf
|
||||
if (C->isNegative() == IsMin && !PropagateNaN)
|
||||
return ConstantFP::get(ReturnType, *C);
|
||||
// TODO: minimum(nnan x, inf) -> x
|
||||
// TODO: minnum(nnan ninf x, flt_max) -> x
|
||||
// TODO: maximum(nnan x, -inf) -> x
|
||||
// TODO: maxnum(nnan ninf x, -flt_max) -> x
|
||||
}
|
||||
|
||||
// Min/max of the same operation with common operand:
|
||||
// m(m(X, Y)), X --> m(X, Y) (4 commuted variants)
|
||||
|
@ -344,8 +344,7 @@ define float @test_minnum_const_max_ninf(float %x) {
|
||||
|
||||
define float @test_maxnum_const_max_ninf(float %x) {
|
||||
; CHECK-LABEL: @test_maxnum_const_max_ninf(
|
||||
; CHECK-NEXT: [[R:%.*]] = call ninf float @llvm.maxnum.f32(float [[X:%.*]], float 0x47EFFFFFE0000000)
|
||||
; CHECK-NEXT: ret float [[R]]
|
||||
; CHECK-NEXT: ret float 0x47EFFFFFE0000000
|
||||
;
|
||||
%r = call ninf float @llvm.maxnum.f32(float %x, float 0x47efffffe0000000)
|
||||
ret float %r
|
||||
@ -371,8 +370,7 @@ define float @test_minimum_const_max_ninf(float %x) {
|
||||
|
||||
define float @test_minnum_const_neg_max_ninf(float %x) {
|
||||
; CHECK-LABEL: @test_minnum_const_neg_max_ninf(
|
||||
; CHECK-NEXT: [[R:%.*]] = call ninf float @llvm.minnum.f32(float [[X:%.*]], float 0xC7EFFFFFE0000000)
|
||||
; CHECK-NEXT: ret float [[R]]
|
||||
; CHECK-NEXT: ret float 0xC7EFFFFFE0000000
|
||||
;
|
||||
%r = call ninf float @llvm.minnum.f32(float %x, float 0xc7efffffe0000000)
|
||||
ret float %r
|
||||
@ -416,8 +414,7 @@ define float @test_minnum_const_max_nnan_ninf(float %x) {
|
||||
|
||||
define float @test_maxnum_const_max_nnan_ninf(float %x) {
|
||||
; CHECK-LABEL: @test_maxnum_const_max_nnan_ninf(
|
||||
; CHECK-NEXT: [[R:%.*]] = call nnan ninf float @llvm.maxnum.f32(float [[X:%.*]], float 0x47EFFFFFE0000000)
|
||||
; CHECK-NEXT: ret float [[R]]
|
||||
; CHECK-NEXT: ret float 0x47EFFFFFE0000000
|
||||
;
|
||||
%r = call nnan ninf float @llvm.maxnum.f32(float %x, float 0x47efffffe0000000)
|
||||
ret float %r
|
||||
@ -443,8 +440,7 @@ define float @test_minimum_const_max_nnan_ninf(float %x) {
|
||||
|
||||
define float @test_minnum_const_neg_max_nnan_ninf(float %x) {
|
||||
; CHECK-LABEL: @test_minnum_const_neg_max_nnan_ninf(
|
||||
; CHECK-NEXT: [[R:%.*]] = call nnan ninf float @llvm.minnum.f32(float [[X:%.*]], float 0xC7EFFFFFE0000000)
|
||||
; CHECK-NEXT: ret float [[R]]
|
||||
; CHECK-NEXT: ret float 0xC7EFFFFFE0000000
|
||||
;
|
||||
%r = call nnan ninf float @llvm.minnum.f32(float %x, float 0xc7efffffe0000000)
|
||||
ret float %r
|
||||
|
Loading…
Reference in New Issue
Block a user