[llvm-commits] [llvm] r123908 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h test/CodeGen/X86/umulo-64.ll

Eric Christopher echristo at apple.com
Thu Jan 20 00:54:29 PST 2011


Author: echristo
Date: Thu Jan 20 02:54:28 2011
New Revision: 123908

URL: http://llvm.org/viewvc/llvm-project?rev=123908&view=rev
Log:
Expand invalid return values for umulo and smulo. Handle these similarly
to add/sub by doing the normal operation and then checking for overflow
afterwards. This generally relies on the DAG handling the later invalid
operations as well.

Fixes the 64-bit part of rdar://8622122 and rdar://8774702.

Added:
    llvm/trunk/test/CodeGen/X86/umulo-64.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=123908&r1=123907&r2=123908&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Thu Jan 20 02:54:28 2011
@@ -1057,6 +1057,8 @@
   case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break;
   case ISD::UADDO:
   case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break;
+  case ISD::UMULO:
+  case ISD::SMULO: ExpandIntRes_UMULSMULO(N, Lo, Hi); break;
   }
 
   // If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -2132,6 +2134,31 @@
   ReplaceValueWith(SDValue(N, 1), Ofl);
 }
 
+void DAGTypeLegalizer::ExpandIntRes_UMULSMULO(SDNode *N,
+                                              SDValue &Lo, SDValue &Hi) {
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
+  DebugLoc dl = N->getDebugLoc();
+  EVT VT = N->getValueType(0);
+  EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() / 2);
+  // Expand the result by simply replacing it with the equivalent
+  // non-overflow-checking operation.
+  SDValue Ret = DAG.getNode(ISD::MUL, dl, LHS.getValueType(), LHS, RHS);
+  SplitInteger(Ret, Lo, Hi);
+  
+  // Now calculate overflow.
+  SDValue Ofl;
+  if (N->getOpcode() == ISD::UMULO)
+    Ofl = DAG.getSetCC(dl, N->getValueType(1), Hi,
+                       DAG.getConstant(0, VT), ISD::SETNE);
+  else {
+    SDValue Tmp = DAG.getConstant(VT.getSizeInBits() - 1, HalfVT);
+    Tmp = DAG.getNode(ISD::SRA, dl, HalfVT, Lo, Tmp);
+    Ofl = DAG.getSetCC(dl, N->getValueType(1), Hi, Tmp, ISD::SETNE);
+  }
+  ReplaceValueWith(SDValue(N, 1), Ofl);
+}
+
 void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
                                          SDValue &Lo, SDValue &Hi) {
   EVT VT = N->getValueType(0);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=123908&r1=123907&r2=123908&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Thu Jan 20 02:54:28 2011
@@ -348,6 +348,7 @@
 
   void ExpandIntRes_SADDSUBO          (SDNode *N, SDValue &Lo, SDValue &Hi);
   void ExpandIntRes_UADDSUBO          (SDNode *N, SDValue &Lo, SDValue &Hi);
+	void ExpandIntRes_UMULSMULO					(SDNode *N, SDValue &Lo, SDValue &Hi);
 
   void ExpandShiftByConstant(SDNode *N, unsigned Amt,
                              SDValue &Lo, SDValue &Hi);

Added: llvm/trunk/test/CodeGen/X86/umulo-64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/umulo-64.ll?rev=123908&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/umulo-64.ll (added)
+++ llvm/trunk/test/CodeGen/X86/umulo-64.ll Thu Jan 20 02:54:28 2011
@@ -0,0 +1,28 @@
+; RUN: llc < %s -mtriple=i386-apple-darwin
+
+%0 = type { i64, i1 }
+
+define i32 @f0(i64 %a, i64 %b) nounwind ssp {
+  %1 = alloca i64, align 4
+  %2 = alloca i64, align 4
+  store i64 %a, i64* %1, align 8
+  store i64 %b, i64* %2, align 8
+  %3 = load i64* %1, align 8
+  %4 = load i64* %2, align 8
+  %5 = call %0 @llvm.smul.with.overflow.i64(i64 %3, i64 %4)
+  %6 = extractvalue %0 %5, 0
+  %7 = extractvalue %0 %5, 1
+  br i1 %7, label %8, label %9
+
+; <label>:8                                       ; preds = %0
+  call void @llvm.trap()
+  unreachable
+
+; <label>:9                                       ; preds = %0
+  %10 = trunc i64 %6 to i32
+  ret i32 %10
+}
+
+declare %0 @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
+
+declare void @llvm.trap() nounwind





More information about the llvm-commits mailing list