Author: Dominik Steenken
Date: 2026-06-01T07:21:42Z
New Revision: a2b77904509333f5c9aa8e71427c694961e417c9

URL: 
https://github.com/llvm/llvm-project/commit/a2b77904509333f5c9aa8e71427c694961e417c9
DIFF: 
https://github.com/llvm/llvm-project/commit/a2b77904509333f5c9aa8e71427c694961e417c9.diff

LOG: [SystemZ] Fix off-by-one error in backend (#200141)

When combineCCMask is called on a TM node with two constant operands,
and all of the bits in the mask are active, the existing APInt bit
access goes off the overall length of the integer by one. This commit
fixes that by using the index value of the leftmost active bit, rather
than the number of active bits.

(cherry picked from commit 78eca55b542b6bca573f34a1b359fa949c3a8c89)

Added: 
    llvm/test/CodeGen/SystemZ/combine-ccmask-tm-full.ll

Modified: 
    llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp 
b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index c3ded986fd68e..48df65ab5871e 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -8843,7 +8843,7 @@ static bool combineCCMask(SDValue &CCReg, int &CCValid, 
int &CCMask,
       auto Result = Op0APVal & Op1APVal;
       bool AllOnes = Result == Op1APVal;
       bool AllZeros = Result == 0;
-      bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits()] != 0;
+      bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
       return AllZeros ? 0 : AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
     };
     SDValue Op0 = CCNode->getOperand(0);

diff  --git a/llvm/test/CodeGen/SystemZ/combine-ccmask-tm-full.ll 
b/llvm/test/CodeGen/SystemZ/combine-ccmask-tm-full.ll
new file mode 100644
index 0000000000000..85ab999d00bd7
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/combine-ccmask-tm-full.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 6
+; Test that DAGCombiner doesn't crash when combining CCMask with TM instruction
+; where all bits in the mask are active (off-by-one error regression test).
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
+
+define void @test_tm_full_mask(ptr %ptr) {
+; CHECK-LABEL: test_tm_full_mask:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    lb %r0, 0(%r2)
+; CHECK-NEXT:    tmll %r0, 1
+; CHECK-NEXT:    lhi %r1, 1
+; CHECK-NEXT:    jne .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    lr %r1, %r0
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:    tmll %r1, 1
+; CHECK-NEXT:    je .LBB0_4
+; CHECK-NEXT:  # %bb.3: # %if.then
+; CHECK-NEXT:    mvi 0(%r2), 1
+; CHECK-NEXT:  .LBB0_4: # %loop
+; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    j .LBB0_4
+  %1 = load i1, ptr %ptr, align 4
+  %2 = freeze i1 %1
+  %3 = select i1 %2, i32 0, i32 -1973148440
+  %4 = trunc i32 %3 to i16
+  %5 = or disjoint i16 %4, 1
+  %6 = icmp ult i16 %5, 3
+  %7 = and i32 %3, -1973157888
+  %8 = icmp eq i32 %7, 0
+  %9 = select i1 %6, i1 %8, i1 %2
+  br i1 %9, label %if.then, label %loop
+
+if.then:
+  store i1 true, ptr %ptr, align 4
+  br label %loop
+
+loop:
+  br label %loop
+}


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

Reply via email to