[llvm] [GlobalISel][AArch64] Optimize shl, lshr, ashr (PR #213576)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 18:38:39 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Yeongu Choe (YeonguChoe)

<details>
<summary>Changes</summary>

## Summary
Instruction Selection of `shl`, `lshr`, `ashr` had additional assembly code produced which is not used.
Removed the code generation by modifying legalizer.

## Before

- shl

```llvmir
and w8, w1, #<!-- -->0xff
lsl w0, w0, w8
ret
```

- lshr

```llvmir
and w8, w1, #<!-- -->0xff
and w9, w0, #<!-- -->0xff
lsr w0, w9, w8
ret
```

- ashr

```llvmir
sxtb w8, w0
and w9, w1, #<!-- -->0xff
asr w0, w8, w9
ret
```

## After

- shl

```llvmir
lsl	w0, w0, w1
ret
```

- lshr

```llvmir
lsr	w0, w0, w1
ret
```

- ashr

```llvmir
asr	w0, w0, w1
ret
```


---
Full diff: https://github.com/llvm/llvm-project/pull/213576.diff


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp (+1-1) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp (+7-13) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 0c2f3f97ec07d..1e3899aa505a5 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -834,7 +834,7 @@ static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID,
                                unsigned OpSize) {
   switch (RegBankID) {
   case AArch64::GPRRegBankID:
-    if (OpSize == 32) {
+    if (OpSize == 8 || OpSize == 16 || OpSize == 32) {
       switch (GenericOpc) {
       case TargetOpcode::G_SHL:
         return AArch64::LSLVWr;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 94ca171c0b207..e92ea197f7535 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -232,13 +232,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
       .moreElementsToNextPow2(0);
 
   getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR})
-      .customIf([=](const LegalityQuery &Query) {
-        const auto &SrcTy = Query.Types[0];
-        const auto &AmtTy = Query.Types[1];
-        return !SrcTy.isVector() && SrcTy.getSizeInBits() == 32 &&
-               AmtTy.getSizeInBits() == 32;
-      })
       .legalFor({
+          {i8, i8},
+          {i16, i16},
           {i32, i32},
           {i32, i64},
           {i64, i64},
@@ -250,19 +246,17 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
           {v4i32, v4i32},
           {v2i64, v2i64},
       })
-      .widenScalarToNextPow2(1)
       .widenScalarToNextPow2(0)
-      .clampScalar(1, s32, s64)
-      .clampScalar(0, s32, s64)
+      .widenScalarToNextPow2(1)
+      .clampScalar(0, s8, s64)
+      .clampScalar(1, s8, s64)
+      .minScalarSameAs(1, 0)
       .clampNumElements(0, v8s8, v16s8)
       .clampNumElements(0, v4s16, v8s16)
       .clampNumElements(0, v2s32, v4s32)
       .clampNumElements(0, v2s64, v2s64)
       .moreElementsToNextPow2(0)
-      .minScalarSameAs(1, 0)
-      .scalarizeIf(scalarOrEltWiderThan(0, 64), 0)
-      .minScalarEltSameAsIf(isVector(0), 1, 0)
-      .maxScalarEltSameAsIf(isVector(0), 1, 0);
+      .scalarizeIf(scalarOrEltWiderThan(0, 64), 0);
 
   getActionDefinitionsBuilder(G_PTR_ADD)
       .legalFor({{p0, i64}, {v2p0, v2i64}})

``````````

</details>


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


More information about the llvm-commits mailing list