[llvm] [ConstraintElim] Simplify `sadd_with_overflow` if A and B have different signs (PR #135784)

Iris Shi via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 30 05:41:44 PDT 2025


================
@@ -0,0 +1,303 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
+
+declare { i8, i1 } @llvm.sadd.with.overflow.i8(i8, i8)
+
+define i8 @sadd_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) {
+; CHECK-LABEL: define i8 @sadd_no_overflow_due_to_cmp_condition(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[A]], 0
+; CHECK-NEXT:    [[C_2:%.*]] = icmp sle i8 [[B]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
+; CHECK-NEXT:    br i1 [[AND]], label %[[MATH:.*]], label %[[EXIT_FAIL:.*]]
+; CHECK:       [[MATH]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = add i8 [[A]], [[B]]
+; CHECK-NEXT:    br i1 false, label %[[EXIT_FAIL]], label %[[EXIT_OK:.*]]
+; CHECK:       [[EXIT_OK]]:
+; CHECK-NEXT:    ret i8 [[TMP0]]
+; CHECK:       [[EXIT_FAIL]]:
+; CHECK-NEXT:    ret i8 0
+;
+entry:
+  %c.1 = icmp sge i8 %a, 0
+  %c.2 = icmp sle i8 %b, 0
+  %and = and i1 %c.1, %c.2
+  br i1 %and, label %math, label %exit.fail
+
+math:
+  %op = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
+  %status = extractvalue { i8, i1 } %op, 1
+  br i1 %status, label %exit.fail, label %exit.ok
+
+exit.ok:
+  %res = extractvalue { i8, i1 } %op, 0
+  ret i8 %res
+
+exit.fail:
+  ret i8 0
+}
+
+define i8 @sadd_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) {
+; CHECK-LABEL: define i8 @sadd_no_overflow_due_to_cmp_condition2(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[A]], 64
+; CHECK-NEXT:    [[C_2:%.*]] = icmp sle i8 [[B]], 64
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
+; CHECK-NEXT:    br i1 [[AND]], label %[[MATH:.*]], label %[[EXIT_FAIL:.*]]
+; CHECK:       [[MATH]]:
+; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[A]], i8 [[B]])
+; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
+; CHECK-NEXT:    br i1 [[STATUS]], label %[[EXIT_FAIL]], label %[[EXIT_OK:.*]]
+; CHECK:       [[EXIT_OK]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = extractvalue { i8, i1 } [[OP]], 0
+; CHECK-NEXT:    ret i8 [[TMP0]]
+; CHECK:       [[EXIT_FAIL]]:
+; CHECK-NEXT:    ret i8 0
+;
+entry:
+  %c.1 = icmp slt i8 %a, 64
+  %c.2 = icmp sle i8 %b, 64
+  %and = and i1 %c.1, %c.2
+  br i1 %and, label %math, label %exit.fail
+
+math:
+  %op = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
+  %status = extractvalue { i8, i1 } %op, 1
+  br i1 %status, label %exit.fail, label %exit.ok
+
+exit.ok:
+  %res = extractvalue { i8, i1 } %op, 0
+  ret i8 %res
+
+exit.fail:
+  ret i8 0
+}
+
+declare void @use_res({ i8, i1 })
+
+define i8 @sadd_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) {
+; CHECK-LABEL: define i8 @sadd_no_overflow_due_to_cmp_condition_result_used(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[A]], 0
+; CHECK-NEXT:    [[C_2:%.*]] = icmp sle i8 [[B]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
+; CHECK-NEXT:    br i1 [[AND]], label %[[MATH:.*]], label %[[EXIT_FAIL:.*]]
+; CHECK:       [[MATH]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = add i8 [[A]], [[B]]
----------------
el-ev wrote:

Definitely not.

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


More information about the llvm-commits mailing list