[prev in list] [next in list] [prev in thread] [next in thread] 

List:       llvm-commits
Subject:    [PATCH] D68232: [DAGCombine] Match a greater range of rotate when not all bits are demanded.
From:       Amaury SECHET via Phabricator via llvm-commits <llvm-commits () lists ! llvm ! org>
Date:       2019-09-30 21:42:28
Message-ID: 2be938d221342da38c40361beea6f529 () localhost ! localdomain
[Download RAW message or body]

deadalnix updated this revision to Diff 222500.
deadalnix added a comment.

Rebase on top of NFC changes


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68232/new/

https://reviews.llvm.org/D68232

Files:
  lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  test/CodeGen/X86/rot16.ll


["D68232.222500.patch" (text/x-patch)]

Index: test/CodeGen/X86/rot16.ll
===================================================================
--- test/CodeGen/X86/rot16.ll
+++ test/CodeGen/X86/rot16.ll
@@ -208,21 +208,14 @@
 define i16 @rot16_trunc(i32 %x, i32 %y) nounwind {
 ; X32-LABEL: rot16_trunc:
 ; X32:       # %bb.0:
-; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT:    movl %eax, %ecx
-; X32-NEXT:    shrl $11, %ecx
-; X32-NEXT:    shll $5, %eax
-; X32-NEXT:    orl %ecx, %eax
-; X32-NEXT:    # kill: def $ax killed $ax killed $eax
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    rolw $5, %ax
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: rot16_trunc:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    movl %edi, %ecx
-; X64-NEXT:    shrl $11, %ecx
-; X64-NEXT:    shll $5, %eax
-; X64-NEXT:    orl %ecx, %eax
+; X64-NEXT:    rolw $5, %ax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
 	%t0 = lshr i32 %x, 11
Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -545,6 +545,8 @@
                               unsigned PosOpcode, unsigned NegOpcode,
                               const SDLoc &DL);
     SDValue MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL);
+    SDValue MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL,
+                        const APInt &DemandedBits);
     SDValue MatchLoadCombine(SDNode *N);
     SDValue MatchStoreCombine(StoreSDNode *N);
     SDValue ReduceLoadWidth(SDNode *N);
@@ -6369,10 +6371,16 @@
   return SDValue();
 }
 
+SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
+  return MatchRotate(LHS, RHS, DL,
+                     APInt::getMaxValue(LHS.getValueType().getSizeInBits()));
+}
+
 // MatchRotate - Handle an 'or' of two operands.  If this is one of the many
 // idioms for rotate, and if the target supports rotation instructions, generate
 // a rot[lr].
-SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
+SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL,
+                                 const APInt &DemandedBits) {
   // Must be a legal type.  Expanded 'n promoted things won't work with rotates.
   EVT VT = LHS.getValueType();
   if (!TLI.isTypeLegal(VT))
@@ -6444,21 +6452,41 @@
     std::swap(LHSMask, RHSMask);
   }
 
-  unsigned EltSizeInBits = VT.getScalarSizeInBits();
   SDValue LHSShiftArg = LHSShift.getOperand(0);
   SDValue LHSShiftAmt = LHSShift.getOperand(1);
   SDValue RHSShiftArg = RHSShift.getOperand(0);
   SDValue RHSShiftAmt = RHSShift.getOperand(1);
 
+  EVT RotVT = VT;
+
   // fold (or (shl x, C1), (srl x, C2)) -> (rotl x, C1)
   // fold (or (shl x, C1), (srl x, C2)) -> (rotr x, C2)
-  auto MatchRotateSum = [EltSizeInBits](ConstantSDNode *LHS,
-                                        ConstantSDNode *RHS) {
-    return (LHS->getAPIntValue() + RHS->getAPIntValue()) == EltSizeInBits;
+  auto MatchRotateSum = [this, &DemandedBits, &RotVT](ConstantSDNode *LHS,
+                                                      ConstantSDNode *RHS) {
+    uint64_t RotAmount =
+        (LHS->getAPIntValue() + RHS->getAPIntValue()).getZExtValue();
+    // For vectors, only allow exact match.
+    if (RotVT.isVector())
+      return RotAmount == RotVT.getScalarSizeInBits();
+    // For scalar, check that the type we use for rotation cover all demanded
+    // bits and is legal.
+    APInt RotMask =
+        APInt::getMaxValue(RotAmount).zextOrTrunc(DemandedBits.getBitWidth());
+    if ((DemandedBits & RotMask) != DemandedBits)
+      return false;
+    RotVT = EVT::getIntegerVT(*DAG.getContext(), RotAmount);
+    return TLI.isTypeLegal(RotVT);
   };
   if (ISD::matchBinaryPredicate(LHSShiftAmt, RHSShiftAmt, MatchRotateSum)) {
-    SDValue Rot = DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, DL, VT,
-                              LHSShiftArg, HasROTL ? LHSShiftAmt : RHSShiftAmt);
+    HasROTL = hasOperation(ISD::ROTL, RotVT);
+    HasROTR = hasOperation(ISD::ROTR, RotVT);
+    if (!HasROTL && !HasROTR)
+      return SDValue();
+
+    SDValue Rotated = DAG.getZExtOrTrunc(LHSShiftArg, DL, RotVT);
+    SDValue Rot = DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, DL, RotVT,
+                              Rotated, HasROTL ? LHSShiftAmt : RHSShiftAmt);
+    Rot = DAG.getAnyExtOrTrunc(Rot, DL, VT);
 
     // If there is an AND of either shifted operand, apply it to the result.
     if (LHSMask.getNode() || RHSMask.getNode()) {
@@ -10926,11 +10954,20 @@
   // because targets may prefer a wider type during later combines and invert
   // this transform.
   switch (N0.getOpcode()) {
+  case ISD::OR: {
+    // TODO: This would idealy be part of the SimplifyDemandedBits mechanic, but
+    // there are no way to easily plug it in at the moment, so it is limited to
+    // TRUNC.
+    SDLoc DL(N);
+    if (SDValue Rot = MatchRotate(N0.getOperand(0), N0.getOperand(1), DL,
+                                  APInt::getMaxValue(VT.getSizeInBits())))
+      return DAG.getNode(ISD::TRUNCATE, DL, VT, Rot);
+    LLVM_FALLTHROUGH;
+  }
   case ISD::ADD:
   case ISD::SUB:
   case ISD::MUL:
   case ISD::AND:
-  case ISD::OR:
   case ISD::XOR:
     if (!LegalOperations && N0.hasOneUse() &&
         (isConstantOrConstantVector(N0.getOperand(0), true) ||

[Attachment #4 (text/plain)]

_______________________________________________
llvm-commits mailing list
llvm-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic