[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