[llvm] 3f100e6 - [InstSimplify] fix fmin/fmax miscompile for partial undef vectors (PR47567)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 18 07:05:54 PDT 2020


Author: Sanjay Patel
Date: 2020-09-18T10:05:44-04:00
New Revision: 3f100e64b429b6468e9a2c5b3e7ef7757a06dc48

URL: https://github.com/llvm/llvm-project/commit/3f100e64b429b6468e9a2c5b3e7ef7757a06dc48
DIFF: https://github.com/llvm/llvm-project/commit/3f100e64b429b6468e9a2c5b3e7ef7757a06dc48.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/fminmax-folds.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 7d939bb63a6b..7645cc93545c 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5480,7 +5480,7 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
     // minimum(X, nan) -> nan
     // maximum(X, nan) -> 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
     // float, if the ninf flag is set.

diff  --git a/llvm/test/Transforms/InstSimplify/fminmax-folds.ll b/llvm/test/Transforms/InstSimplify/fminmax-folds.ll
index c62f76c87fae..e87c2f1d1260 100644
--- a/llvm/test/Transforms/InstSimplify/fminmax-folds.ll
+++ b/llvm/test/Transforms/InstSimplify/fminmax-folds.ll
@@ -806,14 +806,22 @@ define double @minimum_nan_op1(double %x) {
   ret double %r
 }
 
-define <2 x double> @maximum_nan_op0_vec(<2 x double> %x) {
-; CHECK-LABEL: @maximum_nan_op0_vec(
-; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double undef>
+define <2 x double> @maximum_nan_op0_vec_partial_undef(<2 x double> %x) {
+; CHECK-LABEL: @maximum_nan_op0_vec_partial_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)
   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) {
 ; CHECK-LABEL: @maximum_nan_op1_vec(
 ; 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
 }
 
-define <2 x double> @minimum_nan_op0_vec(<2 x double> %x) {
-; CHECK-LABEL: @minimum_nan_op0_vec(
-; CHECK-NEXT:    ret <2 x double> <double undef, double 0x7FF8000DEAD00000>
+define <2 x double> @minimum_nan_op0_vec_partial_undef(<2 x double> %x) {
+; CHECK-LABEL: @minimum_nan_op0_vec_partial_undef(
+; 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)
   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) {
 ; CHECK-LABEL: @minimum_nan_op1_vec(
 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF800DEAD00DEAD, double 0x7FF800DEAD00DEAD>


        


More information about the llvm-commits mailing list