[llvm] [GlobalISel] [AArch64] Skip redundant shift amount masking during isel (PR #223136)
Deepak Shirke via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 10:02:15 PDT 2026
https://github.com/deepakshirkem updated https://github.com/llvm/llvm-project/pull/223136
>From f58ddaf234713e03a6aa89949aa86b8cb4ac60bf Mon Sep 17 00:00:00 2001
From: deepakshirkem <deepakshirke509 at gmail.com>
Date: Sun, 13 Sep 2026 16:35:36 +0530
Subject: [PATCH] AArch64/GlobalISel: Skip redundant shift amount masking in
post-legalizer combiner
AArch64 shift instructions (LSL/LSR/ASR) only use the low 5 bits (i32)
or 6 bits (i64) of the shift amount. When the shift amount is masked with
an AND that was introduced by legalization of a narrow type zext (i.e.
mask is exactly 0xff or 0xffff), the AND is redundant and can be removed.
This is implemented as a post-legalizer combiner rule, mirroring what
AArch64DAGToDAGISel::tryShiftAmountMod does for SelectionDAG0.
---
llvm/lib/Target/AArch64/AArch64Combine.td | 9 +-
.../GISel/AArch64PostLegalizerCombiner.cpp | 37 +++++++
.../AArch64/GlobalISel/shift-amount-mod.ll | 63 ++++++++++++
...st-and-by-const-from-lshr-in-eqcmp-zero.ll | 47 +++------
...ist-and-by-const-from-shl-in-eqcmp-zero.ll | 24 ++---
llvm/test/CodeGen/AArch64/select_const.ll | 3 -
llvm/test/CodeGen/AArch64/shift.ll | 96 ++++++-------------
7 files changed, 159 insertions(+), 120 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 7a8083e3ceb44..f2b91b4acf53f 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -264,6 +264,13 @@ def mul_const : GICombineRule<
(apply [{ applyAArch64MulConstCombine(*${root}, MRI, B, ${matchinfo}); }])
>;
+def shift_amount_mask_matchdata : GIDefMatchData<"Register">;
+def shift_amount_mask : GICombineRule<
+ (defs root:$root, shift_amount_mask_matchdata:$matchinfo),
+ (match (wip_match_opcode G_SHL, G_LSHR, G_ASHR):$root,
+ [{ return matchShiftAmountMask(*${root}, MRI, ${matchinfo}); }]),
+ (apply [{ applyShiftAmountMask(*${root}, MRI, Observer, ${matchinfo}); }])>;
+
def mull_matchdata : GIDefMatchData<"std::tuple<bool, Register, Register>">;
def extmultomull : GICombineRule<
(defs root:$root, mull_matchdata:$matchinfo),
@@ -404,7 +411,7 @@ def AArch64PostLegalizerCombiner
hoist_logic_op_with_same_opcode_hands,
redundant_and, xor_of_and_with_same_reg,
extractvecelt_pairwise_add, redundant_or,
- mul_const, redundant_sext_inreg,
+ mul_const, shift_amount_mask, redundant_sext_inreg,
redundant_zext_sext_inreg, redundant_aext_sext_inreg,
redundant_aext_unmerge_sext_inreg, redundant_zext_unmerge_sext_inreg,
form_bitfield_extract, rotate_out_of_range,
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
index 6ba25ac4ffa0a..736b618af3d69 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
@@ -257,6 +257,43 @@ void applyAArch64MulConstCombine(
MI.eraseFromParent();
}
+/// Skip redundant AND on shift amounts. AArch64 shift instructions only
+/// use the low 5 bits (i32) or 6 bits (i64) of the shift amount, so an
+/// AND that masks to exactly a byte or halfword is redundant.
+bool matchShiftAmountMask(MachineInstr &MI, MachineRegisterInfo &MRI,
+ Register &NewShiftReg) {
+ assert(MI.getOpcode() == TargetOpcode::G_SHL ||
+ MI.getOpcode() == TargetOpcode::G_LSHR ||
+ MI.getOpcode() == TargetOpcode::G_ASHR);
+
+ LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
+ if (SrcTy.isVector())
+ return false;
+
+ Register ShiftReg = MI.getOperand(2).getReg();
+ int64_t MaskImm;
+ Register MaskSrc;
+
+ if (!mi_match(ShiftReg, MRI,
+ m_OneNonDBGUse(m_GAnd(m_Reg(MaskSrc), m_ICst(MaskImm)))))
+ return false;
+
+ uint64_t UMask = (uint64_t)MaskImm;
+ if (UMask != 0xff && UMask != 0xffff)
+ return false;
+
+ NewShiftReg = MaskSrc;
+ return true;
+}
+
+void applyShiftAmountMask(MachineInstr &MI, MachineRegisterInfo &MRI,
+ GISelChangeObserver &Observer,
+ Register &NewShiftReg) {
+ Observer.changingInstr(MI);
+ MI.getOperand(2).setReg(NewShiftReg);
+ Observer.changedInstr(MI);
+}
+
/// Try to fold a G_MERGE_VALUES of 2 s32 sources, where the second source
/// is a zero, into a G_ZEXT of the first.
bool matchFoldMergeToZext(MachineInstr &MI, MachineRegisterInfo &MRI) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll b/llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll
new file mode 100644
index 0000000000000..174f4e14960d4
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll
@@ -0,0 +1,63 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -global-isel -mtriple=aarch64 < %s | FileCheck %s --check-prefix=GI
+; RUN: llc -global-isel=0 -mtriple=aarch64 < %s | FileCheck %s --check-prefix=SD
+
+define i32 @shl_i32_i8(i32 %x, i8 %amt) {
+; GI-LABEL: shl_i32_i8:
+; GI: // %bb.0:
+; GI-NEXT: lsl w0, w0, w1
+; GI-NEXT: ret
+;
+; SD-LABEL: shl_i32_i8:
+; SD: // %bb.0:
+; SD-NEXT: lsl w0, w0, w1
+; SD-NEXT: ret
+ %ext = zext i8 %amt to i32
+ %r = shl i32 %x, %ext
+ ret i32 %r
+}
+
+define i32 @lshr_i32_i8(i32 %x, i8 %amt) {
+; GI-LABEL: lshr_i32_i8:
+; GI: // %bb.0:
+; GI-NEXT: lsr w0, w0, w1
+; GI-NEXT: ret
+;
+; SD-LABEL: lshr_i32_i8:
+; SD: // %bb.0:
+; SD-NEXT: lsr w0, w0, w1
+; SD-NEXT: ret
+ %ext = zext i8 %amt to i32
+ %r = lshr i32 %x, %ext
+ ret i32 %r
+}
+
+define i32 @ashr_i32_i8(i32 %x, i8 %amt) {
+; GI-LABEL: ashr_i32_i8:
+; GI: // %bb.0:
+; GI-NEXT: asr w0, w0, w1
+; GI-NEXT: ret
+;
+; SD-LABEL: ashr_i32_i8:
+; SD: // %bb.0:
+; SD-NEXT: asr w0, w0, w1
+; SD-NEXT: ret
+ %ext = zext i8 %amt to i32
+ %r = ashr i32 %x, %ext
+ ret i32 %r
+}
+
+define i32 @shl_i32_i16(i32 %x, i16 %amt) {
+; GI-LABEL: shl_i32_i16:
+; GI: // %bb.0:
+; GI-NEXT: lsl w0, w0, w1
+; GI-NEXT: ret
+;
+; SD-LABEL: shl_i32_i16:
+; SD: // %bb.0:
+; SD-NEXT: lsl w0, w0, w1
+; SD-NEXT: ret
+ %ext = zext i16 %amt to i32
+ %r = shl i32 %x, %ext
+ ret i32 %r
+}
diff --git a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll
index 7d8ff9ac11e30..78efedb0c9317 100644
--- a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll
+++ b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll
@@ -24,8 +24,7 @@ define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_signbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #128 // =0x80
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, eq
; CHECK-GI-NEXT: ret
@@ -46,8 +45,7 @@ define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_lowestbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, eq
; CHECK-GI-NEXT: ret
@@ -68,8 +66,7 @@ define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_bitsinmiddle_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #24 // =0x18
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, eq
; CHECK-GI-NEXT: ret
@@ -92,8 +89,7 @@ define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
; CHECK-GI-LABEL: scalar_i16_signbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #32768 // =0x8000
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, eq
; CHECK-GI-NEXT: ret
@@ -114,8 +110,7 @@ define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
; CHECK-GI-LABEL: scalar_i16_lowestbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, eq
; CHECK-GI-NEXT: ret
@@ -136,8 +131,7 @@ define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
; CHECK-GI-LABEL: scalar_i16_bitsinmiddle_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #4080 // =0xff0
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, eq
; CHECK-GI-NEXT: ret
@@ -425,8 +419,7 @@ define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_signbit_ne:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #128 // =0x80
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsr w8, w8, w9
+; CHECK-GI-NEXT: lsr w8, w8, w1
; CHECK-GI-NEXT: tst w8, w0
; CHECK-GI-NEXT: cset w0, ne
; CHECK-GI-NEXT: ret
@@ -480,24 +473,14 @@ define i1 @scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
}
define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
-; CHECK-SD-LABEL: scalar_i8_signbit_eq_with_nonzero:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: mov w8, #128 // =0x80
-; CHECK-SD-NEXT: lsr w8, w8, w1
-; CHECK-SD-NEXT: and w8, w8, w0
-; CHECK-SD-NEXT: cmp w8, #1
-; CHECK-SD-NEXT: cset w0, eq
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: scalar_i8_signbit_eq_with_nonzero:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #128 // =0x80
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsr w8, w8, w9
-; CHECK-GI-NEXT: and w8, w8, w0
-; CHECK-GI-NEXT: cmp w8, #1
-; CHECK-GI-NEXT: cset w0, eq
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: scalar_i8_signbit_eq_with_nonzero:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov w8, #128 // =0x80
+; CHECK-NEXT: lsr w8, w8, w1
+; CHECK-NEXT: and w8, w8, w0
+; CHECK-NEXT: cmp w8, #1
+; CHECK-NEXT: cset w0, eq
+; CHECK-NEXT: ret
%t0 = lshr i8 128, %y
%t1 = and i8 %t0, %x
%res = icmp eq i8 %t1, 1 ; should be comparing with 0
diff --git a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll
index f61e4303ca2be..b55efeb580ee7 100644
--- a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll
+++ b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll
@@ -25,8 +25,7 @@ define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_signbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #-128 // =0xffffff80
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xff
; CHECK-GI-NEXT: cset w0, eq
@@ -49,8 +48,7 @@ define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_lowestbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xff
; CHECK-GI-NEXT: cset w0, eq
@@ -73,8 +71,7 @@ define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_bitsinmiddle_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #24 // =0x18
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xff
; CHECK-GI-NEXT: cset w0, eq
@@ -99,8 +96,7 @@ define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
; CHECK-GI-LABEL: scalar_i16_signbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #-32768 // =0xffff8000
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xffff
; CHECK-GI-NEXT: cset w0, eq
@@ -123,8 +119,7 @@ define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
; CHECK-GI-LABEL: scalar_i16_lowestbit_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xffff
; CHECK-GI-NEXT: cset w0, eq
@@ -147,8 +142,7 @@ define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
; CHECK-GI-LABEL: scalar_i16_bitsinmiddle_eq:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #4080 // =0xff0
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xffff
; CHECK-GI-NEXT: cset w0, eq
@@ -430,8 +424,7 @@ define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_signbit_ne:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #-128 // =0xffffff80
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: tst w8, #0xff
; CHECK-GI-NEXT: cset w0, ne
@@ -488,8 +481,7 @@ define i1 @scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; CHECK-GI-LABEL: scalar_i8_bitsinmiddle_slt:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #24 // =0x18
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: lsl w8, w8, w9
+; CHECK-GI-NEXT: lsl w8, w8, w1
; CHECK-GI-NEXT: and w8, w8, w0
; CHECK-GI-NEXT: sxtb w8, w8
; CHECK-GI-NEXT: cmp w8, #0
diff --git a/llvm/test/CodeGen/AArch64/select_const.ll b/llvm/test/CodeGen/AArch64/select_const.ll
index daa9971dbcd58..c67d527dbfed1 100644
--- a/llvm/test/CodeGen/AArch64/select_const.ll
+++ b/llvm/test/CodeGen/AArch64/select_const.ll
@@ -672,7 +672,6 @@ define i8 @shl_constant_sel_constants(i1 %cond) {
; CHECK-GI-NEXT: sbfx w9, w0, #0, #1
; CHECK-GI-NEXT: mov w8, #1 // =0x1
; CHECK-GI-NEXT: add w9, w9, #3
-; CHECK-GI-NEXT: and w9, w9, #0xff
; CHECK-GI-NEXT: lsl w0, w8, w9
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, i8 2, i8 3
@@ -714,7 +713,6 @@ define i8 @lshr_constant_sel_constants(i1 %cond) {
; CHECK-GI-NEXT: sbfx w9, w0, #0, #1
; CHECK-GI-NEXT: mov w8, #64 // =0x40
; CHECK-GI-NEXT: add w9, w9, #3
-; CHECK-GI-NEXT: and w9, w9, #0xff
; CHECK-GI-NEXT: lsr w0, w8, w9
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, i8 2, i8 3
@@ -747,7 +745,6 @@ define i8 @ashr_constant_sel_constants(i1 %cond) {
; CHECK-GI-NEXT: sbfx w9, w0, #0, #1
; CHECK-GI-NEXT: mov w8, #-128 // =0xffffff80
; CHECK-GI-NEXT: add w9, w9, #3
-; CHECK-GI-NEXT: and w9, w9, #0xff
; CHECK-GI-NEXT: asr w0, w8, w9
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, i8 2, i8 3
diff --git a/llvm/test/CodeGen/AArch64/shift.ll b/llvm/test/CodeGen/AArch64/shift.ll
index 5d7935474c903..eb5f56f771a0f 100644
--- a/llvm/test/CodeGen/AArch64/shift.ll
+++ b/llvm/test/CodeGen/AArch64/shift.ll
@@ -19,31 +19,19 @@ define i1 @shl_i1(i1 %0, i1 %1){
}
define i8 @shl_i8(i8 %0, i8 %1){
-; CHECK-SD-LABEL: shl_i8:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: lsl w0, w0, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: shl_i8:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: and w8, w1, #0xff
-; CHECK-GI-NEXT: lsl w0, w0, w8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: shl_i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: lsl w0, w0, w1
+; CHECK-NEXT: ret
%3 = shl i8 %0, %1
ret i8 %3
}
define i16 @shl_i16(i16 %0, i16 %1){
-; CHECK-SD-LABEL: shl_i16:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: lsl w0, w0, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: shl_i16:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: and w8, w1, #0xffff
-; CHECK-GI-NEXT: lsl w0, w0, w8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: shl_i16:
+; CHECK: // %bb.0:
+; CHECK-NEXT: lsl w0, w0, w1
+; CHECK-NEXT: ret
%3 = shl i16 %0, %1
ret i16 %3
}
@@ -118,35 +106,21 @@ define i1 @ashr_i1(i1 %0, i1 %1){
}
define i8 @ashr_i8(i8 %0, i8 %1){
-; CHECK-SD-LABEL: ashr_i8:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: sxtb w8, w0
-; CHECK-SD-NEXT: asr w0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: ashr_i8:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: sxtb w8, w0
-; CHECK-GI-NEXT: and w9, w1, #0xff
-; CHECK-GI-NEXT: asr w0, w8, w9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: ashr_i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: sxtb w8, w0
+; CHECK-NEXT: asr w0, w8, w1
+; CHECK-NEXT: ret
%3 = ashr i8 %0, %1
ret i8 %3
}
define i16 @ashr_i16(i16 %0, i16 %1){
-; CHECK-SD-LABEL: ashr_i16:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: sxth w8, w0
-; CHECK-SD-NEXT: asr w0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: ashr_i16:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: sxth w8, w0
-; CHECK-GI-NEXT: and w9, w1, #0xffff
-; CHECK-GI-NEXT: asr w0, w8, w9
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: ashr_i16:
+; CHECK: // %bb.0:
+; CHECK-NEXT: sxth w8, w0
+; CHECK-NEXT: asr w0, w8, w1
+; CHECK-NEXT: ret
%3 = ashr i16 %0, %1
ret i16 %3
}
@@ -223,35 +197,21 @@ define i1 @lshr_i1(i1 %0, i1 %1){
}
define i8 @lshr_i8(i8 %0, i8 %1){
-; CHECK-SD-LABEL: lshr_i8:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: and w8, w0, #0xff
-; CHECK-SD-NEXT: lsr w0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: lshr_i8:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: and w8, w1, #0xff
-; CHECK-GI-NEXT: and w9, w0, #0xff
-; CHECK-GI-NEXT: lsr w0, w9, w8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: lshr_i8:
+; CHECK: // %bb.0:
+; CHECK-NEXT: and w8, w0, #0xff
+; CHECK-NEXT: lsr w0, w8, w1
+; CHECK-NEXT: ret
%3 = lshr i8 %0, %1
ret i8 %3
}
define i16 @lshr_i16(i16 %0, i16 %1){
-; CHECK-SD-LABEL: lshr_i16:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: and w8, w0, #0xffff
-; CHECK-SD-NEXT: lsr w0, w8, w1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: lshr_i16:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: and w8, w1, #0xffff
-; CHECK-GI-NEXT: and w9, w0, #0xffff
-; CHECK-GI-NEXT: lsr w0, w9, w8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: lshr_i16:
+; CHECK: // %bb.0:
+; CHECK-NEXT: and w8, w0, #0xffff
+; CHECK-NEXT: lsr w0, w8, w1
+; CHECK-NEXT: ret
%3 = lshr i16 %0, %1
ret i16 %3
}
More information about the llvm-commits
mailing list