[llvm] [RISCV] Optimize (slli (srli (slli X, C1), C1), C2) -> (srli (slli X, C1), C1-C2) (PR #119567)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 11 10:41:56 PST 2024


================
@@ -1041,6 +1041,21 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
             CurDAG->getTargetConstant(TrailingZeros + ShAmt, DL, VT));
         ReplaceNode(Node, SLLI);
         return;
+      } else if (TrailingZeros == 0 && LeadingZeros > ShAmt &&
+                 XLen - LeadingZeros > 11 && LeadingZeros != 32) {
+        // Optimize (shl (and X, C2), C) -> (srli (slli X, C4), C4-C)
+        // where C2 has C4 leading zeros and no trailing zeros.
+        // This is profitable if the "and" was to be lowered to
+        // (srli (slli X, C4), C4) and not (andi X, C2).
+        // For "LeadingZeros == 32" we prefer Zba (slli.uw X, C).
----------------
topperc wrote:

It's done with this tablegen pattern in RISCVInstrInfo.td

```
// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2       
// shifts instead of 3. This can occur when unsigned is used to index an array.  
def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),                  
          (SRLI (i64 (SLLI GPR:$rs1, 32)), (ImmSubFrom32 uimm5:$shamt))>;        
} 
```

https://github.com/llvm/llvm-project/pull/119567


More information about the llvm-commits mailing list