Fix constant fold of div by zero and rem by zero to match IEEE 754
authorReid Spencer <rspencer@reidspencer.com>
Fri, 23 Mar 2007 05:33:23 +0000 (05:33 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Fri, 23 Mar 2007 05:33:23 +0000 (05:33 +0000)
requirements. We must return NaN in some cases and correctly signed
infinity in other cases. Passes CFP2006 (not that that says much).

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

lib/VMCore/ConstantFold.cpp

index 05a75883a1a30e9a7a76cdf89c22a93ed2f7ceb3..d7e51956e4d274031f77253b75037d5c03745f69 100644 (file)
@@ -651,17 +651,27 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
       case Instruction::Mul:     
         return ConstantFP::get(CFP1->getType(), C1Val * C2Val);
       case Instruction::FDiv:
-        if (CFP2->isExactlyValue(0.0)) 
-          return ConstantFP::get(CFP1->getType(),
-                                 std::numeric_limits<double>::infinity());
-        if (CFP2->isExactlyValue(-0.0))
-          return ConstantFP::get(CFP1->getType(),
-                                 -std::numeric_limits<double>::infinity());
+        if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
+          if (CFP1->isExactlyValue(0.0) || CFP1->isExactlyValue(-0.0))
+            // IEEE 754, Section 7.1, #4
+            return ConstantFP::get(CFP1->getType(),
+                                   std::numeric_limits<double>::quiet_NaN());
+          else if (CFP2->isExactlyValue(-0.0) || C1Val < 0.0)
+            // IEEE 754, Section 7.2, negative infinity case
+            return ConstantFP::get(CFP1->getType(),
+                                   -std::numeric_limits<double>::infinity());
+          else
+            // IEEE 754, Section 7.2, positive infinity case
+            return ConstantFP::get(CFP1->getType(),
+                                   std::numeric_limits<double>::infinity());
         return ConstantFP::get(CFP1->getType(), C1Val / C2Val);
       case Instruction::FRem:
-        if (CFP2->isNullValue()) 
-          return 0;
+        if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
+          // IEEE 754, Section 7.1, #5
+          return ConstantFP::get(CFP1->getType(), 
+                                 std::numeric_limits<double>::quiet_NaN());
         return ConstantFP::get(CFP1->getType(), std::fmod(C1Val, C2Val));
+
       }
     }
   } else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {