[llvm] [ConstraintElim] decompose subtract with guard as precondition (PR #209615)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 28 07:29:02 PDT 2026
================
@@ -239,3 +239,37 @@ if.end: ; preds = %entry
declare void @use(i1)
+
+; A `sub` without nsw/nuw is decomposed in the unsigned system under the
+; recorded precondition (Op1 u<= Op0). Given `%b u<= %a`, `%a - %b u<= %a` is
+; therefore known and the check folds to true. Without the precondition (the
+; check before the branch) it must NOT fold.
+define i1 @sub_no_wrap_flags_ule(i8 %a, i8 %b) {
+; CHECK-LABEL: @sub_no_wrap_flags_ule(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i8 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[C_NEG:%.*]] = icmp ule i8 [[SUB_NEG]], [[A]]
+; CHECK-NEXT: call void @use(i1 [[C_NEG]])
+; CHECK-NEXT: [[PRECOND:%.*]] = icmp ule i8 [[B]], [[A]]
+; CHECK-NEXT: br i1 [[PRECOND]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[A]], [[B]]
+; CHECK-NEXT: ret i1 true
+; CHECK: else:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %sub.neg = sub i8 %a, %b
+ %c.neg = icmp ule i8 %sub.neg, %a
+ call void @use(i1 %c.neg)
+ %precond = icmp ule i8 %b, %a
+ br i1 %precond, label %then, label %else
+
+then:
+ %sub = sub i8 %a, %b
+ %c = icmp ule i8 %sub, %a
+ ret i1 %c
----------------
fhahn wrote:
you can make this more compact by avoiding CFG and using `call void @llvm.assume(i1 %precond)`. same for test above
https://github.com/llvm/llvm-project/pull/209615
More information about the llvm-commits
mailing list