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

Yeongu Choe via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 18:37:53 PDT 2026


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

## 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
```


>From fe9034b12e5ac8108b494d157f960469109c51cd Mon Sep 17 00:00:00 2001
From: Yeongu Choe <yeongu.choe at icloud.com>
Date: Mon, 3 Aug 2026 01:11:52 +0000
Subject: [PATCH] [GlobalISel][ARM64] Optimize shl, lshr, ashr Instruction
 Selection

Update the legalizer based on the new ARM64 ISA.
Optimize by removing unnecessary zero extensions.
---
 .../GISel/AArch64InstructionSelector.cpp      |  2 +-
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    | 20 +++++++------------
 2 files changed, 8 insertions(+), 14 deletions(-)

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}})



More information about the llvm-commits mailing list