[llvm] [ValueTracking] Add missing check for two-value PN recurrance matching (PR #152700)

Ivan R. Ivanov via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 8 06:32:15 PDT 2025


================
@@ -1310,6 +1310,37 @@ TEST_F(ValueTrackingTest, MatchBinaryIntrinsicRecurrenceNegativeFSHR) {
   EXPECT_FALSE(matchSimpleBinaryIntrinsicRecurrence(II, PN, Init, OtherOp));
 }
 
+TEST_F(ValueTrackingTest, MatchBinaryIntrinsicRecurrenceNonTwoOperand) {
+  auto M = parseModule(R"(
+    declare noundef i32 @llvm.nvvm.read.ptx.sreg.nctaid.x()
+    declare i32 @llvm.umin.i32(i32, i32)
+
+    define void @foo(i32 %arg) {
+    bb:
+      br i1 false, label %bb1, label %bb2
+
+    bb1:                                              ; preds = %bb
+      br label %bb3
+
+    bb2:                                              ; preds = %bb
+      %i = tail call noundef i32 @llvm.nvvm.read.ptx.sreg.nctaid.x()
+      br label %bb3
+
+    bb3:                                              ; preds = %bb2, %bb1
+      %i4 = phi i32 [ 0, %bb1 ], [ %i, %bb2 ]
+      %i6 = tail call noundef i32 @llvm.umin.i32(i32 %i4, i32 %arg)
+      ret void
+    }
+  )");
----------------
ivanradanov wrote:

Yes it is currently possible, but the reproducable-in-lit example is a very artificial one produced by llvm-reduce and its ability to test this specific bug will probably be very flaky depending on future changes in instcombine.

for reference this is how it looks like and removing anything more stops testing the change
```
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #0

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare noundef range(i32 1, -2147483648) i32 @llvm.nvvm.read.ptx.sreg.nctaid.x() #1

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.umin.i32(i32, i32) #1

define i32 @foo(i32 %arg) {
bb:
  br i1 false, label %bb1, label %bb2

bb1:                                              ; preds = %bb
  br label %bb3

bb2:                                              ; preds = %bb
  %i = tail call noundef range(i32 1, -2147483648) i32 @llvm.nvvm.read.ptx.sreg.nctaid.x()
  br label %bb3

bb3:                                              ; preds = %bb2, %bb1
  %i4 = phi i32 [ 0, %bb1 ], [ %i, %bb2 ]
  %i5 = icmp samesign ult i32 0, %i4
  tail call void @llvm.assume(i1 %i5)
  %i6 = tail call noundef i32 @llvm.umin.i32(i32 %i4, i32 %arg)
  %i7 = icmp samesign ult i32 0, %i6
  br i1 %i7, label %bb8, label %bb9

bb8:                                              ; preds = %bb3
  ret i32 0

bb9:                                              ; preds = %bb3
  ret i32 0
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
```

I am not sure if it's valuable adding it.

https://github.com/llvm/llvm-project/pull/152700


More information about the llvm-commits mailing list