[llvm] [ARM] Specify hasOneUse for shouldFoldConstantShiftPairToMask (PR #156915)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 4 09:43:44 PDT 2025


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/156915

>From 454ebd37f57628440bb94acd914ae75dd70ec0fe Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 4 Sep 2025 11:42:11 -0400
Subject: [PATCH 1/3] Create ushlsat.ll

---
 llvm/test/CodeGen/ARM/ushlsat.ll | 71 ++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 llvm/test/CodeGen/ARM/ushlsat.ll

diff --git a/llvm/test/CodeGen/ARM/ushlsat.ll b/llvm/test/CodeGen/ARM/ushlsat.ll
new file mode 100644
index 0000000000000..6d7e388075de4
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/ushlsat.ll
@@ -0,0 +1,71 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=thumbv7m-eabi  %s -o - | FileCheck %s --check-prefix V7M
+; RUN: llc -mtriple=armv7a-eabi  %s -o -   | FileCheck %s --check-prefix V7A
+; RUN: llc -mtriple=thumbv7a-eabi  %s -o -   | FileCheck %s --check-prefix V7A-T
+; RUN: llc -mtriple=armv6m-eabi  %s -o -   | FileCheck %s --check-prefix V6M
+
+; Do not fold shlsat -> shl.
+define i16 @combine_shlsat_to_shl_no_fold(i16 %x) nounwind {
+; V7M-LABEL: combine_shlsat_to_shl_no_fold:
+; V7M:       @ %bb.0:
+; V7M-NEXT:    movs r1, #0
+; V7M-NEXT:    movs r3, #0
+; V7M-NEXT:    movt r1, #16383
+; V7M-NEXT:    movt r3, #8191
+; V7M-NEXT:    and.w r1, r1, r0, lsl #14
+; V7M-NEXT:    and.w r0, r3, r0, lsl #14
+; V7M-NEXT:    cmp r1, r0
+; V7M-NEXT:    lsl.w r2, r1, #3
+; V7M-NEXT:    it ne
+; V7M-NEXT:    movne.w r2, #-1
+; V7M-NEXT:    lsrs r0, r2, #16
+; V7M-NEXT:    bx lr
+;
+; V7A-LABEL: combine_shlsat_to_shl_no_fold:
+; V7A:       @ %bb.0:
+; V7A-NEXT:    movw r1, #0
+; V7A-NEXT:    movw r3, #0
+; V7A-NEXT:    movt r1, #16383
+; V7A-NEXT:    movt r3, #8191
+; V7A-NEXT:    and r1, r1, r0, lsl #14
+; V7A-NEXT:    and r0, r3, r0, lsl #14
+; V7A-NEXT:    cmp r1, r0
+; V7A-NEXT:    lsl r2, r1, #3
+; V7A-NEXT:    mvnne r2, #0
+; V7A-NEXT:    lsr r0, r2, #16
+; V7A-NEXT:    bx lr
+;
+; V7A-T-LABEL: combine_shlsat_to_shl_no_fold:
+; V7A-T:       @ %bb.0:
+; V7A-T-NEXT:    movs r1, #0
+; V7A-T-NEXT:    movs r3, #0
+; V7A-T-NEXT:    movt r1, #16383
+; V7A-T-NEXT:    movt r3, #8191
+; V7A-T-NEXT:    and.w r1, r1, r0, lsl #14
+; V7A-T-NEXT:    and.w r0, r3, r0, lsl #14
+; V7A-T-NEXT:    cmp r1, r0
+; V7A-T-NEXT:    lsl.w r2, r1, #3
+; V7A-T-NEXT:    it ne
+; V7A-T-NEXT:    movne.w r2, #-1
+; V7A-T-NEXT:    lsrs r0, r2, #16
+; V7A-T-NEXT:    bx lr
+;
+; V6M-LABEL: combine_shlsat_to_shl_no_fold:
+; V6M:       @ %bb.0:
+; V6M-NEXT:    lsls r0, r0, #16
+; V6M-NEXT:    lsrs r0, r0, #18
+; V6M-NEXT:    lsls r1, r0, #16
+; V6M-NEXT:    lsls r0, r0, #19
+; V6M-NEXT:    lsrs r2, r0, #3
+; V6M-NEXT:    cmp r1, r2
+; V6M-NEXT:    beq .LBB0_2
+; V6M-NEXT:  @ %bb.1:
+; V6M-NEXT:    movs r0, #0
+; V6M-NEXT:    mvns r0, r0
+; V6M-NEXT:  .LBB0_2:
+; V6M-NEXT:    lsrs r0, r0, #16
+; V6M-NEXT:    bx lr
+  %x2 = lshr i16 %x, 2
+  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x2, i16 3)
+  ret i16 %tmp
+}

>From 382bc96462e2186517c3558ac8c73171dbecc888 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 4 Sep 2025 11:44:29 -0400
Subject: [PATCH 2/3] [ARM] Specify hasOneUse for
 shouldFoldConstantShiftPairToMask

It should be one use, just like AArch64
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp |  4 +++
 llvm/test/CodeGen/ARM/ushlsat.ll        | 39 ++++++++++---------------
 2 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index b5c01eafcf108..45918232e3a70 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -13885,6 +13885,10 @@ bool ARMTargetLowering::shouldFoldConstantShiftPairToMask(
            N->getOperand(0).getOpcode() == ISD::SHL)) &&
          "Expected shift-shift mask");
 
+  // Don't allow multiuse shift folding with the same shift amount.
+  if (!N->getOperand(0)->hasOneUse())
+    return false;
+
   if (!Subtarget->isThumb1Only())
     return true;
 
diff --git a/llvm/test/CodeGen/ARM/ushlsat.ll b/llvm/test/CodeGen/ARM/ushlsat.ll
index 6d7e388075de4..149e703430c45 100644
--- a/llvm/test/CodeGen/ARM/ushlsat.ll
+++ b/llvm/test/CodeGen/ARM/ushlsat.ll
@@ -9,45 +9,36 @@ define i16 @combine_shlsat_to_shl_no_fold(i16 %x) nounwind {
 ; V7M-LABEL: combine_shlsat_to_shl_no_fold:
 ; V7M:       @ %bb.0:
 ; V7M-NEXT:    movs r1, #0
-; V7M-NEXT:    movs r3, #0
 ; V7M-NEXT:    movt r1, #16383
-; V7M-NEXT:    movt r3, #8191
-; V7M-NEXT:    and.w r1, r1, r0, lsl #14
-; V7M-NEXT:    and.w r0, r3, r0, lsl #14
-; V7M-NEXT:    cmp r1, r0
-; V7M-NEXT:    lsl.w r2, r1, #3
+; V7M-NEXT:    and.w r0, r1, r0, lsl #14
+; V7M-NEXT:    lsls r1, r0, #3
+; V7M-NEXT:    cmp.w r0, r1, lsr #3
 ; V7M-NEXT:    it ne
-; V7M-NEXT:    movne.w r2, #-1
-; V7M-NEXT:    lsrs r0, r2, #16
+; V7M-NEXT:    movne.w r1, #-1
+; V7M-NEXT:    lsrs r0, r1, #16
 ; V7M-NEXT:    bx lr
 ;
 ; V7A-LABEL: combine_shlsat_to_shl_no_fold:
 ; V7A:       @ %bb.0:
 ; V7A-NEXT:    movw r1, #0
-; V7A-NEXT:    movw r3, #0
 ; V7A-NEXT:    movt r1, #16383
-; V7A-NEXT:    movt r3, #8191
-; V7A-NEXT:    and r1, r1, r0, lsl #14
-; V7A-NEXT:    and r0, r3, r0, lsl #14
-; V7A-NEXT:    cmp r1, r0
-; V7A-NEXT:    lsl r2, r1, #3
-; V7A-NEXT:    mvnne r2, #0
-; V7A-NEXT:    lsr r0, r2, #16
+; V7A-NEXT:    and r0, r1, r0, lsl #14
+; V7A-NEXT:    lsl r1, r0, #3
+; V7A-NEXT:    cmp r0, r1, lsr #3
+; V7A-NEXT:    mvnne r1, #0
+; V7A-NEXT:    lsr r0, r1, #16
 ; V7A-NEXT:    bx lr
 ;
 ; V7A-T-LABEL: combine_shlsat_to_shl_no_fold:
 ; V7A-T:       @ %bb.0:
 ; V7A-T-NEXT:    movs r1, #0
-; V7A-T-NEXT:    movs r3, #0
 ; V7A-T-NEXT:    movt r1, #16383
-; V7A-T-NEXT:    movt r3, #8191
-; V7A-T-NEXT:    and.w r1, r1, r0, lsl #14
-; V7A-T-NEXT:    and.w r0, r3, r0, lsl #14
-; V7A-T-NEXT:    cmp r1, r0
-; V7A-T-NEXT:    lsl.w r2, r1, #3
+; V7A-T-NEXT:    and.w r0, r1, r0, lsl #14
+; V7A-T-NEXT:    lsls r1, r0, #3
+; V7A-T-NEXT:    cmp.w r0, r1, lsr #3
 ; V7A-T-NEXT:    it ne
-; V7A-T-NEXT:    movne.w r2, #-1
-; V7A-T-NEXT:    lsrs r0, r2, #16
+; V7A-T-NEXT:    movne.w r1, #-1
+; V7A-T-NEXT:    lsrs r0, r1, #16
 ; V7A-T-NEXT:    bx lr
 ;
 ; V6M-LABEL: combine_shlsat_to_shl_no_fold:

>From 7ffd95587d91246417904e840699c343a732b2dc Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 4 Sep 2025 12:43:33 -0400
Subject: [PATCH 3/3] more

---
 llvm/test/CodeGen/ARM/combine-movc-sub.ll     | 14 ++++----
 llvm/test/CodeGen/ARM/dagcombine-ld-op-st.ll  |  7 ++--
 .../CodeGen/ARM/illegal-bitfield-loadstore.ll | 35 +++++++++++--------
 llvm/test/CodeGen/ARM/rotate-add.ll           |  4 +--
 4 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/llvm/test/CodeGen/ARM/combine-movc-sub.ll b/llvm/test/CodeGen/ARM/combine-movc-sub.ll
index ca5d089443542..0aaab83b51ce9 100644
--- a/llvm/test/CodeGen/ARM/combine-movc-sub.ll
+++ b/llvm/test/CodeGen/ARM/combine-movc-sub.ll
@@ -25,15 +25,15 @@ declare void @foo(ptr, ptr)
 define hidden fastcc ptr @test(ptr %Search, ptr %ClauseList, i32 %Level, ptr nocapture %New) {
 ; CHECK-LABEL: test:
 ; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    push.w {r4, r5, r6, r7, r8, r9, lr}
-; CHECK-NEXT:    sub sp, #4
-; CHECK-NEXT:    sub.w r7, r2, #32
+; CHECK-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, lr}
+; CHECK-NEXT:    sub.w r9, r2, #32
 ; CHECK-NEXT:    mov r8, r0
 ; CHECK-NEXT:    movs r0, #1
 ; CHECK-NEXT:    mov r4, r2
-; CHECK-NEXT:    add.w r6, r0, r7, lsr #5
+; CHECK-NEXT:    add.w r6, r0, r9, lsr #5
 ; CHECK-NEXT:    mov r5, r1
-; CHECK-NEXT:    mov.w r9, #0
+; CHECK-NEXT:    lsr.w r7, r9, #5
+; CHECK-NEXT:    mov.w r10, #0
 ; CHECK-NEXT:    b .LBB0_2
 ; CHECK-NEXT:  .LBB0_1: @ %for.inc
 ; CHECK-NEXT:    @ in Loop: Header=BB0_2 Depth=1
@@ -47,7 +47,7 @@ define hidden fastcc ptr @test(ptr %Search, ptr %ClauseList, i32 %Level, ptr noc
 ; CHECK-NEXT:    add.w r0, r0, r6, lsl #2
 ; CHECK-NEXT:    ldr r0, [r0, #40]
 ; CHECK-NEXT:    it hi
-; CHECK-NEXT:    andhi r2, r7, #31
+; CHECK-NEXT:    subhi.w r2, r9, r7, lsl #5
 ; CHECK-NEXT:    lsrs r0, r2
 ; CHECK-NEXT:    lsls r0, r0, #31
 ; CHECK-NEXT:    beq .LBB0_1
@@ -55,7 +55,7 @@ define hidden fastcc ptr @test(ptr %Search, ptr %ClauseList, i32 %Level, ptr noc
 ; CHECK-NEXT:    @ in Loop: Header=BB0_2 Depth=1
 ; CHECK-NEXT:    mov r0, r8
 ; CHECK-NEXT:    bl foo
-; CHECK-NEXT:    str.w r9, [r5, #4]
+; CHECK-NEXT:    str.w r10, [r5, #4]
 ; CHECK-NEXT:    b .LBB0_1
 entry:
   %cmp4.i.i = icmp ugt i32 %Level, 31
diff --git a/llvm/test/CodeGen/ARM/dagcombine-ld-op-st.ll b/llvm/test/CodeGen/ARM/dagcombine-ld-op-st.ll
index 6819af3ba3e26..4025a32655a6f 100644
--- a/llvm/test/CodeGen/ARM/dagcombine-ld-op-st.ll
+++ b/llvm/test/CodeGen/ARM/dagcombine-ld-op-st.ll
@@ -41,10 +41,11 @@ define i16 @test(ptr %p1) {
 ;
 ; CHECK-BE-NORMAL-LABEL: test:
 ; CHECK-BE-NORMAL:       @ %bb.0: @ %entry
-; CHECK-BE-NORMAL-NEXT:    ldrh r1, [r0]
+; CHECK-BE-NORMAL-NEXT:    ldr r1, [r0]
 ; CHECK-BE-NORMAL-NEXT:    movw r2, #65534
-; CHECK-BE-NORMAL-NEXT:    orr r1, r1, r2
-; CHECK-BE-NORMAL-NEXT:    strh r1, [r0]
+; CHECK-BE-NORMAL-NEXT:    orr r2, r2, r1, lsr #16
+; CHECK-BE-NORMAL-NEXT:    pkhbt r1, r1, r2, lsl #16
+; CHECK-BE-NORMAL-NEXT:    str r1, [r0]
 ; CHECK-BE-NORMAL-NEXT:    mov r0, #0
 ; CHECK-BE-NORMAL-NEXT:    bx lr
 ;
diff --git a/llvm/test/CodeGen/ARM/illegal-bitfield-loadstore.ll b/llvm/test/CodeGen/ARM/illegal-bitfield-loadstore.ll
index 5dbf8dd86b891..1627e4fab6423 100644
--- a/llvm/test/CodeGen/ARM/illegal-bitfield-loadstore.ll
+++ b/llvm/test/CodeGen/ARM/illegal-bitfield-loadstore.ll
@@ -90,16 +90,16 @@ define void @i56_or(ptr %a) {
 ;
 ; BE-LABEL: i56_or:
 ; BE:       @ %bb.0:
-; BE-NEXT:    mov r1, r0
-; BE-NEXT:    ldr r0, [r0]
-; BE-NEXT:    ldrh r2, [r1, #4]!
-; BE-NEXT:    ldrb r3, [r1, #2]
+; BE-NEXT:    ldr r1, [r0]
+; BE-NEXT:    strb r1, [r0, #3]
+; BE-NEXT:    ldrh r2, [r0, #4]!
+; BE-NEXT:    ldrb r3, [r0, #2]
 ; BE-NEXT:    orr r2, r3, r2, lsl #8
-; BE-NEXT:    orr r0, r2, r0, lsl #24
-; BE-NEXT:    orr r0, r0, #384
-; BE-NEXT:    strb r0, [r1, #2]
-; BE-NEXT:    lsr r0, r0, #8
-; BE-NEXT:    strh r0, [r1]
+; BE-NEXT:    orr r1, r2, r1, lsl #24
+; BE-NEXT:    orr r1, r1, #384
+; BE-NEXT:    strb r1, [r0, #2]
+; BE-NEXT:    lsr r1, r1, #8
+; BE-NEXT:    strh r1, [r0]
 ; BE-NEXT:    mov pc, lr
   %aa = load i56, ptr %a
   %b = or i56 %aa, 384
@@ -118,11 +118,14 @@ define void @i56_and_or(ptr %a) {
 ;
 ; BE-LABEL: i56_and_or:
 ; BE:       @ %bb.0:
-; BE-NEXT:    ldrh r1, [r0, #4]!
-; BE-NEXT:    mov r2, #128
-; BE-NEXT:    orr r1, r1, #1
-; BE-NEXT:    strb r2, [r0, #2]
-; BE-NEXT:    strh r1, [r0]
+; BE-NEXT:    mov r1, r0
+; BE-NEXT:    mov r3, #128
+; BE-NEXT:    ldrh r2, [r1, #4]!
+; BE-NEXT:    strb r3, [r1, #2]
+; BE-NEXT:    ldr r3, [r0]
+; BE-NEXT:    strb r3, [r0, #3]
+; BE-NEXT:    orr r0, r2, #1
+; BE-NEXT:    strh r0, [r1]
 ; BE-NEXT:    mov pc, lr
 
   %b = load i56, ptr %a, align 1
@@ -143,9 +146,11 @@ define void @i56_insert_bit(ptr %a, i1 zeroext %bit) {
 ;
 ; BE-LABEL: i56_insert_bit:
 ; BE:       @ %bb.0:
-; BE-NEXT:    ldrh r2, [r0, #4]!
+; BE-NEXT:    ldr r2, [r0]
 ; BE-NEXT:    mov r3, #57088
+; BE-NEXT:    strb r2, [r0, #3]
 ; BE-NEXT:    orr r3, r3, #16711680
+; BE-NEXT:    ldrh r2, [r0, #4]!
 ; BE-NEXT:    and r2, r3, r2, lsl #8
 ; BE-NEXT:    orr r1, r2, r1, lsl #13
 ; BE-NEXT:    lsr r1, r1, #8
diff --git a/llvm/test/CodeGen/ARM/rotate-add.ll b/llvm/test/CodeGen/ARM/rotate-add.ll
index fd3055e5e2725..4ae7fcf6fac00 100644
--- a/llvm/test/CodeGen/ARM/rotate-add.ll
+++ b/llvm/test/CodeGen/ARM/rotate-add.ll
@@ -124,9 +124,9 @@ define i64 @test_rotl_udiv_special_case(i64 %i) {
 ; CHECK-NEXT:    ldr r12, .LCPI8_0
 ; CHECK-NEXT:    adc lr, r2, #0
 ; CHECK-NEXT:    umull r3, r2, lr, r12
-; CHECK-NEXT:    bic r3, r2, #1
-; CHECK-NEXT:    add r2, r3, r2, lsr #1
 ; CHECK-NEXT:    ldr r3, .LCPI8_1
+; CHECK-NEXT:    lsr r2, r2, #1
+; CHECK-NEXT:    add r2, r2, r2, lsl #1
 ; CHECK-NEXT:    sub r2, lr, r2
 ; CHECK-NEXT:    subs r0, r0, r2
 ; CHECK-NEXT:    sbc r1, r1, #0



More information about the llvm-commits mailing list