[llvm] [SCCP] Extend `visitBinaryOperator` to overflowing binary ops (PR #84470)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 8 04:27:45 PST 2024
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/84470
Leverage more refined ranges results when handling overflowing binary operators.
>From 018fdfb47cefc76be5306b96cb71a05c02c1198d Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Fri, 8 Mar 2024 13:16:03 +0100
Subject: [PATCH] [SCCP] Extend `visitBinaryOperator` to overflowing binary ops
Leverage more refined ranges results when handling overflowing
binary operators.
---
llvm/lib/Transforms/Utils/SCCPSolver.cpp | 13 ++++++++-
.../test/Transforms/SCCP/add-nuw-nsw-flags.ll | 29 +++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index a185e8cd371c60..a0e522d9e555c7 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -1486,7 +1486,18 @@ void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
// Try to simplify to a constant range.
ConstantRange A = getConstantRange(V1State, I.getType());
ConstantRange B = getConstantRange(V2State, I.getType());
- ConstantRange R = A.binaryOp(cast<BinaryOperator>(&I)->getOpcode(), B);
+
+ auto *BO = cast<BinaryOperator>(&I);
+ ConstantRange R = ConstantRange::getEmpty(I.getType()->getScalarSizeInBits());
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO)) {
+ bool HasNUW = OBO->hasNoUnsignedWrap();
+ bool HasNSW = OBO->hasNoSignedWrap();
+ unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
+ (HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0);
+ R = A.overflowingBinaryOp(BO->getOpcode(), B, Flags);
+ } else {
+ R = A.binaryOp(BO->getOpcode(), B);
+ }
mergeInValue(&I, ValueLatticeElement::getRange(R));
// TODO: Currently we do not exploit special values that produce something
diff --git a/llvm/test/Transforms/SCCP/add-nuw-nsw-flags.ll b/llvm/test/Transforms/SCCP/add-nuw-nsw-flags.ll
index b8f5d5dba0c4b2..05d9acd1919629 100644
--- a/llvm/test/Transforms/SCCP/add-nuw-nsw-flags.ll
+++ b/llvm/test/Transforms/SCCP/add-nuw-nsw-flags.ll
@@ -240,3 +240,32 @@ then:
else:
ret i16 0
}
+
+define i1 @test_add_nuw_sub(i32 %a) {
+; CHECK-LABEL: @test_add_nuw_sub(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A:%.*]], 10000
+; CHECK-NEXT: [[SUB:%.*]] = add i32 [[ADD]], -5000
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %add = add nuw i32 %a, 10000
+ %sub = add i32 %add, -5000
+ %cond = icmp ult i32 %sub, 5000
+ ret i1 %cond
+}
+
+define i1 @test_add_nsw_sub(i32 %a) {
+; CHECK-LABEL: @test_add_nsw_sub(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A:%.*]], 10000
+; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[ADD]], -5000
+; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[SUB]], 5000
+; CHECK-NEXT: ret i1 [[COND]]
+;
+entry:
+ %add = add nsw i32 %a, 10000
+ %sub = add i32 %add, -5000
+ %cond = icmp ult i32 %sub, 5000
+ ret i1 %cond
+}
More information about the llvm-commits
mailing list