https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/172962

>From 0c2f9b463e2013710ba90e9b8a19f8e9b9fd693f Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <[email protected]>
Date: Thu, 18 Dec 2025 23:37:39 -0800
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.6-beta.1
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 66 +++++++++++--------
 .../AArch64/switch-cases-to-branch-and.ll     | 40 +++++------
 2 files changed, 56 insertions(+), 50 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp 
b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 837393b0cbdcd..476a455f2e506 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11177,6 +11177,40 @@ std::pair<SDValue, uint64_t> 
lookThroughSignExtension(SDValue Val) {
   return {Val, Val.getValueSizeInBits() - 1};
 }
 
+// Op is an SDValue that is being compared to 0. If the comparison is a bit
+// test, optimize it to a TBZ or TBNZ.
+static SDValue optimizeBitTest(SDValue Op, SDValue Chain, SDValue Dest,
+                               unsigned Opcode, SelectionDAG &DAG) {
+  SDLoc DL(Op);
+
+  if (Op.getOpcode() != ISD::AND)
+    return SDValue();
+
+  // See if we can use a TBZ to fold in an AND as well.
+  // TBZ has a smaller branch displacement than CBZ.  If the offset is
+  // out of bounds, a late MI-layer pass rewrites branches.
+  // 403.gcc is an example that hits this case.
+  if (isa<ConstantSDNode>(Op.getOperand(1)) &&
+      isPowerOf2_64(Op.getConstantOperandVal(1))) {
+    SDValue Test = Op.getOperand(0);
+    uint64_t Mask = Op.getConstantOperandVal(1);
+    return DAG.getNode(Opcode, DL, MVT::Other, Chain, Test,
+                       DAG.getConstant(Log2_64(Mask), DL, MVT::i64), Dest);
+  }
+
+  if (Op.getOperand(0).getOpcode() == ISD::SHL) {
+    auto Op00 = Op.getOperand(0).getOperand(0);
+    if (isa<ConstantSDNode>(Op00) && Op00->getAsZExtVal() == 1) {
+      auto Shr = DAG.getNode(ISD::SRL, DL, Op00.getValueType(),
+                             Op.getOperand(1), Op.getOperand(0).getOperand(1));
+      return DAG.getNode(Opcode, DL, MVT::Other, Chain, Shr,
+                         DAG.getConstant(0, DL, MVT::i64), Dest);
+    }
+  }
+
+  return SDValue();
+}
+
 SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const 
{
   SDValue Chain = Op.getOperand(0);
   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
@@ -11236,35 +11270,15 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, 
SelectionDAG &DAG) const {
     const ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
     if (RHSC && RHSC->getZExtValue() == 0 && ProduceNonFlagSettingCondBr) {
       if (CC == ISD::SETEQ) {
-        // See if we can use a TBZ to fold in an AND as well.
-        // TBZ has a smaller branch displacement than CBZ.  If the offset is
-        // out of bounds, a late MI-layer pass rewrites branches.
-        // 403.gcc is an example that hits this case.
-        if (LHS.getOpcode() == ISD::AND &&
-            isa<ConstantSDNode>(LHS.getOperand(1)) &&
-            isPowerOf2_64(LHS.getConstantOperandVal(1))) {
-          SDValue Test = LHS.getOperand(0);
-          uint64_t Mask = LHS.getConstantOperandVal(1);
-          return DAG.getNode(AArch64ISD::TBZ, DL, MVT::Other, Chain, Test,
-                             DAG.getConstant(Log2_64(Mask), DL, MVT::i64),
-                             Dest);
-        }
+        if (SDValue Result =
+                optimizeBitTest(LHS, Chain, Dest, AArch64ISD::TBZ, DAG))
+          return Result;
 
         return DAG.getNode(AArch64ISD::CBZ, DL, MVT::Other, Chain, LHS, Dest);
       } else if (CC == ISD::SETNE) {
-        // See if we can use a TBZ to fold in an AND as well.
-        // TBZ has a smaller branch displacement than CBZ.  If the offset is
-        // out of bounds, a late MI-layer pass rewrites branches.
-        // 403.gcc is an example that hits this case.
-        if (LHS.getOpcode() == ISD::AND &&
-            isa<ConstantSDNode>(LHS.getOperand(1)) &&
-            isPowerOf2_64(LHS.getConstantOperandVal(1))) {
-          SDValue Test = LHS.getOperand(0);
-          uint64_t Mask = LHS.getConstantOperandVal(1);
-          return DAG.getNode(AArch64ISD::TBNZ, DL, MVT::Other, Chain, Test,
-                             DAG.getConstant(Log2_64(Mask), DL, MVT::i64),
-                             Dest);
-        }
+        if (SDValue Result =
+                optimizeBitTest(LHS, Chain, Dest, AArch64ISD::TBNZ, DAG))
+          return Result;
 
         return DAG.getNode(AArch64ISD::CBNZ, DL, MVT::Other, Chain, LHS, Dest);
       } else if (CC == ISD::SETLT && LHS.getOpcode() != ISD::AND) {
diff --git a/llvm/test/CodeGen/AArch64/switch-cases-to-branch-and.ll 
b/llvm/test/CodeGen/AArch64/switch-cases-to-branch-and.ll
index 775ab3fe110e0..cb59a8d976eda 100644
--- a/llvm/test/CodeGen/AArch64/switch-cases-to-branch-and.ll
+++ b/llvm/test/CodeGen/AArch64/switch-cases-to-branch-and.ll
@@ -422,25 +422,23 @@ e2:
 define i32 @switch_in_loop_with_matching_dests_0_and_pow2_4_cases(ptr %start) {
 ; CHECK-LABEL: switch_in_loop_with_matching_dests_0_and_pow2_4_cases:
 ; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    mov x10, #32769 ; =0x8001
-; CHECK-NEXT:    mov w8, #1 ; =0x1
+; CHECK-NEXT:    mov x8, #32769 ; =0x8001
 ; CHECK-NEXT:    add x9, x0, #1
-; CHECK-NEXT:    movk x10, #1, lsl #32
+; CHECK-NEXT:    movk x8, #1, lsl #32
 ; CHECK-NEXT:    b LBB5_2
 ; CHECK-NEXT:  LBB5_1: ; %loop
 ; CHECK-NEXT:    ; in Loop: Header=BB5_2 Depth=1
-; CHECK-NEXT:    cmp w11, #124
+; CHECK-NEXT:    cmp w10, #124
 ; CHECK-NEXT:    b.eq LBB5_5
 ; CHECK-NEXT:  LBB5_2: ; %loop
 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    ldrb w11, [x9], #1
-; CHECK-NEXT:    cmp w11, #32
+; CHECK-NEXT:    ldrb w10, [x9], #1
+; CHECK-NEXT:    cmp w10, #32
 ; CHECK-NEXT:    b.hi LBB5_1
 ; CHECK-NEXT:  ; %bb.3: ; %loop
 ; CHECK-NEXT:    ; in Loop: Header=BB5_2 Depth=1
-; CHECK-NEXT:    lsl x12, x8, x11
-; CHECK-NEXT:    tst x12, x10
-; CHECK-NEXT:    b.eq LBB5_1
+; CHECK-NEXT:    lsr x11, x8, x10
+; CHECK-NEXT:    tbz w11, #0, LBB5_1
 ; CHECK-NEXT:  ; %bb.4: ; %e1
 ; CHECK-NEXT:    mov w0, #-1 ; =0xffffffff
 ; CHECK-NEXT:    ret
@@ -608,10 +606,9 @@ exit:
 define i64 @consecutive_match_both(ptr %p, i32 %param) {
 ; CHECK-LABEL: consecutive_match_both:
 ; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    mov w8, #1 ; =0x1
+; CHECK-NEXT:    mov w8, #249 ; =0xf9
 ; CHECK-NEXT:    mov w9, #100 ; =0x64
-; CHECK-NEXT:    mov w10, #249 ; =0xf9
-; CHECK-NEXT:    lsl w8, w8, w1
+; CHECK-NEXT:    lsr w8, w8, w1
 ; CHECK-NEXT:    b LBB8_2
 ; CHECK-NEXT:  LBB8_1: ; %loop.latch
 ; CHECK-NEXT:    ; in Loop: Header=BB8_2 Depth=1
@@ -623,8 +620,7 @@ define i64 @consecutive_match_both(ptr %p, i32 %param) {
 ; CHECK-NEXT:    b.hi LBB8_1
 ; CHECK-NEXT:  ; %bb.3: ; %loop.header
 ; CHECK-NEXT:    ; in Loop: Header=BB8_2 Depth=1
-; CHECK-NEXT:    tst w8, w10
-; CHECK-NEXT:    b.eq LBB8_1
+; CHECK-NEXT:    tbz w8, #0, LBB8_1
 ; CHECK-NEXT:  ; %bb.4: ; %e0
 ; CHECK-NEXT:    mov x0, xzr
 ; CHECK-NEXT:    ret
@@ -688,10 +684,9 @@ e1:
 define i64 @consecutive_match_before(ptr %p, i32 %param) {
 ; CHECK-LABEL: consecutive_match_before:
 ; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    mov w8, #1 ; =0x1
+; CHECK-NEXT:    mov w8, #25 ; =0x19
 ; CHECK-NEXT:    mov w9, #100 ; =0x64
-; CHECK-NEXT:    mov w10, #25 ; =0x19
-; CHECK-NEXT:    lsl w8, w8, w1
+; CHECK-NEXT:    lsr w8, w8, w1
 ; CHECK-NEXT:    b LBB9_2
 ; CHECK-NEXT:  LBB9_1: ; %loop.latch
 ; CHECK-NEXT:    ; in Loop: Header=BB9_2 Depth=1
@@ -703,8 +698,7 @@ define i64 @consecutive_match_before(ptr %p, i32 %param) {
 ; CHECK-NEXT:    b.hi LBB9_1
 ; CHECK-NEXT:  ; %bb.3: ; %loop.header
 ; CHECK-NEXT:    ; in Loop: Header=BB9_2 Depth=1
-; CHECK-NEXT:    tst w8, w10
-; CHECK-NEXT:    b.eq LBB9_1
+; CHECK-NEXT:    tbz w8, #0, LBB9_1
 ; CHECK-NEXT:  ; %bb.4: ; %e0
 ; CHECK-NEXT:    mov x0, xzr
 ; CHECK-NEXT:    ret
@@ -765,10 +759,9 @@ e1:
 define i64 @consecutive_match_after(ptr %p, i32 %param) {
 ; CHECK-LABEL: consecutive_match_after:
 ; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    mov w8, #1 ; =0x1
+; CHECK-NEXT:    mov w8, #49 ; =0x31
 ; CHECK-NEXT:    mov w9, #100 ; =0x64
-; CHECK-NEXT:    mov w10, #49 ; =0x31
-; CHECK-NEXT:    lsl w8, w8, w1
+; CHECK-NEXT:    lsr w8, w8, w1
 ; CHECK-NEXT:    b LBB10_2
 ; CHECK-NEXT:  LBB10_1: ; %loop.latch
 ; CHECK-NEXT:    ; in Loop: Header=BB10_2 Depth=1
@@ -780,8 +773,7 @@ define i64 @consecutive_match_after(ptr %p, i32 %param) {
 ; CHECK-NEXT:    b.hi LBB10_1
 ; CHECK-NEXT:  ; %bb.3: ; %loop.header
 ; CHECK-NEXT:    ; in Loop: Header=BB10_2 Depth=1
-; CHECK-NEXT:    tst w8, w10
-; CHECK-NEXT:    b.eq LBB10_1
+; CHECK-NEXT:    tbz w8, #0, LBB10_1
 ; CHECK-NEXT:  ; %bb.4: ; %e0
 ; CHECK-NEXT:    mov x0, xzr
 ; CHECK-NEXT:    ret

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to