[InstSimplify] fix fmin/fmax miscompile for partial undef vectors (PR47567)

It would also be correct to return the variable operand in these cases,
but eliminating a variable use is probably better for optimization.
This commit is contained in:
Sanjay Patel 2020-09-18 09:53:06 -04:00
parent 751a6c5760
commit 3f100e64b4
2 changed files with 23 additions and 7 deletions

View File

@ -5480,7 +5480,7 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
// minimum(X, nan) -> nan // minimum(X, nan) -> nan
// maximum(X, nan) -> nan // maximum(X, nan) -> nan
if (match(Op1, m_NaN())) if (match(Op1, m_NaN()))
return PropagateNaN ? Op1 : Op0; return PropagateNaN ? propagateNaN(cast<Constant>(Op1)) : Op0;
// In the following folds, inf can be replaced with the largest finite // In the following folds, inf can be replaced with the largest finite
// float, if the ninf flag is set. // float, if the ninf flag is set.

View File

@ -806,14 +806,22 @@ define double @minimum_nan_op1(double %x) {
ret double %r ret double %r
} }
define <2 x double> @maximum_nan_op0_vec(<2 x double> %x) { define <2 x double> @maximum_nan_op0_vec_partial_undef(<2 x double> %x) {
; CHECK-LABEL: @maximum_nan_op0_vec( ; CHECK-LABEL: @maximum_nan_op0_vec_partial_undef(
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double undef> ; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
; ;
%r = call <2 x double> @llvm.maximum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x) %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> %x)
ret <2 x double> %r ret <2 x double> %r
} }
define <2 x double> @maximum_nan_op1_vec_partial_undef(<2 x double> %x) {
; CHECK-LABEL: @maximum_nan_op1_vec_partial_undef(
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
;
%r = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> <double 0x7ff8000000000000, double undef>)
ret <2 x double> %r
}
define <2 x double> @maximum_nan_op1_vec(<2 x double> %x) { define <2 x double> @maximum_nan_op1_vec(<2 x double> %x) {
; CHECK-LABEL: @maximum_nan_op1_vec( ; CHECK-LABEL: @maximum_nan_op1_vec(
; CHECK-NEXT: ret <2 x double> <double 0x7FF800000000DEAD, double 0x7FF8FFFFFFFFFFFF> ; CHECK-NEXT: ret <2 x double> <double 0x7FF800000000DEAD, double 0x7FF8FFFFFFFFFFFF>
@ -822,14 +830,22 @@ define <2 x double> @maximum_nan_op1_vec(<2 x double> %x) {
ret <2 x double> %r ret <2 x double> %r
} }
define <2 x double> @minimum_nan_op0_vec(<2 x double> %x) { define <2 x double> @minimum_nan_op0_vec_partial_undef(<2 x double> %x) {
; CHECK-LABEL: @minimum_nan_op0_vec( ; CHECK-LABEL: @minimum_nan_op0_vec_partial_undef(
; CHECK-NEXT: ret <2 x double> <double undef, double 0x7FF8000DEAD00000> ; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
; ;
%r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x) %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double undef, double 0x7ff8000dead00000>, <2 x double> %x)
ret <2 x double> %r ret <2 x double> %r
} }
define <2 x double> @minimum_nan_op1_vec_partial_undef(<2 x double> %x) {
; CHECK-LABEL: @minimum_nan_op1_vec_partial_undef(
; CHECK-NEXT: ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
;
%r = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> <double undef, double 0x7ff8000dead00000>)
ret <2 x double> %r
}
define <2 x double> @minimum_nan_op1_vec(<2 x double> %x) { define <2 x double> @minimum_nan_op1_vec(<2 x double> %x) {
; CHECK-LABEL: @minimum_nan_op1_vec( ; CHECK-LABEL: @minimum_nan_op1_vec(
; CHECK-NEXT: ret <2 x double> <double 0x7FF800DEAD00DEAD, double 0x7FF800DEAD00DEAD> ; CHECK-NEXT: ret <2 x double> <double 0x7FF800DEAD00DEAD, double 0x7FF800DEAD00DEAD>