[llvm] VT: teach isImpliedCondMatchingOperands about samesign (PR #122474)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 10 07:29:38 PST 2025
https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/122474
Move isImplied{True,False}ByMatchingCmp from CmpInst to ICmpInst, so that it can operate on CmpPredicate instead of CmpInst::Predicate, and teach it about samesign. There are two callers of this function, and we choose to migrate the one in ValueTracking, namely isImpliedCondMatchingOperands to CmpPredicate, hence teaching it about samesign, with visible test impact.
>From 6d02fa7bd8b3b98f9cceddf2fe93eb8628b6234a Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 16 Dec 2024 17:26:20 +0000
Subject: [PATCH] VT: teach isImpliedCondMatchingOperands about samesign
Move isImplied{True,False}ByMatchingCmp from CmpInst to ICmpInst, so
that it can operate on CmpPredicate instead of CmpInst::Predicate, and
teach it about samesign. There are two callers of this function, and we
choose to migrate the one in ValueTracking, namely
isImpliedCondMatchingOperands to CmpPredicate, hence teaching it about
samesign, with visible test impact.
---
llvm/include/llvm/IR/InstrTypes.h | 8 --------
llvm/include/llvm/IR/Instructions.h | 10 ++++++++++
llvm/include/llvm/SandboxIR/Instruction.h | 16 +++++++++-------
llvm/lib/Analysis/ValueTracking.cpp | 9 ++++-----
llvm/lib/IR/Instructions.cpp | 13 ++++++++++---
llvm/lib/Transforms/Scalar/NewGVN.cpp | 8 ++++----
.../ValueTracking/implied-condition-samesign.ll | 7 ++-----
7 files changed, 39 insertions(+), 32 deletions(-)
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index e6332a16df7d5f5..7ad34e4f2233940 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -967,14 +967,6 @@ class CmpInst : public Instruction {
/// Determine if the predicate is false when comparing a value with itself.
static bool isFalseWhenEqual(Predicate predicate);
- /// Determine if Pred1 implies Pred2 is true when two compares have matching
- /// operands.
- static bool isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2);
-
- /// Determine if Pred1 implies Pred2 is false when two compares have matching
- /// operands.
- static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2);
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ICmp ||
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index a8df12a1282fcce..59eb50409883786 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -1266,6 +1266,16 @@ class ICmpInst: public CmpInst {
return getFlippedSignednessPredicate(getPredicate());
}
+ /// Determine if Pred1 implies Pred2 is true when two compares have matching
+ /// operands.
+ static bool isImpliedTrueByMatchingCmp(CmpPredicate Pred1,
+ CmpPredicate Pred2);
+
+ /// Determine if Pred1 implies Pred2 is false when two compares have matching
+ /// operands.
+ static bool isImpliedFalseByMatchingCmp(CmpPredicate Pred1,
+ CmpPredicate Pred2);
+
void setSameSign(bool B = true) {
SubclassOptionalData = (SubclassOptionalData & ~SameSign) | (B * SameSign);
}
diff --git a/llvm/include/llvm/SandboxIR/Instruction.h b/llvm/include/llvm/SandboxIR/Instruction.h
index 4d21c4d3da3556f..d7c1eda81c00607 100644
--- a/llvm/include/llvm/SandboxIR/Instruction.h
+++ b/llvm/include/llvm/SandboxIR/Instruction.h
@@ -2511,13 +2511,6 @@ class CmpInst : public SingleLLVMInstructionImpl<llvm::CmpInst> {
WRAP_STATIC_PREDICATE(isOrdered);
WRAP_STATIC_PREDICATE(isUnordered);
- static bool isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2) {
- return llvm::CmpInst::isImpliedTrueByMatchingCmp(Pred1, Pred2);
- }
- static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2) {
- return llvm::CmpInst::isImpliedFalseByMatchingCmp(Pred1, Pred2);
- }
-
/// Method for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *From) {
return From->getSubclassID() == ClassID::ICmp ||
@@ -2554,6 +2547,15 @@ class ICmpInst : public CmpInst {
WRAP_STATIC_PREDICATE(isGE);
WRAP_STATIC_PREDICATE(isLE);
+ static bool isImpliedTrueByMatchingCmp(CmpPredicate Pred1,
+ CmpPredicate Pred2) {
+ return llvm::ICmpInst::isImpliedTrueByMatchingCmp(Pred1, Pred2);
+ }
+ static bool isImpliedFalseByMatchingCmp(CmpPredicate Pred1,
+ CmpPredicate Pred2) {
+ return llvm::ICmpInst::isImpliedFalseByMatchingCmp(Pred1, Pred2);
+ }
+
static auto predicates() { return llvm::ICmpInst::predicates(); }
static bool compare(const APInt &LHS, const APInt &RHS,
ICmpInst::Predicate Pred) {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9a61b36efa51da4..31792dcb17df958 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9374,12 +9374,11 @@ isImpliedCondOperands(CmpInst::Predicate Pred, const Value *ALHS,
/// Return true if "icmp1 LPred X, Y" implies "icmp2 RPred X, Y" is true.
/// Return false if "icmp1 LPred X, Y" implies "icmp2 RPred X, Y" is false.
/// Otherwise, return std::nullopt if we can't infer anything.
-static std::optional<bool>
-isImpliedCondMatchingOperands(CmpInst::Predicate LPred,
- CmpInst::Predicate RPred) {
- if (CmpInst::isImpliedTrueByMatchingCmp(LPred, RPred))
+static std::optional<bool> isImpliedCondMatchingOperands(CmpPredicate LPred,
+ CmpPredicate RPred) {
+ if (ICmpInst::isImpliedTrueByMatchingCmp(LPred, RPred))
return true;
- if (CmpInst::isImpliedFalseByMatchingCmp(LPred, RPred))
+ if (ICmpInst::isImpliedFalseByMatchingCmp(LPred, RPred))
return false;
return std::nullopt;
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 2d6fe40f4c1de00..49c148bb68a4d38 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -3886,12 +3886,18 @@ bool CmpInst::isFalseWhenEqual(Predicate predicate) {
}
}
-bool CmpInst::isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2) {
+bool ICmpInst::isImpliedTrueByMatchingCmp(CmpPredicate Pred1,
+ CmpPredicate Pred2) {
// If the predicates match, then we know the first condition implies the
// second is true.
- if (Pred1 == Pred2)
+ if (CmpPredicate::getMatching(Pred1, Pred2))
return true;
+ if (Pred1.hasSameSign() && CmpInst::isSigned(Pred2))
+ Pred1 = ICmpInst::getFlippedSignednessPredicate(Pred1);
+ else if (Pred2.hasSameSign() && CmpInst::isSigned(Pred1))
+ Pred2 = ICmpInst::getFlippedSignednessPredicate(Pred2);
+
switch (Pred1) {
default:
break;
@@ -3911,7 +3917,8 @@ bool CmpInst::isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2) {
return false;
}
-bool CmpInst::isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2) {
+bool ICmpInst::isImpliedFalseByMatchingCmp(CmpPredicate Pred1,
+ CmpPredicate Pred2) {
return isImpliedTrueByMatchingCmp(Pred1, getInversePredicate(Pred2));
}
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 0cba8739441bcbd..3812e99508f7385 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -1964,15 +1964,15 @@ NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
if (PBranch->TrueEdge) {
// If we know the previous predicate is true and we are in the true
// edge then we may be implied true or false.
- if (CmpInst::isImpliedTrueByMatchingCmp(BranchPredicate,
- OurPredicate)) {
+ if (ICmpInst::isImpliedTrueByMatchingCmp(BranchPredicate,
+ OurPredicate)) {
return ExprResult::some(
createConstantExpression(ConstantInt::getTrue(CI->getType())),
PI);
}
- if (CmpInst::isImpliedFalseByMatchingCmp(BranchPredicate,
- OurPredicate)) {
+ if (ICmpInst::isImpliedFalseByMatchingCmp(BranchPredicate,
+ OurPredicate)) {
return ExprResult::some(
createConstantExpression(ConstantInt::getFalse(CI->getType())),
PI);
diff --git a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll
index 042155ae2bb79bc..546ff2d77d86e3d 100644
--- a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll
+++ b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll
@@ -118,8 +118,7 @@ define i1 @sgt_implies_ge_via_assume(i32 %i, i32 %j) {
; CHECK-SAME: i32 [[I:%.*]], i32 [[J:%.*]]) {
; CHECK-NEXT: [[I_SGT_J:%.*]] = icmp sgt i32 [[I]], [[J]]
; CHECK-NEXT: call void @llvm.assume(i1 [[I_SGT_J]])
-; CHECK-NEXT: [[I_GE_J:%.*]] = icmp samesign uge i32 [[I]], [[J]]
-; CHECK-NEXT: ret i1 [[I_GE_J]]
+; CHECK-NEXT: ret i1 true
;
%i.sgt.j = icmp sgt i32 %i, %j
call void @llvm.assume(i1 %i.sgt.j)
@@ -134,9 +133,7 @@ define i32 @gt_implies_sge_dominating(i32 %a, i32 %len) {
; CHECK-NEXT: [[A_GT_LEN:%.*]] = icmp samesign ugt i32 [[A]], [[LEN]]
; CHECK-NEXT: br i1 [[A_GT_LEN]], label %[[TAKEN:.*]], label %[[END:.*]]
; CHECK: [[TAKEN]]:
-; CHECK-NEXT: [[A_SGE_LEN:%.*]] = icmp sge i32 [[A]], [[LEN]]
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[A_SGE_LEN]], i32 30, i32 0
-; CHECK-NEXT: ret i32 [[RES]]
+; CHECK-NEXT: ret i32 30
; CHECK: [[END]]:
; CHECK-NEXT: ret i32 -1
;
More information about the llvm-commits
mailing list