[llvm] [ARM] Prefer << 31 >> 31 over -(a & 1) for THUMB1 only (PR #152936)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 10 12:19:42 PDT 2025


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

>From 535ed4e0df370a1e0a9017e79909878604757098 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Fri, 8 Aug 2025 14:55:05 -0400
Subject: [PATCH] [ARM] Prefer << 31 >> 31 over -(a & 1) for THUMB1 only

Materializing the 1 requires its own instruction for Thumb1
---
 llvm/lib/Target/ARM/ARMInstrThumb.td          |  8 ++++++
 llvm/test/CodeGen/ARM/select_const.ll         |  5 ++--
 .../CodeGen/Thumb/srem-seteq-illegal-types.ll | 26 +++++++++----------
 3 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index e38cafdf55c46..a52d0eddee92a 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -1571,6 +1571,14 @@ def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8),
 def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
             (tCMPr   tGPR:$Rn, tGPR:$Rm)>;
 
+// -(n & 1) -> (n << 31) >> 31 to avoid materializing constants on Thumb1
+def : T1Pat<(ineg (and tGPR:$Rn, (i32 1))),
+            (tASRri (tLSLri tGPR:$Rn, 31), 31)>,
+      Requires<[IsThumb, IsThumb1Only]>;
+def : T1Pat<(sub (i32 0), (and tGPR:$Rn, (i32 1))),
+            (tASRri (tLSLri tGPR:$Rn, 31), 31)>,
+      Requires<[IsThumb, IsThumb1Only]>;
+
 // Bswap 16 with load/store
 def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)),
             (tREV16 (tLDRHi t_addrmode_is2:$addr))>;
diff --git a/llvm/test/CodeGen/ARM/select_const.ll b/llvm/test/CodeGen/ARM/select_const.ll
index 180daa12e7c52..54a14e7ac7343 100644
--- a/llvm/test/CodeGen/ARM/select_const.ll
+++ b/llvm/test/CodeGen/ARM/select_const.ll
@@ -276,9 +276,8 @@ define i32 @select_neg1_or_0(i1 %cond) {
 ;
 ; THUMB-LABEL: select_neg1_or_0:
 ; THUMB:       @ %bb.0:
-; THUMB-NEXT:    movs r1, #1
-; THUMB-NEXT:    ands r1, r0
-; THUMB-NEXT:    rsbs r0, r1, #0
+; THUMB-NEXT:    lsls r0, r0, #31
+; THUMB-NEXT:    asrs r0, r0, #31
 ; THUMB-NEXT:    bx lr
   %sel = select i1 %cond, i32 -1, i32 0
   ret i32 %sel
diff --git a/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll b/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll
index 00eed6483cc12..65f2af078232c 100644
--- a/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll
+++ b/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll
@@ -81,15 +81,14 @@ define <3 x i1> @test_srem_vec(<3 x i33> %X) nounwind {
 ; CHECK-NEXT:    push {r4, r5, r6, r7, lr}
 ; CHECK-NEXT:    .pad #12
 ; CHECK-NEXT:    sub sp, #12
-; CHECK-NEXT:    movs r7, r3
-; CHECK-NEXT:    str r2, [sp, #4] @ 4-byte Spill
-; CHECK-NEXT:    movs r5, #1
-; CHECK-NEXT:    ands r1, r5
-; CHECK-NEXT:    rsbs r1, r1, #0
+; CHECK-NEXT:    str r3, [sp, #4] @ 4-byte Spill
+; CHECK-NEXT:    movs r5, r2
+; CHECK-NEXT:    lsls r1, r1, #31
+; CHECK-NEXT:    asrs r1, r1, #31
 ; CHECK-NEXT:    movs r6, #9
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    str r3, [sp] @ 4-byte Spill
+; CHECK-NEXT:    movs r7, #0
 ; CHECK-NEXT:    movs r2, r6
+; CHECK-NEXT:    movs r3, r7
 ; CHECK-NEXT:    bl __aeabi_ldivmod
 ; CHECK-NEXT:    movs r4, r2
 ; CHECK-NEXT:    movs r0, #3
@@ -98,13 +97,14 @@ define <3 x i1> @test_srem_vec(<3 x i33> %X) nounwind {
 ; CHECK-NEXT:    orrs r4, r3
 ; CHECK-NEXT:    subs r0, r4, #1
 ; CHECK-NEXT:    sbcs r4, r0
-; CHECK-NEXT:    ands r7, r5
-; CHECK-NEXT:    rsbs r1, r7, #0
 ; CHECK-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
+; CHECK-NEXT:    lsls r0, r0, #31
+; CHECK-NEXT:    asrs r1, r0, #31
+; CHECK-NEXT:    movs r0, r5
 ; CHECK-NEXT:    movs r2, r6
-; CHECK-NEXT:    ldr r7, [sp] @ 4-byte Reload
 ; CHECK-NEXT:    movs r3, r7
 ; CHECK-NEXT:    bl __aeabi_ldivmod
+; CHECK-NEXT:    movs r5, #1
 ; CHECK-NEXT:    movs r0, r5
 ; CHECK-NEXT:    bics r0, r3
 ; CHECK-NEXT:    movs r1, #2
@@ -113,12 +113,12 @@ define <3 x i1> @test_srem_vec(<3 x i33> %X) nounwind {
 ; CHECK-NEXT:    orrs r6, r0
 ; CHECK-NEXT:    subs r0, r6, #1
 ; CHECK-NEXT:    sbcs r6, r0
-; CHECK-NEXT:    ldr r0, [sp, #36]
-; CHECK-NEXT:    ands r0, r5
-; CHECK-NEXT:    rsbs r1, r0, #0
 ; CHECK-NEXT:    movs r0, #8
 ; CHECK-NEXT:    mvns r2, r0
 ; CHECK-NEXT:    mvns r3, r7
+; CHECK-NEXT:    ldr r0, [sp, #36]
+; CHECK-NEXT:    lsls r0, r0, #31
+; CHECK-NEXT:    asrs r1, r0, #31
 ; CHECK-NEXT:    ldr r0, [sp, #32]
 ; CHECK-NEXT:    bl __aeabi_ldivmod
 ; CHECK-NEXT:    ands r5, r3



More information about the llvm-commits mailing list