[llvm] [ConstraintElim] Set NSW on sub when simplifying ssub.with.overflow. (PR #213532)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 2 04:35:22 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
When simplifying ssub.with.overflow to a plain sub, we already proven that the sub does not sign wrap. Replace it with `sub nsw`.
No changes on https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/842, but there is very little usage of ssub.with.overflow in default C/C++ builds.
It improves optimizations for code where ssub.with.overflow is used more widely, like Clang + UBSan or Swift where checked arithmetic is the default.
A simple C example is https://clang.godbolt.org/z/cv5MbYsrz
---
Full diff: https://github.com/llvm/llvm-project/pull/213532.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (+1-1)
- (modified) llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll (+3-3)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 8b7018f6c8433..07498dcb6ef7f 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1901,7 +1901,7 @@ static bool replaceSubOverflowUses(IntrinsicInst *II, Value *A, Value *B,
for (User *U : make_early_inc_range(II->users())) {
if (match(U, m_ExtractValue<0>(m_Value()))) {
if (!Sub)
- Sub = Builder.CreateSub(A, B);
+ Sub = Builder.CreateNSWSub(A, B);
U->replaceAllUsesWith(Sub);
Changed = true;
} else if (match(U, m_ExtractValue<1>(m_Value()))) {
diff --git a/llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll
index 254a6a662025e..4a270881bebf8 100644
--- a/llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll
+++ b/llvm/test/Transforms/ConstraintElimination/ssub-with-overflow.ll
@@ -11,7 +11,7 @@ define i8 @ssub_no_overflow_due_to_or_conds(i8 %a, i8 %b) {
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
; CHECK: math:
-; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i8 [[B]], [[A]]
; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
; CHECK: exit.ok:
; CHECK-NEXT: ret i8 [[TMP0]]
@@ -47,7 +47,7 @@ define i8 @ssub_no_overflow_due_to_or_conds_result_used(i8 %a, i8 %b) {
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2]], [[C_1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
; CHECK: math:
-; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i8 [[B]], [[A]]
; CHECK-NEXT: [[OP:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[B]], i8 [[A]])
; CHECK-NEXT: call void @use_res({ i8, i1 } [[OP]])
; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
@@ -84,7 +84,7 @@ define i8 @ssub_no_overflow_due_to_and_conds(i8 %a, i8 %b) {
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
; CHECK-NEXT: br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
; CHECK: math:
-; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i8 [[B]], [[A]]
; CHECK-NEXT: br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
; CHECK: exit.ok:
; CHECK-NEXT: ret i8 [[TMP0]]
``````````
</details>
https://github.com/llvm/llvm-project/pull/213532
More information about the llvm-commits
mailing list