[llvm] [InstCombine] Fold Minimum over trailing or leading zeros (PR #173768)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 28 09:09:40 PST 2025


================
@@ -380,3 +380,29 @@ define i16 @umin_ctlz_i16_negative_two_uses(i16 %X) {
   %ret = add i16 %ctlz, %op0
   ret i16 %ret
 }
+
+define dso_local range(i32 0, 33) i32 @src1(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 {
+; CHECK-LABEL: define dso_local range(i32 0, 33) i32 @src1(
+; CHECK-SAME: i32 noundef [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP3]], i1 true)
+; CHECK-NEXT:    ret i32 [[TMP5]]
+;
+  %3 = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 %0, i1 false)
+  %4 = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 %1, i1 false)
+  %5 = tail call i32 @llvm.umin.i32(i32 %3, i32 %4)
+  ret i32 %5
+}
+
+define dso_local range(i32 0, 33) i32 @src2(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 {
+; CHECK-LABEL: define dso_local range(i32 0, 33) i32 @src2(
+; CHECK-SAME: i32 noundef [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[TMP5:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[TMP3]], i1 true)
+; CHECK-NEXT:    ret i32 [[TMP5]]
+;
+  %3 = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 %0, i1 false)
+  %4 = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 %1, i1 false)
+  %5 = tail call i32 @llvm.umin.i32(i32 %3, i32 %4)
+  ret i32 %5
+}
----------------
nikic wrote:

Please test both true and false for the poison flag.

Also add a negative test e.g. for the arguments being ctlz and cttz instead of both the same.

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


More information about the llvm-commits mailing list