Consider expression "0.0 - X" as the negation of X if
authorShuxin Yang <shuxin.llvm@gmail.com>
Wed, 9 Jan 2013 00:13:41 +0000 (00:13 +0000)
committerShuxin Yang <shuxin.llvm@gmail.com>
Wed, 9 Jan 2013 00:13:41 +0000 (00:13 +0000)
  - this expression is explicitly marked no-signed-zero, or
  - no-signed-zero of this expression can be derived from some context.

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

include/llvm/IR/Constant.h
include/llvm/IR/InstrTypes.h
lib/IR/Constants.cpp
lib/IR/Instructions.cpp
lib/Transforms/InstCombine/InstCombine.h
lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/fast-math.ll

index 36a4538e86cbe80a65772f5c125a50d1e09ac851..5a3ba28447328be19a352fab24f55c6492583227 100644 (file)
@@ -61,6 +61,9 @@ public:
   /// by getZeroValueForNegation.
   bool isNegativeZeroValue() const;
 
+  /// Return true if the value is negative zero or null value.
+  bool isZeroValue() const;
+
   /// canTrap - Return true if evaluation of this constant could trap.  This is
   /// true for things like constant expressions that could divide by zero.
   bool canTrap() const;
index 66bf8dde979054dd1ccb35dfefe5b17e8751fe25..7ee5cdb3223d05f2153456caa11ff2781342ac58 100644 (file)
@@ -309,7 +309,7 @@ public:
   /// NEG, FNeg, or NOT instruction.
   ///
   static bool isNeg(const Value *V);
-  static bool isFNeg(const Value *V);
+  static bool isFNeg(const Value *V, bool IgnoreZeroSign=false);
   static bool isNot(const Value *V);
 
   /// getNegArgument, getNotArgument - Helper functions to extract the
index 4b5859995548de8576a4af2eda12454b190332c1..812692f3fae9680a22e2df64b61be257c1d537a1 100644 (file)
@@ -51,6 +51,15 @@ bool Constant::isNegativeZeroValue() const {
   return isNullValue();
 }
 
+bool Constant::isZeroValue() const {
+  // Floating point values have an explicit -0.0 value.
+  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
+    return CFP->isZero();
+
+  // Otherwise, just use +0.0.
+  return isNullValue();
+}
+
 bool Constant::isNullValue() const {
   // 0 is null.
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
index 1b5d004978c59b0aec452ea65eb1050853f93195..f2e9813bc638848e0245a2731239ff3ed4717eee 100644 (file)
@@ -1926,11 +1926,14 @@ bool BinaryOperator::isNeg(const Value *V) {
   return false;
 }
 
-bool BinaryOperator::isFNeg(const Value *V) {
+bool BinaryOperator::isFNeg(const Value *V, bool IgnoreZeroSign) {
   if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
     if (Bop->getOpcode() == Instruction::FSub)
-      if (Constant* C = dyn_cast<Constant>(Bop->getOperand(0)))
-        return C->isNegativeZeroValue();
+      if (Constant* C = dyn_cast<Constant>(Bop->getOperand(0))) {
+        if (!IgnoreZeroSign)
+          IgnoreZeroSign = cast<Instruction>(V)->hasNoSignedZeros();
+        return !IgnoreZeroSign ? C->isNegativeZeroValue() : C->isZeroValue();
+      }
   return false;
 }
 
index 959daa258d8a750d01485d87f629c5209e98ee23..a36b1e6b9e5dae09a94eb5a2525f56ade01d9252 100644 (file)
@@ -211,7 +211,7 @@ public:
 private:
   bool ShouldChangeType(Type *From, Type *To) const;
   Value *dyn_castNegVal(Value *V) const;
-  Value *dyn_castFNegVal(Value *V) const;
+  Value *dyn_castFNegVal(Value *V, bool NoSignedZero=false) const;
   Type *FindElementAtOffset(Type *Ty, int64_t Offset, 
                                   SmallVectorImpl<Value*> &NewIndices);
   Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
index 6f24cdd738c37eddc325605329522df64a868aa0..dc7fe5cf6b5bfe68324b923dcb6fee8c3e3ee8b8 100644 (file)
@@ -516,8 +516,8 @@ Value *InstCombiner::dyn_castNegVal(Value *V) const {
 // instruction if the LHS is a constant negative zero (which is the 'negate'
 // form).
 //
-Value *InstCombiner::dyn_castFNegVal(Value *V) const {
-  if (BinaryOperator::isFNeg(V))
+Value *InstCombiner::dyn_castFNegVal(Value *V, bool IgnoreZeroSign) const {
+  if (BinaryOperator::isFNeg(V, IgnoreZeroSign))
     return BinaryOperator::getFNegArgument(V);
 
   // Constants can be considered to be negated values if they can be folded.
index 5d40d71f8752f2d922fe52730fd2e9a5150deed1..df0455a2032b1c514a8e83a4947b07d2ff51bfe6 100644 (file)
@@ -243,5 +243,16 @@ define float @fmul5(float %f1, float %f2) {
 ; CHECK: fdiv fast float %f1, 0x47E8000000000000
 }
 
-
-
+; =========================================================================
+;
+;   Testing-cases about negation
+;
+; =========================================================================
+define float @fneg1(float %f1, float %f2) {
+  %sub = fsub float -0.000000e+00, %f1
+  %sub1 = fsub nsz float 0.000000e+00, %f2
+  %mul = fmul float %sub, %sub1
+  ret float %mul
+; CHECK: @fneg1
+; CHECK: fmul float %f1, %f2
+}