1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[ConstantFolding] Enable folding of min/max/copysign for all floats

Previously such folding was enabled for half, float and double values
only. With this change it is allowed for other floating point values
also.

Differential Revision: https://reviews.llvm.org/D103956
This commit is contained in:
Serge Pavlov 2021-06-09 10:49:17 +07:00
parent 71c9962122
commit e952eb5d5d
3 changed files with 164 additions and 21 deletions

View File

@ -2362,7 +2362,7 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
}
if (auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
if (!Ty->isFloatingPointTy())
return nullptr;
APFloat Op1V = Op1->getValueAPF();
@ -2374,8 +2374,6 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
switch (IntrinsicID) {
default:
break;
case Intrinsic::pow:
return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
case Intrinsic::copysign:
return ConstantFP::get(Ty->getContext(), APFloat::copySign(Op1V, Op2V));
case Intrinsic::minnum:
@ -2386,6 +2384,16 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
return ConstantFP::get(Ty->getContext(), minimum(Op1V, Op2V));
case Intrinsic::maximum:
return ConstantFP::get(Ty->getContext(), maximum(Op1V, Op2V));
}
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return nullptr;
switch (IntrinsicID) {
default:
break;
case Intrinsic::pow:
return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
case Intrinsic::amdgcn_fmul_legacy:
// The legacy behaviour is that multiplying +/- 0.0 by anything, even
// NaN or infinity, gives +0.0.

View File

@ -57,8 +57,7 @@ define double @f64_03() {
define bfloat @bf16_01() {
; CHECK-LABEL: @bf16_01(
; CHECK-NEXT: [[X:%.*]] = call bfloat @llvm.copysign.bf16(bfloat 0xR3F80, bfloat 0xRC000)
; CHECK-NEXT: ret bfloat [[X]]
; CHECK-NEXT: ret bfloat 0xRBF80
;
%x = call bfloat @llvm.copysign.bf16(bfloat 1.0, bfloat -2.0)
ret bfloat %x
@ -66,8 +65,7 @@ define bfloat @bf16_01() {
define bfloat @bf16_02() {
; CHECK-LABEL: @bf16_02(
; CHECK-NEXT: [[X:%.*]] = call bfloat @llvm.copysign.bf16(bfloat 0xRC000, bfloat 0xR3F80)
; CHECK-NEXT: ret bfloat [[X]]
; CHECK-NEXT: ret bfloat 0xR4000
;
%x = call bfloat @llvm.copysign.bf16(bfloat -2.0, bfloat 1.0)
ret bfloat %x
@ -75,8 +73,7 @@ define bfloat @bf16_02() {
define bfloat @bf16_03() {
; CHECK-LABEL: @bf16_03(
; CHECK-NEXT: [[X:%.*]] = call bfloat @llvm.copysign.bf16(bfloat 0xRC000, bfloat 0xRBF80)
; CHECK-NEXT: ret bfloat [[X]]
; CHECK-NEXT: ret bfloat 0xRC000
;
%x = call bfloat @llvm.copysign.bf16(bfloat -2.0, bfloat -1.0)
ret bfloat %x
@ -84,8 +81,7 @@ define bfloat @bf16_03() {
define fp128 @f128_01() {
; CHECK-LABEL: @f128_01(
; CHECK-NEXT: [[X:%.*]] = call fp128 @llvm.copysign.f128(fp128 0xL00000000000000000000000000000001, fp128 0xL00000000000000008000000000000002)
; CHECK-NEXT: ret fp128 [[X]]
; CHECK-NEXT: ret fp128 0xL00000000000000008000000000000001
;
%x = call fp128 @llvm.copysign.f128(fp128 0xL00000000000000000000000000000001, fp128 0xL00000000000000008000000000000002)
ret fp128 %x
@ -93,8 +89,7 @@ define fp128 @f128_01() {
define fp128 @f128_02() {
; CHECK-LABEL: @f128_02(
; CHECK-NEXT: [[X:%.*]] = call fp128 @llvm.copysign.f128(fp128 0xL00000000000000008000000000000003, fp128 0xL00000000000000000000000000000004)
; CHECK-NEXT: ret fp128 [[X]]
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000003
;
%x = call fp128 @llvm.copysign.f128(fp128 0xL00000000000000008000000000000003, fp128 0xL00000000000000000000000000000004)
ret fp128 %x
@ -102,8 +97,7 @@ define fp128 @f128_02() {
define fp128 @f128_03() {
; CHECK-LABEL: @f128_03(
; CHECK-NEXT: [[X:%.*]] = call fp128 @llvm.copysign.f128(fp128 0xL00000000000000008000000000000005, fp128 0xL00000000000000008000000000000006)
; CHECK-NEXT: ret fp128 [[X]]
; CHECK-NEXT: ret fp128 0xL00000000000000008000000000000005
;
%x = call fp128 @llvm.copysign.f128(fp128 0xL00000000000000008000000000000005, fp128 0xL00000000000000008000000000000006)
ret fp128 %x
@ -111,8 +105,7 @@ define fp128 @f128_03() {
define ppc_fp128 @ppc128_01() {
; CHECK-LABEL: @ppc128_01(
; CHECK-NEXT: [[X:%.*]] = call ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 0xM00000000000000000000000000000001, ppc_fp128 0xM80000000000000000000000000000002)
; CHECK-NEXT: ret ppc_fp128 [[X]]
; CHECK-NEXT: ret ppc_fp128 0xM80000000000000008000000000000001
;
%x = call ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 0xM00000000000000000000000000000001, ppc_fp128 0xM80000000000000000000000000000002)
ret ppc_fp128 %x
@ -120,8 +113,7 @@ define ppc_fp128 @ppc128_01() {
define ppc_fp128 @ppc128_02() {
; CHECK-LABEL: @ppc128_02(
; CHECK-NEXT: [[X:%.*]] = call ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 0xM80000000000000000000000000000003, ppc_fp128 0xM00000000000000000000000000000004)
; CHECK-NEXT: ret ppc_fp128 [[X]]
; CHECK-NEXT: ret ppc_fp128 0xM00000000000000008000000000000003
;
%x = call ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 0xM80000000000000000000000000000003, ppc_fp128 0xM00000000000000000000000000000004)
ret ppc_fp128 %x
@ -129,8 +121,7 @@ define ppc_fp128 @ppc128_02() {
define ppc_fp128 @ppc128_03() {
; CHECK-LABEL: @ppc128_03(
; CHECK-NEXT: [[X:%.*]] = call ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 0xM80000000000000000000000000000005, ppc_fp128 0xM80000000000000000000000000000006)
; CHECK-NEXT: ret ppc_fp128 [[X]]
; CHECK-NEXT: ret ppc_fp128 0xM80000000000000000000000000000005
;
%x = call ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 0xM80000000000000000000000000000005, ppc_fp128 0xM80000000000000000000000000000006)
ret ppc_fp128 %x

View File

@ -2,16 +2,32 @@
; RUN: opt -instsimplify -S < %s | FileCheck %s
declare float @llvm.minnum.f32(float, float)
declare bfloat @llvm.minnum.bf16(bfloat, bfloat)
declare half @llvm.minnum.f16(half, half)
declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
declare <4 x bfloat> @llvm.minnum.v4bf16(<4 x bfloat>, <4 x bfloat>)
declare <4 x half> @llvm.minnum.v4f16(<4 x half>, <4 x half>)
declare float @llvm.maxnum.f32(float, float)
declare bfloat @llvm.maxnum.bf16(bfloat, bfloat)
declare half @llvm.maxnum.f16(half, half)
declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
declare <4 x bfloat> @llvm.maxnum.v4bf16(<4 x bfloat>, <4 x bfloat>)
declare <4 x half> @llvm.maxnum.v4f16(<4 x half>, <4 x half>)
declare float @llvm.minimum.f32(float, float)
declare bfloat @llvm.minimum.bf16(bfloat, bfloat)
declare half @llvm.minimum.f16(half, half)
declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>)
declare <4 x bfloat> @llvm.minimum.v4bf16(<4 x bfloat>, <4 x bfloat>)
declare <4 x half> @llvm.minimum.v4f16(<4 x half>, <4 x half>)
declare float @llvm.maximum.f32(float, float)
declare bfloat @llvm.maximum.bf16(bfloat, bfloat)
declare half @llvm.maximum.f16(half, half)
declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>)
declare <4 x bfloat> @llvm.maximum.v4bf16(<4 x bfloat>, <4 x bfloat>)
declare <4 x half> @llvm.maximum.v4f16(<4 x half>, <4 x half>)
declare i8 @llvm.smax.i8(i8, i8)
declare <5 x i8> @llvm.smax.v5i8(<5 x i8>, <5 x i8>)
@ -33,6 +49,22 @@ define float @minnum_float() {
ret float %1
}
define bfloat @minnum_bfloat() {
; CHECK-LABEL: @minnum_bfloat(
; CHECK-NEXT: ret bfloat 0xR40A0
;
%1 = call bfloat @llvm.minnum.bf16(bfloat 5.0, bfloat 42.0)
ret bfloat %1
}
define half @minnum_half() {
; CHECK-LABEL: @minnum_half(
; CHECK-NEXT: ret half 0xH4500
;
%1 = call half @llvm.minnum.f16(half 5.0, half 42.0)
ret half %1
}
; Check that minnum constant folds to propagate non-NaN or smaller argument
define <4 x float> @minnum_float_vec() {
@ -43,6 +75,22 @@ define <4 x float> @minnum_float_vec() {
ret <4 x float> %1
}
define <4 x bfloat> @minnum_bfloat_vec() {
; CHECK-LABEL: @minnum_bfloat_vec(
; CHECK-NEXT: ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR40A0, bfloat 0xR4228, bfloat 0xR40A0>
;
%1 = call <4 x bfloat> @llvm.minnum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
ret <4 x bfloat> %1
}
define <4 x half> @minnum_half_vec() {
; CHECK-LABEL: @minnum_half_vec(
; CHECK-NEXT: ret <4 x half> <half 0xH7E00, half 0xH4500, half 0xH5140, half 0xH4500>
;
%1 = call <4 x half> @llvm.minnum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
ret <4 x half> %1
}
; Check that minnum constant folds to propagate one of its argument zeros
define <4 x float> @minnum_float_zeros_vec() {
@ -61,6 +109,22 @@ define float @maxnum_float() {
ret float %1
}
define bfloat @maxnum_bfloat() {
; CHECK-LABEL: @maxnum_bfloat(
; CHECK-NEXT: ret bfloat 0xR4228
;
%1 = call bfloat @llvm.maxnum.bf16(bfloat 5.0, bfloat 42.0)
ret bfloat %1
}
define half @maxnum_half() {
; CHECK-LABEL: @maxnum_half(
; CHECK-NEXT: ret half 0xH5140
;
%1 = call half @llvm.maxnum.f16(half 5.0, half 42.0)
ret half %1
}
; Check that maxnum constant folds to propagate non-NaN or greater argument
define <4 x float> @maxnum_float_vec() {
@ -71,6 +135,22 @@ define <4 x float> @maxnum_float_vec() {
ret <4 x float> %1
}
define <4 x bfloat> @maxnum_bfloat_vec() {
; CHECK-LABEL: @maxnum_bfloat_vec(
; CHECK-NEXT: ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR40A0, bfloat 0xR4228, bfloat 0xR4228>
;
%1 = call <4 x bfloat> @llvm.maxnum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
ret <4 x bfloat> %1
}
define <4 x half> @maxnum_half_vec() {
; CHECK-LABEL: @maxnum_half_vec(
; CHECK-NEXT: ret <4 x half> <half 0xH7E00, half 0xH4500, half 0xH5140, half 0xH5140>
;
%1 = call <4 x half> @llvm.maxnum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
ret <4 x half> %1
}
; Check that maxnum constant folds to propagate one of its argument zeros
define <4 x float> @maxnum_float_zeros_vec() {
@ -89,6 +169,22 @@ define float @minimum_float() {
ret float %1
}
define bfloat @minimum_bfloat() {
; CHECK-LABEL: @minimum_bfloat(
; CHECK-NEXT: ret bfloat 0xR40A0
;
%1 = call bfloat @llvm.minimum.bf16(bfloat 5.0, bfloat 42.0)
ret bfloat %1
}
define half @minimum_half() {
; CHECK-LABEL: @minimum_half(
; CHECK-NEXT: ret half 0xH4500
;
%1 = call half @llvm.minimum.f16(half 5.0, half 42.0)
ret half %1
}
; Check that minimum propagates its NaN or smaller argument
define <4 x float> @minimum_float_vec() {
@ -99,6 +195,22 @@ define <4 x float> @minimum_float_vec() {
ret <4 x float> %1
}
define <4 x bfloat> @minimum_bfloat_vec() {
; CHECK-LABEL: @minimum_bfloat_vec(
; CHECK-NEXT: ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR40A0>
;
%1 = call <4 x bfloat> @llvm.minimum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
ret <4 x bfloat> %1
}
define <4 x half> @minimum_half_vec() {
; CHECK-LABEL: @minimum_half_vec(
; CHECK-NEXT: ret <4 x half> <half 0xH7E00, half 0xH7E00, half 0xH7E00, half 0xH4500>
;
%1 = call <4 x half> @llvm.minimum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
ret <4 x half> %1
}
; Check that minimum treats -0.0 as smaller than 0.0 while constant folding
define <4 x float> @minimum_float_zeros_vec() {
@ -117,6 +229,22 @@ define float @maximum_float() {
ret float %1
}
define bfloat @maximum_bfloat() {
; CHECK-LABEL: @maximum_bfloat(
; CHECK-NEXT: ret bfloat 0xR4228
;
%1 = call bfloat @llvm.maximum.bf16(bfloat 5.0, bfloat 42.0)
ret bfloat %1
}
define half @maximum_half() {
; CHECK-LABEL: @maximum_half(
; CHECK-NEXT: ret half 0xH5140
;
%1 = call half @llvm.maximum.f16(half 5.0, half 42.0)
ret half %1
}
; Check that maximum propagates its NaN or greater argument
define <4 x float> @maximum_float_vec() {
@ -127,6 +255,22 @@ define <4 x float> @maximum_float_vec() {
ret <4 x float> %1
}
define <4 x bfloat> @maximum_bfloat_vec() {
; CHECK-LABEL: @maximum_bfloat_vec(
; CHECK-NEXT: ret <4 x bfloat> <bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR7FC0, bfloat 0xR4228>
;
%1 = call <4 x bfloat> @llvm.maximum.v4bf16(<4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 0x7FF8000000000000, bfloat 42., bfloat 42.>, <4 x bfloat> <bfloat 0x7FF8000000000000, bfloat 5., bfloat 0x7FF8000000000000, bfloat 5.>)
ret <4 x bfloat> %1
}
define <4 x half> @maximum_half_vec() {
; CHECK-LABEL: @maximum_half_vec(
; CHECK-NEXT: ret <4 x half> <half 0xH7E00, half 0xH7E00, half 0xH7E00, half 0xH5140>
;
%1 = call <4 x half> @llvm.maximum.v4f16(<4 x half> <half 0x7FF8000000000000, half 0x7FF8000000000000, half 42., half 42.>, <4 x half> <half 0x7FF8000000000000, half 5., half 0x7FF8000000000000, half 5.>)
ret <4 x half> %1
}
; Check that maximum treats -0.0 as smaller than 0.0 while constant folding
define <4 x float> @maximum_float_zeros_vec() {