[llvm-commits] [llvm] r125748 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Duncan Sands baldrick at free.fr
Thu Feb 17 04:42:48 PST 2011


Author: baldrick
Date: Thu Feb 17 06:42:48 2011
New Revision: 125748

URL: http://llvm.org/viewvc/llvm-project?rev=125748&view=rev
Log:
Fix wrong logic in promotion of signed mul-with-overflow (I pointed this out at
the time but presumably my email got lost).  Examples where the previous logic
got it wrong: (1) a signed i8 multiply of 64 by 2 overflows, but the high part is
zero; (2) a signed i8 multiple of -128 by 2 overflows, but the high part is all
ones. 

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=125748&r1=125747&r2=125748&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Thu Feb 17 06:42:48 2011
@@ -548,16 +548,15 @@
   return Res;
 }
 
-
 SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
   // Promote the overflow bit trivially.
   if (ResNo == 1)
     return PromoteIntRes_Overflow(N);
-  
+
   SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
   DebugLoc DL = N->getDebugLoc();
-  unsigned SmallSize = LHS.getValueType().getSizeInBits();
-  
+  EVT SmallVT = LHS.getValueType();
+
   // To determine if the result overflowed in a larger type, we extend the input
   // to the larger type, do the multiply, then check the high bits of the result
   // to see if the overflow happened.
@@ -568,26 +567,22 @@
     LHS = ZExtPromotedInteger(LHS);
     RHS = ZExtPromotedInteger(RHS);
   }
-  
   SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
-  
-  
-  // For an unsigned overflow, we check to see if the high part is != 0;
+
+  // Overflow occurred iff the high part of the result does not zero/sign-extend
+  // the low part.
   SDValue Overflow;
   if (N->getOpcode() == ISD::UMULO) {
+    // Unsigned overflow occurred iff the high part is non-zero.
     SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
-                             DAG.getIntPtrConstant(SmallSize));
-    // Overflowed if and only if this is not equal to Res.
+                             DAG.getIntPtrConstant(SmallVT.getSizeInBits()));
     Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
                             DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
   } else {
-    // Signed multiply overflowed if the high part is not 0 and not -1.
-    SDValue Hi = DAG.getNode(ISD::SRA, DL, Mul.getValueType(), Mul,
-                             DAG.getIntPtrConstant(SmallSize));
-    Hi = DAG.getNode(ISD::ADD, DL, Hi.getValueType(), Hi,
-                     DAG.getConstant(1, Hi.getValueType()));
-    Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
-                            DAG.getConstant(1, Hi.getValueType()), ISD::SETUGT);
+    // Signed overflow occurred iff the high part does not sign extend the low.
+    SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
+                               Mul, DAG.getValueType(SmallVT));
+    Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
   }
 
   // Use the calculated overflow everywhere.
@@ -595,7 +590,6 @@
   return Mul;
 }
 
-
 SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
   // Zero extend the input.
   SDValue LHS = ZExtPromotedInteger(N->getOperand(0));





More information about the llvm-commits mailing list