OSDN Git Service

[IR] add optional parameter for copying IR flags to compare instructions
authorSanjay Patel <spatel@rotateright.com>
Wed, 7 Nov 2018 00:00:42 +0000 (00:00 +0000)
committerSanjay Patel <spatel@rotateright.com>
Wed, 7 Nov 2018 00:00:42 +0000 (00:00 +0000)
As shown, this is used to eliminate redundant code in InstCombine,
and there are more cases where we should be using this pattern, but
we're currently unintentionally dropping flags.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346282 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/InstrTypes.h
include/llvm/IR/Instructions.h
lib/IR/Instructions.cpp
lib/Transforms/InstCombine/InstCombineCompares.cpp

index ec782fa..f8d23c7 100644 (file)
@@ -677,7 +677,8 @@ public:
 protected:
   CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred,
           Value *LHS, Value *RHS, const Twine &Name = "",
-          Instruction *InsertBefore = nullptr);
+          Instruction *InsertBefore = nullptr,
+          Instruction *FlagsSource = nullptr);
 
   CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred,
           Value *LHS, Value *RHS, const Twine &Name,
index 449e6e8..7b2c13c 100644 (file)
@@ -1299,12 +1299,13 @@ public:
 
   /// Constructor with no-insertion semantics
   FCmpInst(
-    Predicate pred, ///< The predicate to use for the comparison
+    Predicate Pred, ///< The predicate to use for the comparison
     Value *LHS,     ///< The left-hand-side of the expression
     Value *RHS,     ///< The right-hand-side of the expression
-    const Twine &NameStr = "" ///< Name of the instruction
-  ) : CmpInst(makeCmpResultType(LHS->getType()),
-              Instruction::FCmp, pred, LHS, RHS, NameStr) {
+    const Twine &NameStr = "", ///< Name of the instruction
+    Instruction *FlagsSource = nullptr
+  ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, Pred, LHS,
+              RHS, NameStr, nullptr, FlagsSource) {
     AssertOK();
   }
 
index 3b8d8d0..7d4b6df 100644 (file)
@@ -3149,15 +3149,18 @@ AddrSpaceCastInst::AddrSpaceCastInst(
 //===----------------------------------------------------------------------===//
 
 CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
-                 Value *RHS, const Twine &Name, Instruction *InsertBefore)
+                 Value *RHS, const Twine &Name, Instruction *InsertBefore,
+                 Instruction *FlagsSource)
   : Instruction(ty, op,
                 OperandTraits<CmpInst>::op_begin(this),
                 OperandTraits<CmpInst>::operands(this),
                 InsertBefore) {
-    Op<0>() = LHS;
-    Op<1>() = RHS;
+  Op<0>() = LHS;
+  Op<1>() = RHS;
   setPredicate((Predicate)predicate);
   setName(Name);
+  if (FlagsSource)
+    copyIRFlags(FlagsSource);
 }
 
 CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
index 2381e26..c6dbfd9 100644 (file)
@@ -5281,11 +5281,7 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
   if (C->isNegative())
     Pred = I.getSwappedPredicate();
 
-  // Finally emit the new fcmp.
-  Value *X = LHSI->getOperand(1);
-  FCmpInst *NewFCI = new FCmpInst(Pred, X, RHSC);
-  NewFCI->copyFastMathFlags(&I);
-  return NewFCI;
+  return new FCmpInst(Pred, LHSI->getOperand(1), RHSC, "", &I);
 }
 
 /// Optimize fabs(X) compared with zero.
@@ -5434,43 +5430,34 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
             if (Instruction *Res = foldCmpLoadFromIndexedGlobal(GEP, GV, I))
               return Res;
       break;
-    case Instruction::Call:
-      if (Instruction *X = foldFabsWithFcmpZero(I))
-        return X;
-      break;
   }
   }
 
+  if (Instruction *R = foldFabsWithFcmpZero(I))
+    return R;
+
   Value *X, *Y;
   if (match(Op0, m_FNeg(m_Value(X)))) {
-    if (match(Op1, m_FNeg(m_Value(Y)))) {
-      // fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y
-      Instruction *NewFCmp = new FCmpInst(I.getSwappedPredicate(), X, Y);
-      NewFCmp->copyFastMathFlags(&I);
-      return NewFCmp;
-    }
+    // fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y
+    if (match(Op1, m_FNeg(m_Value(Y))))
+      return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I);
 
+    // fcmp pred (fneg X), C --> fcmp swap(pred) X, -C
     Constant *C;
     if (match(Op1, m_Constant(C))) {
-      // fcmp pred (fneg X), C --> fcmp swap(pred) X, -C
       Constant *NegC = ConstantExpr::getFNeg(C);
-      Instruction *NewFCmp = new FCmpInst(I.getSwappedPredicate(), X, NegC);
-      NewFCmp->copyFastMathFlags(&I);
-      return NewFCmp;
+      return new FCmpInst(I.getSwappedPredicate(), X, NegC, "", &I);
     }
   }
 
   if (match(Op0, m_FPExt(m_Value(X)))) {
-    if (match(Op1, m_FPExt(m_Value(Y))) && X->getType() == Y->getType()) {
-      // fcmp (fpext X), (fpext Y) -> fcmp X, Y
-      Instruction *NewFCmp = new FCmpInst(Pred, X, Y);
-      NewFCmp->copyFastMathFlags(&I);
-      return NewFCmp;
-    }
+    // fcmp (fpext X), (fpext Y) -> fcmp X, Y
+    if (match(Op1, m_FPExt(m_Value(Y))) && X->getType() == Y->getType())
+      return new FCmpInst(Pred, X, Y, "", &I);
 
+    // fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless
     const APFloat *C;
     if (match(Op1, m_APFloat(C))) {
-      // fcmp (fpext X), C -> fcmp X, (fptrunc C) if fptrunc is lossless
       const fltSemantics &FPSem =
           X->getType()->getScalarType()->getFltSemantics();
       bool Lossy;
@@ -5485,9 +5472,7 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
           ((Fabs.compare(APFloat::getSmallestNormalized(FPSem)) !=
             APFloat::cmpLessThan) || Fabs.isZero())) {
         Constant *NewC = ConstantFP::get(X->getType(), TruncC);
-        Instruction *NewFCmp = new FCmpInst(Pred, X, NewC);
-        NewFCmp->copyFastMathFlags(&I);
-        return NewFCmp;
+        return new FCmpInst(Pred, X, NewC, "", &I);
       }
     }
   }