[llvm] InstSimplify: teach simplifyICmpWithConstant about samesign (PR #125899)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 7 10:46:44 PST 2025
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/125899
>From 193c879abdab710dbfd1758746235303bb5b9024 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 5 Feb 2025 15:56:35 +0000
Subject: [PATCH 1/2] ValueTracking: pre-commit constrange-samesign tests
---
.../Analysis/ValueTracking/constant-ranges.ll | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/llvm/test/Analysis/ValueTracking/constant-ranges.ll b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
index c440cfad889d3b4..7a4b9f7ed645a9f 100644
--- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll
+++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
@@ -160,6 +160,15 @@ define i1 @srem_posC_okay0(i8 %x) {
ret i1 %r
}
+define i1 @srem_posC_okay0_samesign(i8 %x) {
+; CHECK-LABEL: @srem_posC_okay0_samesign(
+; CHECK-NEXT: ret i1 true
+;
+ %val = srem i8 34, %x
+ %r = icmp samesign ule i8 %val, 34
+ ret i1 %r
+}
+
define i1 @srem_posC_okay1(i8 %x) {
; CHECK-LABEL: @srem_posC_okay1(
; CHECK-NEXT: ret i1 true
@@ -169,6 +178,15 @@ define i1 @srem_posC_okay1(i8 %x) {
ret i1 %r
}
+define i1 @srem_posC_okay1_samesign(i8 %x) {
+; CHECK-LABEL: @srem_posC_okay1_samesign(
+; CHECK-NEXT: ret i1 false
+;
+ %val = srem i8 34, %x
+ %r = icmp samesign uge i8 %val, -3
+ ret i1 %r
+}
+
define i1 @srem_negC_okay0(i8 %x) {
; CHECK-LABEL: @srem_negC_okay0(
; CHECK-NEXT: ret i1 true
@@ -178,6 +196,17 @@ define i1 @srem_negC_okay0(i8 %x) {
ret i1 %r
}
+define i1 @srem_negC_okay0_samesign(i8 %x) {
+; CHECK-LABEL: @srem_negC_okay0_samesign(
+; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp samesign ule i8 [[VAL]], 0
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = srem i8 -34, %x
+ %r = icmp samesign ule i8 %val, 0
+ ret i1 %r
+}
+
define i1 @srem_negC_okay1(i8 %x) {
; CHECK-LABEL: @srem_negC_okay1(
; CHECK-NEXT: ret i1 true
@@ -187,6 +216,17 @@ define i1 @srem_negC_okay1(i8 %x) {
ret i1 %r
}
+define i1 @srem_negC_okay1_samesign(i8 %x) {
+; CHECK-LABEL: @srem_negC_okay1_samesign(
+; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp samesign uge i8 [[VAL]], -34
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %val = srem i8 -34, %x
+ %r = icmp samesign uge i8 %val, -34
+ ret i1 %r
+}
+
define i1 @srem_posC_fail0(i8 %x) {
; CHECK-LABEL: @srem_posC_fail0(
; CHECK-NEXT: [[VAL:%.*]] = srem i8 34, [[X:%.*]]
>From f9a2becc1a6c346a17e103979d93c6b2838d65a4 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 5 Feb 2025 17:46:48 +0000
Subject: [PATCH 2/2] InstSimplify: teach simplifyICmpWithConstant about
samesign
We have chosen to change ConstantRange::makeAllowedICmpRegion to respect
samesign information, noting that ConstantRange::makeExactICmpRegion
should not be modified.
---
llvm/include/llvm/IR/ConstantRange.h | 7 ++++++-
llvm/lib/Analysis/InstructionSimplify.cpp | 2 +-
llvm/lib/IR/ConstantRange.cpp | 8 ++++++++
llvm/test/Analysis/ValueTracking/constant-ranges.ll | 10 +++-------
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/IR/ConstantRange.h b/llvm/include/llvm/IR/ConstantRange.h
index d086c25390fd227..f530e0a2e59df00 100644
--- a/llvm/include/llvm/IR/ConstantRange.h
+++ b/llvm/include/llvm/IR/ConstantRange.h
@@ -34,7 +34,6 @@
#include "llvm/ADT/APInt.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
-#include "llvm/Support/Compiler.h"
#include <cstdint>
namespace llvm {
@@ -42,6 +41,7 @@ namespace llvm {
class MDNode;
class raw_ostream;
struct KnownBits;
+class CmpPredicate;
/// This class represents a range of values.
class [[nodiscard]] ConstantRange {
@@ -103,6 +103,11 @@ class [[nodiscard]] ConstantRange {
static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred,
const ConstantRange &Other);
+ /// Calls makeAllowedICmpRegion with a CmpPredicate, yielding an asymmetric
+ /// range when samesign information is present.
+ static ConstantRange makeAsymmetricICmpRegion(CmpPredicate Pred,
+ const ConstantRange &Other);
+
/// Produce the largest range such that all values in the returned range
/// satisfy the given predicate with all values contained within Other.
/// Formally, this returns a subset of
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 3cbc4107433ef3d..939df1e4677bf2a 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3012,7 +3012,7 @@ static Value *simplifyICmpWithConstant(CmpPredicate Pred, Value *LHS,
}
// Rule out tautological comparisons (eg., ult 0 or uge 0).
- ConstantRange RHS_CR = ConstantRange::makeExactICmpRegion(Pred, *C);
+ ConstantRange RHS_CR = ConstantRange::makeAsymmetricICmpRegion(Pred, *C);
if (RHS_CR.isEmptySet())
return ConstantInt::getFalse(ITy);
if (RHS_CR.isFullSet())
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 35664353989929d..0728cbeac9e730f 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -145,6 +145,14 @@ ConstantRange ConstantRange::makeAllowedICmpRegion(CmpInst::Predicate Pred,
}
}
+ConstantRange ConstantRange::makeAsymmetricICmpRegion(CmpPredicate Pred,
+ const ConstantRange &CR) {
+ if (Pred.hasSameSign() && ICmpInst::isRelational(Pred))
+ return makeAllowedICmpRegion(Pred, CR).unionWith(makeAllowedICmpRegion(
+ ICmpInst::getFlippedSignednessPredicate(Pred), CR));
+ return makeAllowedICmpRegion(Pred, CR);
+}
+
ConstantRange ConstantRange::makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
const ConstantRange &CR) {
// Follows from De-Morgan's laws:
diff --git a/llvm/test/Analysis/ValueTracking/constant-ranges.ll b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
index 7a4b9f7ed645a9f..2e9731895bff3ce 100644
--- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll
+++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
@@ -180,7 +180,7 @@ define i1 @srem_posC_okay1(i8 %x) {
define i1 @srem_posC_okay1_samesign(i8 %x) {
; CHECK-LABEL: @srem_posC_okay1_samesign(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: ret i1 true
;
%val = srem i8 34, %x
%r = icmp samesign uge i8 %val, -3
@@ -198,9 +198,7 @@ define i1 @srem_negC_okay0(i8 %x) {
define i1 @srem_negC_okay0_samesign(i8 %x) {
; CHECK-LABEL: @srem_negC_okay0_samesign(
-; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = icmp samesign ule i8 [[VAL]], 0
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 true
;
%val = srem i8 -34, %x
%r = icmp samesign ule i8 %val, 0
@@ -218,9 +216,7 @@ define i1 @srem_negC_okay1(i8 %x) {
define i1 @srem_negC_okay1_samesign(i8 %x) {
; CHECK-LABEL: @srem_negC_okay1_samesign(
-; CHECK-NEXT: [[VAL:%.*]] = srem i8 -34, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = icmp samesign uge i8 [[VAL]], -34
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 true
;
%val = srem i8 -34, %x
%r = icmp samesign uge i8 %val, -34
More information about the llvm-commits
mailing list