mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01: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:
parent
71c9962122
commit
e952eb5d5d
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user