[llvm] r272199 - [InstCombine] move fold of select of add/sub to helper function; NFCI

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 8 14:10:02 PDT 2016


Author: spatel
Date: Wed Jun  8 16:10:01 2016
New Revision: 272199

URL: http://llvm.org/viewvc/llvm-project?rev=272199&view=rev
Log:
[InstCombine] move fold of select of add/sub to helper function; NFCI

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=272199&r1=272198&r2=272199&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Wed Jun  8 16:10:01 2016
@@ -813,6 +813,78 @@ static Value *foldSelectICmpAnd(const Se
   return V;
 }
 
+/// Turn select C, (X + Y), (X - Y) --> (X + (select C, Y, (-Y))).
+/// This is even legal for FP.
+static Instruction *foldAddSubSelect(SelectInst &SI,
+                                     InstCombiner::BuilderTy &Builder) {
+  Value *CondVal = SI.getCondition();
+  Value *TrueVal = SI.getTrueValue();
+  Value *FalseVal = SI.getFalseValue();
+  auto *TI = dyn_cast<Instruction>(TrueVal);
+  auto *FI = dyn_cast<Instruction>(FalseVal);
+  if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
+    return nullptr;
+
+  Instruction *AddOp = nullptr, *SubOp = nullptr;
+  if ((TI->getOpcode() == Instruction::Sub &&
+       FI->getOpcode() == Instruction::Add) ||
+      (TI->getOpcode() == Instruction::FSub &&
+       FI->getOpcode() == Instruction::FAdd)) {
+    AddOp = FI;
+    SubOp = TI;
+  } else if ((FI->getOpcode() == Instruction::Sub &&
+              TI->getOpcode() == Instruction::Add) ||
+             (FI->getOpcode() == Instruction::FSub &&
+              TI->getOpcode() == Instruction::FAdd)) {
+    AddOp = TI;
+    SubOp = FI;
+  }
+
+  if (AddOp) {
+    Value *OtherAddOp = nullptr;
+    if (SubOp->getOperand(0) == AddOp->getOperand(0)) {
+      OtherAddOp = AddOp->getOperand(1);
+    } else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {
+      OtherAddOp = AddOp->getOperand(0);
+    }
+
+    if (OtherAddOp) {
+      // So at this point we know we have (Y -> OtherAddOp):
+      //        select C, (add X, Y), (sub X, Z)
+      Value *NegVal; // Compute -Z
+      if (SI.getType()->isFPOrFPVectorTy()) {
+        NegVal = Builder.CreateFNeg(SubOp->getOperand(1));
+        if (Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
+          FastMathFlags Flags = AddOp->getFastMathFlags();
+          Flags &= SubOp->getFastMathFlags();
+          NegInst->setFastMathFlags(Flags);
+        }
+      } else {
+        NegVal = Builder.CreateNeg(SubOp->getOperand(1));
+      }
+
+      Value *NewTrueOp = OtherAddOp;
+      Value *NewFalseOp = NegVal;
+      if (AddOp != TI)
+        std::swap(NewTrueOp, NewFalseOp);
+      Value *NewSel = Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
+                                           SI.getName() + ".p");
+
+      if (SI.getType()->isFPOrFPVectorTy()) {
+        Instruction *RI =
+            BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
+
+        FastMathFlags Flags = AddOp->getFastMathFlags();
+        Flags &= SubOp->getFastMathFlags();
+        RI->setFastMathFlags(Flags);
+        return RI;
+      } else
+        return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
+    }
+  }
+  return nullptr;
+}
+
 Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
   Value *CondVal = SI.getCondition();
   Value *TrueVal = SI.getTrueValue();
@@ -981,74 +1053,16 @@ Instruction *InstCombiner::visitSelectIn
     if (Instruction *Result = visitSelectInstWithICmp(SI, ICI))
       return Result;
 
+  if (Instruction *Add = foldAddSubSelect(SI, *Builder))
+    return Add;
+
   auto *TI = dyn_cast<Instruction>(TrueVal);
   auto *FI = dyn_cast<Instruction>(FalseVal);
   if (TI && FI && TI->hasOneUse() && FI->hasOneUse()) {
-    Instruction *AddOp = nullptr, *SubOp = nullptr;
-
     // Turn (select C, (op X, Y), (op X, Z)) -> (op X, (select C, Y, Z))
     if (TI->getOpcode() == FI->getOpcode())
       if (Instruction *IV = FoldSelectOpOp(SI, TI, FI))
         return IV;
-
-    // Turn select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y))).  This is
-    // even legal for FP.
-    if ((TI->getOpcode() == Instruction::Sub &&
-         FI->getOpcode() == Instruction::Add) ||
-        (TI->getOpcode() == Instruction::FSub &&
-         FI->getOpcode() == Instruction::FAdd)) {
-      AddOp = FI;
-      SubOp = TI;
-    } else if ((FI->getOpcode() == Instruction::Sub &&
-                TI->getOpcode() == Instruction::Add) ||
-               (FI->getOpcode() == Instruction::FSub &&
-                TI->getOpcode() == Instruction::FAdd)) {
-      AddOp = TI;
-      SubOp = FI;
-    }
-
-    if (AddOp) {
-      Value *OtherAddOp = nullptr;
-      if (SubOp->getOperand(0) == AddOp->getOperand(0)) {
-        OtherAddOp = AddOp->getOperand(1);
-      } else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {
-        OtherAddOp = AddOp->getOperand(0);
-      }
-
-      if (OtherAddOp) {
-        // So at this point we know we have (Y -> OtherAddOp):
-        //        select C, (add X, Y), (sub X, Z)
-        Value *NegVal; // Compute -Z
-        if (SI.getType()->isFPOrFPVectorTy()) {
-          NegVal = Builder->CreateFNeg(SubOp->getOperand(1));
-          if (Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
-            FastMathFlags Flags = AddOp->getFastMathFlags();
-            Flags &= SubOp->getFastMathFlags();
-            NegInst->setFastMathFlags(Flags);
-          }
-        } else {
-          NegVal = Builder->CreateNeg(SubOp->getOperand(1));
-        }
-
-        Value *NewTrueOp = OtherAddOp;
-        Value *NewFalseOp = NegVal;
-        if (AddOp != TI)
-          std::swap(NewTrueOp, NewFalseOp);
-        Value *NewSel = Builder->CreateSelect(CondVal, NewTrueOp, NewFalseOp,
-                                              SI.getName() + ".p");
-
-        if (SI.getType()->isFPOrFPVectorTy()) {
-          Instruction *RI =
-              BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
-
-          FastMathFlags Flags = AddOp->getFastMathFlags();
-          Flags &= SubOp->getFastMathFlags();
-          RI->setFastMathFlags(Flags);
-          return RI;
-        } else
-          return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
-      }
-    }
   }
 
   // See if we can fold the select into one of our operands.




More information about the llvm-commits mailing list