[llvm] 659bd73 - [InstSimplify] use FMF to improve fcmp+select fold

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 4 05:31:59 PST 2019


Author: Sanjay Patel
Date: 2019-11-04T08:29:56-05:00
New Revision: 659bd73d13686948c2b4dbee02df2f82542849dd

URL: https://github.com/llvm/llvm-project/commit/659bd73d13686948c2b4dbee02df2f82542849dd
DIFF: https://github.com/llvm/llvm-project/commit/659bd73d13686948c2b4dbee02df2f82542849dd.diff

LOG: [InstSimplify] use FMF to improve fcmp+select fold

This is part of a series of patches needed to solve PR39535:
https://bugs.llvm.org/show_bug.cgi?id=39535

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/fcmp-select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 11a12ab84e9b..83b767a8fd10 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3909,18 +3909,21 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
 
 /// Try to simplify a select instruction when its condition operand is a
 /// floating-point comparison.
-static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F) {
+static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F,
+                                     const SimplifyQuery &Q) {
   FCmpInst::Predicate Pred;
   if (!match(Cond, m_FCmp(Pred, m_Specific(T), m_Specific(F))) &&
       !match(Cond, m_FCmp(Pred, m_Specific(F), m_Specific(T))))
     return nullptr;
 
-  // TODO: The transform may not be valid with -0.0. An incomplete way of
-  // testing for that possibility is to check if at least one operand is a
-  // non-zero constant.
+  // This transform is safe if we do not have (do not care about) -0.0 or if
+  // at least one operand is known to not be -0.0. Otherwise, the select can
+  // change the sign of a zero operand.
+  bool HasNoSignedZeros = Q.CxtI && isa<FPMathOperator>(Q.CxtI) &&
+                          Q.CxtI->hasNoSignedZeros();
   const APFloat *C;
-  if ((match(T, m_APFloat(C)) && C->isNonZero()) ||
-      (match(F, m_APFloat(C)) && C->isNonZero())) {
+  if (HasNoSignedZeros || (match(T, m_APFloat(C)) && C->isNonZero()) ||
+                          (match(F, m_APFloat(C)) && C->isNonZero())) {
     // (T == F) ? T : F --> F
     // (F == T) ? T : F --> F
     if (Pred == FCmpInst::FCMP_OEQ)
@@ -3971,7 +3974,7 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
           simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse))
     return V;
 
-  if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal))
+  if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal, Q))
     return V;
 
   if (Value *V = foldSelectWithBinaryOp(Cond, TrueVal, FalseVal))

diff  --git a/llvm/test/Transforms/InstSimplify/fcmp-select.ll b/llvm/test/Transforms/InstSimplify/fcmp-select.ll
index 8e04a9b46744..e10069126f1c 100644
--- a/llvm/test/Transforms/InstSimplify/fcmp-select.ll
+++ b/llvm/test/Transforms/InstSimplify/fcmp-select.ll
@@ -104,9 +104,7 @@ define double @une_zero_swapped(double %x) {
 
 define double @oeq_zero_nsz(double %x) {
 ; CHECK-LABEL: @oeq_zero_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[COND:%.*]] = select nsz i1 [[CMP]], double [[X]], double 0.000000e+00
-; CHECK-NEXT:    ret double [[COND]]
+; CHECK-NEXT:    ret double 0.000000e+00
 ;
   %cmp = fcmp oeq double %x, 0.0
   %cond = select nsz i1 %cmp, double %x, double 0.0
@@ -117,9 +115,7 @@ define double @oeq_zero_nsz(double %x) {
 
 define float @oeq_zero_swapped_nsz(float %x) {
 ; CHECK-LABEL: @oeq_zero_swapped_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[COND:%.*]] = select fast i1 [[CMP]], float 0.000000e+00, float [[X]]
-; CHECK-NEXT:    ret float [[COND]]
+; CHECK-NEXT:    ret float [[X:%.*]]
 ;
   %cmp = fcmp oeq float %x, 0.0
   %cond = select fast i1 %cmp, float 0.0, float %x
@@ -130,9 +126,7 @@ define float @oeq_zero_swapped_nsz(float %x) {
 
 define double @une_zero_nsz(double %x) {
 ; CHECK-LABEL: @une_zero_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[COND:%.*]] = select ninf nsz i1 [[CMP]], double [[X]], double 0.000000e+00
-; CHECK-NEXT:    ret double [[COND]]
+; CHECK-NEXT:    ret double [[X:%.*]]
 ;
   %cmp = fcmp une double %x, 0.0
   %cond = select nsz ninf i1 %cmp, double %x, double 0.0
@@ -143,9 +137,7 @@ define double @une_zero_nsz(double %x) {
 
 define <2 x double> @une_zero_swapped_nsz(<2 x double> %x) {
 ; CHECK-LABEL: @une_zero_swapped_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une <2 x double> [[X:%.*]], zeroinitializer
-; CHECK-NEXT:    [[COND:%.*]] = select nsz <2 x i1> [[CMP]], <2 x double> zeroinitializer, <2 x double> [[X]]
-; CHECK-NEXT:    ret <2 x double> [[COND]]
+; CHECK-NEXT:    ret <2 x double> zeroinitializer
 ;
   %cmp = fcmp une <2 x double> %x, <double 0.0, double 0.0>
   %cond = select nsz <2 x i1> %cmp, <2 x double> <double 0.0, double 0.0>, <2 x double> %x
@@ -156,9 +148,7 @@ define <2 x double> @une_zero_swapped_nsz(<2 x double> %x) {
 
 define double @oeq_nsz(double %x, double %y) {
 ; CHECK-LABEL: @oeq_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[COND:%.*]] = select fast i1 [[CMP]], double [[X]], double [[Y]]
-; CHECK-NEXT:    ret double [[COND]]
+; CHECK-NEXT:    ret double [[Y:%.*]]
 ;
   %cmp = fcmp oeq double %x, %y
   %cond = select fast i1 %cmp, double %x, double %y
@@ -169,9 +159,7 @@ define double @oeq_nsz(double %x, double %y) {
 
 define <2 x float> @oeq_swapped_nsz(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: @oeq_swapped_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq <2 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[COND:%.*]] = select nnan nsz <2 x i1> [[CMP]], <2 x float> [[Y]], <2 x float> [[X]]
-; CHECK-NEXT:    ret <2 x float> [[COND]]
+; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
 ;
   %cmp = fcmp oeq <2 x float> %x, %y
   %cond = select nsz nnan <2 x i1> %cmp, <2 x float> %y, <2 x float> %x
@@ -182,9 +170,7 @@ define <2 x float> @oeq_swapped_nsz(<2 x float> %x, <2 x float> %y) {
 
 define double @une_nsz(double %x, double %y) {
 ; CHECK-LABEL: @une_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[COND:%.*]] = select nsz i1 [[CMP]], double [[X]], double [[Y]]
-; CHECK-NEXT:    ret double [[COND]]
+; CHECK-NEXT:    ret double [[X:%.*]]
 ;
   %cmp = fcmp une double %x, %y
   %cond = select nsz i1 %cmp, double %x, double %y
@@ -195,9 +181,7 @@ define double @une_nsz(double %x, double %y) {
 
 define <2 x double> @une_swapped_nsz(<2 x double> %x, <2 x double> %y) {
 ; CHECK-LABEL: @une_swapped_nsz(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une <2 x double> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[COND:%.*]] = select fast <2 x i1> [[CMP]], <2 x double> [[Y]], <2 x double> [[X]]
-; CHECK-NEXT:    ret <2 x double> [[COND]]
+; CHECK-NEXT:    ret <2 x double> [[Y:%.*]]
 ;
   %cmp = fcmp une <2 x double> %x, %y
   %cond = select fast <2 x i1> %cmp, <2 x double> %y, <2 x double> %x


        


More information about the llvm-commits mailing list