[llvm] [AArch64][GlobalISel] Use PreferredShiftAmountTy in TruncOfShift combine (PR #213381)

David Green via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 10 02:01:58 PDT 2026


https://github.com/davemgreen updated https://github.com/llvm/llvm-project/pull/213381

>From 8f143cab8ac3c7ab98fcf21384e45c764c58c716 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Fri, 31 Jul 2026 16:02:09 +0100
Subject: [PATCH] [AArch64][GlobalISel] Use PreferredShiftAmountTy in
 TruncOfShift combine.

This trunc of shift combine has always caused issues with the shift amount type
no longer matching the new shift type. This patch changes the type of the shift
amount to at least match the getPreferredShiftAmountTy.
---
 .../lib/CodeGen/GlobalISel/CombinerHelper.cpp |  5 +++
 .../combine-shift-immed-mismatch-crash.mir    |  4 +-
 .../AArch64/GlobalISel/combine-trunc.mir      |  4 +-
 llvm/test/CodeGen/AArch64/arm64-vshift.ll     | 37 ++++---------------
 llvm/test/CodeGen/AArch64/shift.ll            |  4 +-
 llvm/test/CodeGen/RISCV/GlobalISel/shift.ll   |  7 +---
 6 files changed, 21 insertions(+), 40 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index d9c5fd2843490..063fd094fbadc 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2872,6 +2872,11 @@ void CombinerHelper::applyCombineTruncOfShift(
   Register ShiftSrc = ShiftMI->getOperand(1).getReg();
   ShiftSrc = Builder.buildTrunc(NewShiftTy, ShiftSrc).getReg(0);
 
+  const auto &TL = getTargetLowering();
+  LLT PrefShiftTy = TL.getPreferredShiftAmountTy(NewShiftTy);
+  if (MRI.getType(ShiftAmt) != PrefShiftTy)
+    ShiftAmt = Builder.buildZExtOrTrunc(PrefShiftTy, ShiftAmt).getReg(0);
+
   Register NewShift =
       Builder
           .buildInstr(ShiftMI->getOpcode(), {NewShiftTy}, {ShiftSrc, ShiftAmt})
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir
index d042474f3e836..da915b6daadbc 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir
@@ -26,8 +26,8 @@ body:             |
   ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 4
   ; CHECK-NEXT:   [[SHL:%[0-9]+]]:_(i32) = nsw G_SHL [[LOAD]], [[C1]](i32)
   ; CHECK-NEXT:   [[MUL:%[0-9]+]]:_(i32) = nsw G_MUL [[SHL]], [[C]]
-  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 2
-  ; CHECK-NEXT:   [[SHL1:%[0-9]+]]:_(i32) = G_SHL [[MUL]], [[C2]](i64)
+  ; CHECK-NEXT:   [[C2:%[0-9]+]]:_(i32) = G_CONSTANT i32 2
+  ; CHECK-NEXT:   [[SHL1:%[0-9]+]]:_(i32) = G_SHL [[MUL]], [[C2]](i32)
   ; CHECK-NEXT:   $w0 = COPY [[SHL1]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
   bb.1:
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
index b717d7a002271..f478aa80e7fa2 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
@@ -146,9 +146,9 @@ body:             |
     ; CHECK-PRE: liveins: $w0
     ; CHECK-PRE-NEXT: {{  $}}
     ; CHECK-PRE-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0
-    ; CHECK-PRE-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 2
     ; CHECK-PRE-NEXT: [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY]](i32)
-    ; CHECK-PRE-NEXT: [[SHL:%[0-9]+]]:_(i16) = G_SHL [[TRUNC]], [[C]](i32)
+    ; CHECK-PRE-NEXT: [[C:%[0-9]+]]:_(i16) = G_CONSTANT i16 2
+    ; CHECK-PRE-NEXT: [[SHL:%[0-9]+]]:_(i16) = G_SHL [[TRUNC]], [[C]](i16)
     ; CHECK-PRE-NEXT: $h0 = COPY [[SHL]](i16)
     ;
     ; CHECK-POST-LABEL: name: test_combine_trunc_shl_s32_by_2
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index 8d17836a2b761..088db615b99d1 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -4623,13 +4623,8 @@ define <4 x i16> @lshr_trunc_v4i64_v4i16(<4 x i64> %a) {
 ;
 ; CHECK-GI-LABEL: lshr_trunc_v4i64_v4i16:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    adrp x8, .LCPI278_0
 ; CHECK-GI-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI278_0]
-; CHECK-GI-NEXT:    uzp1 v2.4s, v2.4s, v2.4s
-; CHECK-GI-NEXT:    neg v1.4s, v2.4s
-; CHECK-GI-NEXT:    ushl v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT:    xtn v0.4h, v0.4s
+; CHECK-GI-NEXT:    shrn v0.4h, v0.4s, #8
 ; CHECK-GI-NEXT:    ret
   %b = lshr <4 x i64> %a, <i64 8, i64 8, i64 8, i64 8>
   %c = trunc <4 x i64> %b to <4 x i16>
@@ -4664,13 +4659,8 @@ define <4 x i16> @ashr_trunc_v4i64_v4i16(<4 x i64> %a) {
 ;
 ; CHECK-GI-LABEL: ashr_trunc_v4i64_v4i16:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    adrp x8, .LCPI280_0
 ; CHECK-GI-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI280_0]
-; CHECK-GI-NEXT:    uzp1 v2.4s, v2.4s, v2.4s
-; CHECK-GI-NEXT:    neg v1.4s, v2.4s
-; CHECK-GI-NEXT:    sshl v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT:    xtn v0.4h, v0.4s
+; CHECK-GI-NEXT:    shrn v0.4h, v0.4s, #8
 ; CHECK-GI-NEXT:    ret
   %b = ashr <4 x i64> %a, <i64 8, i64 8, i64 8, i64 8>
   %c = trunc <4 x i64> %b to <4 x i16>
@@ -4695,23 +4685,12 @@ define <2 x i8> @shl_trunc_v2i64_v2i8(<2 x i64> %a) {
 }
 
 define <4 x i16> @shl_trunc_v4i64_v4i16(<4 x i64> %a) {
-; CHECK-SD-LABEL: shl_trunc_v4i64_v4i16:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-SD-NEXT:    xtn v0.4h, v0.4s
-; CHECK-SD-NEXT:    shl v0.4h, v0.4h, #8
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: shl_trunc_v4i64_v4i16:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    adrp x8, .LCPI282_0
-; CHECK-GI-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI282_0]
-; CHECK-GI-NEXT:    uzp1 v1.4s, v2.4s, v2.4s
-; CHECK-GI-NEXT:    xtn v0.4h, v0.4s
-; CHECK-GI-NEXT:    xtn v1.4h, v1.4s
-; CHECK-GI-NEXT:    ushl v0.4h, v0.4h, v1.4h
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: shl_trunc_v4i64_v4i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    xtn v0.4h, v0.4s
+; CHECK-NEXT:    shl v0.4h, v0.4h, #8
+; CHECK-NEXT:    ret
   %b = shl <4 x i64> %a, <i64 8, i64 8, i64 8, i64 8>
   %c = trunc <4 x i64> %b to <4 x i16>
   ret <4 x i16> %c
diff --git a/llvm/test/CodeGen/AArch64/shift.ll b/llvm/test/CodeGen/AArch64/shift.ll
index 574afd32eecc0..5d7935474c903 100644
--- a/llvm/test/CodeGen/AArch64/shift.ll
+++ b/llvm/test/CodeGen/AArch64/shift.ll
@@ -1040,8 +1040,8 @@ define <2 x i8> @pr168848(<2 x i1> %shift) {
 ; CHECK-GI-NEXT:    movi v1.2s, #1
 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
 ; CHECK-GI-NEXT:    movi v1.8b, #1
-; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h
-; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
+; CHECK-GI-NEXT:    mov w8, v0.s[1]
+; CHECK-GI-NEXT:    mov v0.b[1], w8
 ; CHECK-GI-NEXT:    ushl v0.8b, v1.8b, v0.8b
 ; CHECK-GI-NEXT:    umov w8, v0.b[0]
 ; CHECK-GI-NEXT:    umov w9, v0.b[1]
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/shift.ll b/llvm/test/CodeGen/RISCV/GlobalISel/shift.ll
index f29f3bcc7d3a3..1b7ca75315a6c 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/shift.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/shift.ll
@@ -57,10 +57,8 @@ define i16 @test_lshr_i48_2(i48 %x, i48 %y) {
 ;
 ; RV64-LABEL: test_lshr_i48_2:
 ; RV64:       # %bb.0:
-; RV64-NEXT:    slli a0, a0, 32
 ; RV64-NEXT:    andi a1, a1, 15
-; RV64-NEXT:    srli a0, a0, 32
-; RV64-NEXT:    srl a0, a0, a1
+; RV64-NEXT:    srlw a0, a0, a1
 ; RV64-NEXT:    ret
   %and = and i48 %y, 15
   %lshr = lshr i48 %x, %and
@@ -79,8 +77,7 @@ define i16 @test_ashr_i48_2(i48 %x, i48 %y) {
 ; RV64-LABEL: test_ashr_i48_2:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    andi a1, a1, 15
-; RV64-NEXT:    sext.w a0, a0
-; RV64-NEXT:    sra a0, a0, a1
+; RV64-NEXT:    sraw a0, a0, a1
 ; RV64-NEXT:    ret
   %and = and i48 %y, 15
   %ashr = ashr i48 %x, %and



More information about the llvm-commits mailing list