[llvm] [DAG] Fold logic of zero-checks to multiplication for MinSize (PR #171805)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 30 10:13:28 PST 2026


================
@@ -0,0 +1,131 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv64 -mattr=+m -enable-machine-outliner=never < %s | FileCheck %s
+
+define i1 @fold_or_eq_zero_i16(i16 zeroext %a, i16 zeroext %b) minsize {
+; CHECK-LABEL: fold_or_eq_zero_i16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    mul a0, a0, a1
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i16 %a, 0
+  %cmp2 = icmp eq i16 %b, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @fold_and_ne_zero_i16(i16 zeroext %a, i16 zeroext %b) minsize {
+; CHECK-LABEL: fold_and_ne_zero_i16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    mul a0, a0, a1
+; CHECK-NEXT:    snez a0, a0
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp ne i16 %a, 0
+  %cmp2 = icmp ne i16 %b, 0
+  %and = and i1 %cmp1, %cmp2
+  ret i1 %and
+}
+
+define i1 @negative_fold_potential_overflow_i64(i64 %a, i64 %b) minsize {
+; CHECK-LABEL: negative_fold_potential_overflow_i64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    seqz a1, a1
+; CHECK-NEXT:    or a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i64 %a, 0
+  %cmp2 = icmp eq i64 %b, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @negative_fold_no_minsize(i16 zeroext %a, i16 zeroext %b) {
+; CHECK-LABEL: negative_fold_no_minsize:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    seqz a1, a1
+; CHECK-NEXT:    or a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i16 %a, 0
+  %cmp2 = icmp eq i16 %b, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @negative_fold_mismatched_predicates(i16 zeroext %a, i16 zeroext %b) minsize {
+; CHECK-LABEL: negative_fold_mismatched_predicates:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    snez a1, a1
+; CHECK-NEXT:    or a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i16 %a, 0
+  %cmp2 = icmp ne i16 %b, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @negative_fold_lhs_nonzero_constant(i16 zeroext %a, i16 zeroext %b) minsize {
+; CHECK-LABEL: negative_fold_lhs_nonzero_constant:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    seqz a1, a1
+; CHECK-NEXT:    or a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i16 %a, 1;
+  %cmp2 = icmp eq i16 %b, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @negative_fold_rhs_nonzero_constant(i16 zeroext %a, i16 zeroext %b) minsize {
+; CHECK-LABEL: negative_fold_rhs_nonzero_constant:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    addi a1, a1, -1
+; CHECK-NEXT:    seqz a1, a1
+; CHECK-NEXT:    or a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i16 %a, 0;
+  %cmp2 = icmp eq i16 %b, 1
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @negative_fold_type_mismatch(i16 zeroext %a, i32 signext %b) minsize {
+; CHECK-LABEL: negative_fold_type_mismatch:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    seqz a1, a1
+; CHECK-NEXT:    or a0, a0, a1
+; CHECK-NEXT:    ret
+entry:
+  %cmp1 = icmp eq i16 %a, 0
+  %cmp2 = icmp eq i32 %b, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
+define i1 @fold_nsw_unsafe_proof(i8 zeroext %a, i8 zeroext %b) minsize {
+; CHECK-LABEL: fold_nsw_unsafe_proof:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    andi a0, a0, 15
+; CHECK-NEXT:    andi a1, a1, 15
+; CHECK-NEXT:    mul a0, a0, a1
+; CHECK-NEXT:    seqz a0, a0
+; CHECK-NEXT:    ret
+entry:
+  %a.masked = and i8 %a, 15
+  %b.masked = and i8 %b, 15
+  %cmp1 = icmp eq i8 %a.masked, 0
+  %cmp2 = icmp eq i8 %b.masked, 0
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
----------------
arsenm wrote:

Test a few vector cases 

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


More information about the llvm-commits mailing list