[PATCH] D31848: [PowerPC] Eliminate compares in instruction selection - Vol. 2

Nemanja Ivanovic via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 10 11:07:06 PDT 2017


nemanjai created this revision.

This revision just adds functions that handle the special case of comparing against zero (both 32-bit and 64-bit).


Repository:
  rL LLVM

https://reviews.llvm.org/D31848

Files:
  lib/Target/PowerPC/PPCISelDAGToDAG.cpp


Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -265,6 +265,10 @@
     SDValue zeroExtendInputIfNeeded(SDValue Input);
     SDValue addExtOrTrunc(SDValue NatWidthRes, bool From32Bit,
                           bool To32Bit);
+    SDValue getSETGE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext);
+    SDValue getSETGE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext);
+    SDValue getSETLE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext);
+    SDValue getSETLE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext);
 
     void PeepholePPC64();
     void PeepholePPC64ZExt();
@@ -2568,6 +2572,65 @@
   return ConvOp;
 }
 
+// Produces a sign/zero extended result of comparing whether a 32-bit value is
+// greater than or equal to zero.
+SDValue PPCDAGToDAGISel::getSETGE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext) {
+  SDValue Not =
+    SDValue(CurDAG->getMachineNode(PPC::NOR, dl, MVT::i32, LHS, LHS), 0);
+  if (IsSext)
+    return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, Not,
+                                          getI32Imm(31, dl)), 0);
+  SDValue ShiftOps[] =
+    { Not, getI32Imm(1, dl), getI32Imm(31, dl), getI32Imm(31, dl) };
+  return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
+                                        ShiftOps), 0);
+}
+
+// Produces a sign/zero extended result of comparing whether a 64-bit value is
+// greater than or equal to zero.
+SDValue PPCDAGToDAGISel::getSETGE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext) {
+  SDValue Not =
+    SDValue(CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, LHS, LHS), 0);
+  if (IsSext)
+    return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Not,
+                                          getI64Imm(31, dl)), 0);
+  return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Not,
+                                        getI64Imm(1, dl), getI64Imm(63, dl)),
+                 0);
+}
+
+// Produces a sign/zero extended result of comparing whether a 32-bit value is
+// less than or equal to zero.
+SDValue PPCDAGToDAGISel::getSETLE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext) {
+  SDValue Neg =
+    SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, LHS), 0);
+  SDValue Srdi =
+    SDValue(CurDAG->getMachineNode(PPC::RLDICL_32, dl, MVT::i32,
+                                   Neg, getI64Imm(1, dl),
+                                   getI64Imm(63, dl)), 0);
+  if (IsSext)
+    return SDValue(CurDAG->getMachineNode(PPC::ADDI, dl, MVT::i32, Srdi,
+                                          getI32Imm(-1, dl)), 0);
+  return SDValue(CurDAG->getMachineNode(PPC::XORI, dl, MVT::i32, Srdi,
+                 getI32Imm(1, dl)), 0);
+}
+
+// Produces a sign/zero extended result of comparing whether a 64-bit value is
+// less than or equal to zero.
+SDValue PPCDAGToDAGISel::getSETLE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext) {
+  SDValue Addi =
+    SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS,
+                                   getI64Imm(~0ULL, dl)), 0);
+  SDValue Or =
+    SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
+                                   Addi, LHS), 0);
+  if (IsSext)
+    return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Or,
+                                          getI64Imm(63, dl)), 0);
+  return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
+                                        Or, getI64Imm(1, dl),
+                                        getI64Imm(63, dl)), 0);
+}
 void PPCDAGToDAGISel::transferMemOperands(SDNode *N, SDNode *Result) {
   // Transfer memoperands.
   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31848.94598.patch
Type: text/x-patch
Size: 3801 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170410/3d82fb99/attachment.bin>


More information about the llvm-commits mailing list