[llvm] [InstCombine] Allow overflowing selects to work on cumulative arguments (PR #90812)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 1 19:27:43 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: AtariDreams (AtariDreams)
<details>
<summary>Changes</summary>
This came up when working on a patch for systemd, where the code would not simplify because the code read:
```
unsigned int u(unsigned int x, unsigned int y)
{
unsigned int z;
if (__builtin_uadd_overflow(x, y, &z))
return UINT_MAX; /* indicate overflow */
return x + y;
}
```
Instead of:
```
unsigned int u(unsigned int x, unsigned int y)
{
unsigned int z;
if (__builtin_uadd_overflow(x, y, &z))
return UINT_MAX; /* indicate overflow */
return z;
}
```
---
Full diff: https://github.com/llvm/llvm-project/pull/90812.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+17-2)
- (modified) llvm/test/Transforms/InstCombine/overflow_to_sat.ll (+12)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 8818369e79452b..d10adb1667c020 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2075,12 +2075,27 @@ foldOverflowingAddSubSelect(SelectInst &SI, InstCombiner::BuilderTy &Builder) {
Value *FalseVal = SI.getFalseValue();
WithOverflowInst *II;
- if (!match(CondVal, m_ExtractValue<1>(m_WithOverflowInst(II))) ||
- !match(FalseVal, m_ExtractValue<0>(m_Specific(II))))
+ if (!match(CondVal, m_ExtractValue<1>(m_WithOverflowInst(II))))
return nullptr;
Value *X = II->getLHS();
Value *Y = II->getRHS();
+ if (!match(FalseVal, m_ExtractValue<0>(m_Specific(II)))) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::sadd_with_overflow:
+ if (!match(FalseVal, m_c_Add(m_Specific(X), m_Specific(Y))))
+ return nullptr;
+ break;
+ case Intrinsic::usub_with_overflow:
+ case Intrinsic::ssub_with_overflow:
+ if (!match(FalseVal, m_Sub(m_Specific(X), m_Specific(Y))))
+ return nullptr;
+ break;
+ default:
+ return nullptr;
+ }
+ }
auto IsSignedSaturateLimit = [&](Value *Limit, bool IsAdd) {
Type *Ty = Limit->getType();
diff --git a/llvm/test/Transforms/InstCombine/overflow_to_sat.ll b/llvm/test/Transforms/InstCombine/overflow_to_sat.ll
index 568ac77d6b88dd..eaa247b42a37b9 100644
--- a/llvm/test/Transforms/InstCombine/overflow_to_sat.ll
+++ b/llvm/test/Transforms/InstCombine/overflow_to_sat.ll
@@ -13,6 +13,18 @@ define i32 @uadd(i32 %x, i32 %y) {
ret i32 %s
}
+define i32 @uadd_cumm(i32 %x, i32 %y) {
+; CHECK-LABEL: @uadd_cumm(
+; CHECK-NEXT: [[S:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
+; CHECK-NEXT: ret i32 [[S]]
+;
+ %ao = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
+ %o = extractvalue { i32, i1 } %ao, 1
+ %a = add i32 %y, %x
+ %s = select i1 %o, i32 -1, i32 %a
+ ret i32 %s
+}
+
define i32 @usub(i32 %x, i32 %y) {
; CHECK-LABEL: @usub(
; CHECK-NEXT: [[S:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
``````````
</details>
https://github.com/llvm/llvm-project/pull/90812
More information about the llvm-commits
mailing list