[llvm] [ConstraintElim] Simplify `sadd_with_overflow` if A and B have different signs (PR #135784)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 30 05:24:19 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]]
----------------
dtcxzyw wrote:
Is this behavior expected?
https://github.com/llvm/llvm-project/pull/135784
More information about the llvm-commits
mailing list