[llvm] r203316 - [DAGCombiner] Distribute TRUNC through AND in rotation amount

Adam Nemet anemet at apple.com
Fri Mar 7 15:56:30 PST 2014


Author: anemet
Date: Fri Mar  7 17:56:30 2014
New Revision: 203316

URL: http://llvm.org/viewvc/llvm-project?rev=203316&view=rev
Log:
[DAGCombiner] Distribute TRUNC through AND in rotation amount

This is already done for shifts.  Allow it for rotations as well. E.g.:

   (rotl:i32 x, (trunc (and y, 31))) -> (rotl:i32 x, (and (trunc y), 31))

Use the newly factored-out distributeTruncateThroughAnd.

With this patch and some X86.td tweaks we should be able to remove redundant
masking of the rotation amount like in the example above.  HW implicitly
performs this masking.

The testcase will be added as part of the X86 patch.

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

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=203316&r1=203315&r2=203316&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Mar  7 17:56:30 2014
@@ -229,6 +229,7 @@ namespace {
     SDValue visitSHL(SDNode *N);
     SDValue visitSRA(SDNode *N);
     SDValue visitSRL(SDNode *N);
+    SDValue visitRotate(SDNode *N);
     SDValue visitCTLZ(SDNode *N);
     SDValue visitCTLZ_ZERO_UNDEF(SDNode *N);
     SDValue visitCTTZ(SDNode *N);
@@ -1194,6 +1195,8 @@ SDValue DAGCombiner::visit(SDNode *N) {
   case ISD::SHL:                return visitSHL(N);
   case ISD::SRA:                return visitSRA(N);
   case ISD::SRL:                return visitSRL(N);
+  case ISD::ROTR:
+  case ISD::ROTL:               return visitRotate(N);
   case ISD::CTLZ:               return visitCTLZ(N);
   case ISD::CTLZ_ZERO_UNDEF:    return visitCTLZ_ZERO_UNDEF(N);
   case ISD::CTTZ:               return visitCTTZ(N);
@@ -3899,6 +3902,19 @@ SDValue DAGCombiner::distributeTruncateT
 
   return SDValue();
 }
+
+SDValue DAGCombiner::visitRotate(SDNode *N) {
+  // fold (rot* x, (trunc (and y, c))) -> (rot* x, (and (trunc y), (trunc c))).
+  if (N->getOperand(1).getOpcode() == ISD::TRUNCATE &&
+      N->getOperand(1).getOperand(0).getOpcode() == ISD::AND) {
+    SDValue NewOp1 = distributeTruncateThroughAnd(N->getOperand(1).getNode());
+    if (NewOp1.getNode())
+      return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
+                         N->getOperand(0), NewOp1);
+  }
+  return SDValue();
+}
+
 SDValue DAGCombiner::visitSHL(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   SDValue N1 = N->getOperand(1);





More information about the llvm-commits mailing list