Expand arith on machines without carry flags
authorAndrew Lenharth <andrewl@lenharth.org>
Tue, 7 Oct 2008 14:15:42 +0000 (14:15 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Tue, 7 Oct 2008 14:15:42 +0000 (14:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57243 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
test/CodeGen/Alpha/add128.ll
test/CodeGen/Alpha/sub128.ll [new file with mode: 0644]

index e61cb0c1e5afbb6fb2e9b51c92456cb3b14aa959..59197baeb0cef66e7ad1f1c6221a2a5c19781ed4 100644 (file)
@@ -6431,7 +6431,6 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
         break;
       }
     }
-    
     // Expand the subcomponents.
     SDValue LHSL, LHSH, RHSL, RHSH;
     ExpandOp(Node->getOperand(0), LHSL, LHSH);
@@ -6442,16 +6441,41 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){
     LoOps[1] = RHSL;
     HiOps[0] = LHSH;
     HiOps[1] = RHSH;
-    if (Node->getOpcode() == ISD::ADD) {
-      Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
-      HiOps[2] = Lo.getValue(1);
-      Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+    if(TLI.isOperationLegal(ISD::ADDC, NVT)) {
+      if (Node->getOpcode() == ISD::ADD) {
+        Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+        HiOps[2] = Lo.getValue(1);
+        Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+      } else {
+        Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+        HiOps[2] = Lo.getValue(1);
+        Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+      }
+      break;
     } else {
-      Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
-      HiOps[2] = Lo.getValue(1);
-      Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+      if (Node->getOpcode() == ISD::ADD) {
+        Lo = DAG.getNode(ISD::ADD, VTList, LoOps, 2);
+        Hi = DAG.getNode(ISD::ADD, VTList, HiOps, 2);
+        SDValue Cmp1 = DAG.getSetCC(NVT, Lo, LoOps[0], ISD::SETULT);
+        SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1,
+                                     DAG.getConstant(1, NVT), 
+                                     DAG.getConstant(0, NVT));
+        SDValue Cmp2 = DAG.getSetCC(NVT, Lo, LoOps[1], ISD::SETULT);
+        SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2,
+                                    DAG.getConstant(1, NVT), 
+                                    Carry1);
+        Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2);
+      } else {
+        Lo = DAG.getNode(ISD::SUB, VTList, LoOps, 2);
+        Hi = DAG.getNode(ISD::SUB, VTList, HiOps, 2);
+        SDValue Cmp = DAG.getSetCC(NVT, LoOps[0], LoOps[1], ISD::SETULT);
+        SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp,
+                                     DAG.getConstant(1, NVT), 
+                                     DAG.getConstant(0, NVT));
+        Hi = DAG.getNode(ISD::SUB, NVT, Hi, Borrow);
+      }
+      break;
     }
-    break;
   }
     
   case ISD::ADDC:
index 6432b2d9a847d801b6aff65ce7838a457ae4db65..61d020890e89b6fdeb8d11b4fd8a978237e3c2a8 100644 (file)
@@ -1,7 +1,6 @@
 ;test for ADDC and ADDE expansion
 ;
 ; RUN: llvm-as < %s | llc -march=alpha
-; XFAIL: *
 
 define i128 @add128(i128 %x, i128 %y) {
 entry:
diff --git a/test/CodeGen/Alpha/sub128.ll b/test/CodeGen/Alpha/sub128.ll
new file mode 100644 (file)
index 0000000..cb18559
--- /dev/null
@@ -0,0 +1,9 @@
+;test for SUBC and SUBE expansion
+;
+; RUN: llvm-as < %s | llc -march=alpha
+
+define i128 @sub128(i128 %x, i128 %y) {
+entry:
+       %tmp = sub i128 %y, %x
+       ret i128 %tmp
+}