Add generic expansion of SUB when ADD and XOR
authorDuncan Sands <baldrick@free.fr>
Wed, 6 May 2009 11:29:50 +0000 (11:29 +0000)
committerDuncan Sands <baldrick@free.fr>
Wed, 6 May 2009 11:29:50 +0000 (11:29 +0000)
are legal.  Based on a patch by Micah Villmow.

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

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

index bdcad0a3b5eaf6b49c54a1771088c7df07d968c7..ca5f962a869f10bfc27be6adfa85684306a93fea 100644 (file)
@@ -3268,8 +3268,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
           OpToUse = ISD::UMUL_LOHI;
         }
         if (OpToUse) {
-          Result = SDValue(DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2).getNode(),
-                           0);
+          Result = DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2);
           break;
         }
       }
@@ -3289,16 +3288,21 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
       }
       if (Node->getOpcode() == ISD::SDIV &&
           TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) {
-        Result = SDValue(DAG.getNode(ISD::SDIVREM, dl,
-                                     VTs, Tmp1, Tmp2).getNode(),
-                         0);
+        Result = DAG.getNode(ISD::SDIVREM, dl, VTs, Tmp1, Tmp2);
         break;
       }
       if (Node->getOpcode() == ISD::UDIV &&
           TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) {
-        Result = SDValue(DAG.getNode(ISD::UDIVREM, dl,
-                                     VTs, Tmp1, Tmp2).getNode(),
-                         0);
+        Result = DAG.getNode(ISD::UDIVREM, dl, VTs, Tmp1, Tmp2);
+        break;
+      }
+      if (Node->getOpcode() == ISD::SUB &&
+          TLI.isOperationLegalOrCustom(ISD::ADD, VT) &&
+          TLI.isOperationLegalOrCustom(ISD::XOR, VT)) {
+        Tmp2 = DAG.getNode(ISD::XOR, dl, VT, Tmp2,
+               DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT));
+        Tmp2 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT));
+        Result = DAG.getNode(ISD::ADD, dl, VT, Tmp1, Tmp2);
         break;
       }