[llvm-commits] [llvm] r42328 - in /llvm/trunk/lib: Support/APFloat.cpp VMCore/ConstantFold.cpp

Dale Johannesen dalej at apple.com
Tue Sep 25 16:07:07 PDT 2007


Author: johannes
Date: Tue Sep 25 18:07:07 2007
New Revision: 42328

URL: http://llvm.org/viewvc/llvm-project?rev=42328&view=rev
Log:
Make APFloat->int conversions deterministic even in
cases with undefined behavior.

Modified:
    llvm/trunk/lib/Support/APFloat.cpp
    llvm/trunk/lib/VMCore/ConstantFold.cpp

Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=42328&r1=42327&r2=42328&view=diff

==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Tue Sep 25 18:07:07 2007
@@ -1399,13 +1399,28 @@
   unsigned int msb, partsCount;
   int bits;
 
-  /* Handle the three special cases first.  */
-  if(category == fcInfinity || category == fcNaN)
-    return opInvalidOp;
-
   partsCount = partCountForBits(width);
 
-  if(category == fcZero) {
+  /* Handle the three special cases first.  We produce
+     a deterministic result even for the Invalid cases. */
+  if (category == fcNaN) {
+    // Neither sign nor isSigned affects this.
+    APInt::tcSet(parts, 0, partsCount);
+    return opInvalidOp;
+  }
+  if (category == fcInfinity) {
+    if (!sign && isSigned)
+      APInt::tcSetLeastSignificantBits(parts, partsCount, width-1);
+    else if (!sign && !isSigned)
+      APInt::tcSetLeastSignificantBits(parts, partsCount, width);
+    else if (sign && isSigned) {
+      APInt::tcSetLeastSignificantBits(parts, partsCount, 1);
+      APInt::tcShiftLeft(parts, partsCount, width-1);
+    } else // sign && !isSigned
+      APInt::tcSet(parts, 0, partsCount);
+    return opInvalidOp;
+  }
+  if (category == fcZero) {
     APInt::tcSet(parts, 0, partsCount);
     return opOK;
   }
@@ -1418,6 +1433,19 @@
   if(bits > 0) {
     lost_fraction = tmp.shiftSignificandRight(bits);
   } else {
+    if (-bits >= semantics->precision) {
+      // Unrepresentably large.
+      if (!sign && isSigned)
+        APInt::tcSetLeastSignificantBits(parts, partsCount, width-1);
+      else if (!sign && !isSigned)
+        APInt::tcSetLeastSignificantBits(parts, partsCount, width);
+      else if (sign && isSigned) {
+        APInt::tcSetLeastSignificantBits(parts, partsCount, 1);
+        APInt::tcShiftLeft(parts, partsCount, width-1);
+      } else // sign && !isSigned
+        APInt::tcSet(parts, 0, partsCount);
+      return (opStatus)(opOverflow | opInexact);
+    }
     tmp.shiftSignificandLeft(-bits);
     lost_fraction = lfExactlyZero;
   }

Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=42328&r1=42327&r2=42328&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Sep 25 18:07:07 2007
@@ -197,8 +197,6 @@
       APFloat::opStatus status = V.convertToInteger(x, DestBitWidth, 
                              opc==Instruction::FPToSI,
                              APFloat::rmTowardZero);
-      if (status!=APFloat::opOK && status!=APFloat::opInexact)
-        return 0; // give up
       APInt Val(DestBitWidth, 2, x);
       return ConstantInt::get(Val);
     }





More information about the llvm-commits mailing list