[llvm] 8ff36aa - [ConstantFolding] Enable folding of min/max/copysign for all floats
Serge Pavlov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 9 21:58:37 PDT 2021
Author: Serge Pavlov
Date: 2021-06-10T11:57:51+07:00
New Revision: 8ff36aab69ece2cc91ba30f82847d19fe877a7ab
URL: https://github.com/llvm/llvm-project/commit/8ff36aab69ece2cc91ba30f82847d19fe877a7ab
DIFF: https://github.com/llvm/llvm-project/commit/8ff36aab69ece2cc91ba30f82847d19fe877a7ab.diff
LOG: [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
Added:
Modified:
llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstSimplify/ConstProp/copysign.ll
llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 85aab19c19bab..3508e3c68fa38 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -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.
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/copysign.ll b/llvm/test/Transforms/InstSimplify/ConstProp/copysign.ll
index 6c0dfbbf881ac..35bc5990df69f 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/copysign.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/copysign.ll
@@ -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
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll b/llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll
index 4ef2fbf13de7f..975ff36fd73e0 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll
@@ -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() {
More information about the llvm-commits
mailing list