1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ConstantFolding] add undef handling for fmin/fmax intrinsics

The output here may not be optimal (yet), but it should be
consistent for commuted operands (it was not before) and
correct. We can do better by checking FMF and NaN if needed.

Code in InstSimplify generally assumes that we have already
folded code like this, so it was not handling 2 constant
inputs by commuting consistently.
This commit is contained in:
Sanjay Patel 2020-09-18 16:37:17 -04:00
parent 58f51bc97c
commit 883809adba
2 changed files with 23 additions and 4 deletions

View File

@ -2305,6 +2305,25 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
const CallBase *Call) {
assert(Operands.size() == 2 && "Wrong number of operands.");
if (Ty->isFloatingPointTy()) {
// TODO: We should have undef handling for all of the FP intrinsics that
// are attempted to be folded in this function.
bool IsOp0Undef = isa<UndefValue>(Operands[0]);
bool IsOp1Undef = isa<UndefValue>(Operands[1]);
switch (IntrinsicID) {
case Intrinsic::maxnum:
case Intrinsic::minnum:
case Intrinsic::maximum:
case Intrinsic::minimum:
// If one argument is undef, return the other argument.
if (IsOp0Undef)
return Operands[1];
if (IsOp1Undef)
return Operands[0];
break;
}
}
if (auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return nullptr;

View File

@ -540,7 +540,7 @@ define <2 x double> @frem_undef_op0_constant_vec(<2 x double> %x) {
define <2 x double> @maximum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
; CHECK-LABEL: @maximum_nan_op0_vec_partial_undef_op1_undef(
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double undef>
;
%r = call <2 x double> @llvm.maximum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
ret <2 x double> %r
@ -556,7 +556,7 @@ define <2 x double> @maximum_nan_op1_vec_partial_undef_op0_undef(<2 x double> %x
define <2 x double> @minimum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
; CHECK-LABEL: @minimum_nan_op0_vec_partial_undef_op1_undef(
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double undef>
;
%r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
ret <2 x double> %r
@ -572,7 +572,7 @@ define <2 x double> @minimum_nan_op1_vec_partial_undef_op0_undef(<2 x double> %x
define <2 x double> @maxnum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
; CHECK-LABEL: @maxnum_nan_op0_vec_partial_undef_op1_undef(
; CHECK-NEXT: ret <2 x double> undef
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double undef>
;
%r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
ret <2 x double> %r
@ -588,7 +588,7 @@ define <2 x double> @maxnum_nan_op1_vec_partial_undef_op0_undef(<2 x double> %x)
define <2 x double> @minnum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
; CHECK-LABEL: @minnum_nan_op0_vec_partial_undef_op1_undef(
; CHECK-NEXT: ret <2 x double> undef
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double undef>
;
%r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
ret <2 x double> %r